Feature: fix/hackathon-portal-finish to dev - #452
Merged
Merged
Conversation
The hackathon pages, submit, judging and their error and loading
screens had drifted into a fake-terminal style the rest of the portal
does not use: underscored titles ("Auth_Error", "Status_Code: 401"),
"System Failure" / "Reboot System" copy, neon glows, gradient text,
pulsing dots, blur blobs inside cards, hover lifts and a second green
accent. They now use the dashboard and settings conventions: Oswald
headings, the teal accent, one set of buttons and inputs, rounded-sm,
plain sentence-case copy, and one empty-state pattern.
- Registration statuses render through a shared StatusBadge
("Under review", "Accepted", "Checked in") instead of raw enums.
The detail page and registration card no longer say "Registered" or
"You're in" while an application is still pending.
- text-text-muted is not a utility, so "muted" text rendered at full
brightness in 89 places across the site. Now text-[var(--text-muted)].
- Hand-pasted SVG icons are lucide icons; icon-only project links have
visible labels; external links carry rel="noopener noreferrer".
- Empty states for a filter that matches nothing and for judges with no
open hackathons; the list page's back link no longer sends
hackathon-only users to the members-only club page.
- The login footer's "Internal Terminal // Auth Gateway v2.1" is gone.
maxParticipants used to be claimed at application time, so the form said "full" once N people had applied, even with most still pending, which defeats accepting in waves. Applying now never takes a seat. A seat is taken on acceptance: waves fill what is left, and Accept + email, single and bulk approve check the remaining seats under the hackathon row lock (assertSeats) and refuse rather than go over. currentParticipants counts approved and checked-in.
Team create/join opened only 12 hours into the event. The window now runs from acceptance up to +34h; checkAdmitted already limits who may form a team. The +12h mark stays as the submission opening only, and team.window reports opensAt: null.
- judge.setActive is isAdmin: every admin saw Approve, but only super admins could use it, so self-registered judges could stay inactive. Removing a judge stays super-admin. - judge.create takes an email and finds the account, so an organiser can add a sponsor or walk-in judge. - judge.register only accepts public editions that are announced or later. Any uuid used to pass, and a missing one hit the foreign key as a 500. Judge applications open while an event is announced.
- team.mySubmission returns the judging table number, and /submit shows it. Judges are sent to a table; the team was never told which. - The Judges tab's Assign Judge form could never render (this edition had no unassigned judges). It is now Add judge: by email via judge.create, assigned in the same step, plus a copyable apply link. - /submit defaults to a registration that is still active, matching the dropdown, and says waitlisted / not accepted in words.
- /hacklytics offered the interest form after registration opened, where registerInterest refuses it, and called a closed edition 'not announced'. It now shows the form only while announced, and otherwise a status line with a link to the event page. closed joins the public funnel statuses. - toggleJudging refuses to open judging while no judge has an unscored table queued; judges opened straight onto 'All done, 0 of 0'. A judge with an empty queue now reads 'No tables yet', and the Judges tab links to Prepare judging (/admin/judging?hackathonId=...).
- hackathon.withdrawRegistration removes your own registration and frees the seat. Refused once you are on a team, checked in, or have a project, since undoing those affects others. - The results email goes to checked-in participants (it reached every applicant, accepted or not) and links straight to the Results tab. - Graduation year is validated relative to the current year.
Scanlines, a cyan grid, rotating squares round the logo, floating glow
orbs and fake telemetry ("Core Operational", "REGION: ATL-08",
"Handshake Verified") are gone. The page is a short intro and a card
titled Sign in, in the portal's house style. Behaviour is unchanged.
The email error copy said link where the flow sends a code.
- A full event still takes applications (capacity caps acceptances), with a note that new applicants are waitlisted. - Participants can withdraw a pending, accepted or waitlisted registration, with an inline confirm; checked-in participants get a link to submit their project. - Team create/join only show for accepted participants, with a line saying why otherwise; the server already refused the rest. - Failed loads read as errors with Try again, not as empty lists, on projects, teams, schedule, admin hackathons and attendees. - Schedule times carry the day: 'Sat, Feb 27 · 2:00 PM'. - Approve without email says so; seat-limit refusals are shown. - The scanner explains that scans need a check-in event, and a pass from another hackathon says so instead of 'Event not found'.
At desktop width the intro and the card sat at opposite edges of a 6xl container. A 4xl container and a larger heading keep them together.
Sync: dev to main
- updateParticipantStatus seat-checks checked_in as well as approved, and only promotes to checked_in from a seated status, so a check-in racing a waitlist change cannot seat somebody past capacity. - withdrawRegistration carries its checks into the DELETE (not checked in, not on a team) and reports CONFLICT if the row changed after it was read. Finished or cancelled events refuse withdrawals, and the same caches as an organiser status change are evicted. - toggleJudging blocks only when no queue was ever built, so judging can be reopened after every slot is scored.
- Opening the registration form fell through to 'Registration is closed.' right above the open form. - Team members are told to leave their team before withdrawing, instead of getting a refusal after two clicks. - Adding a judge refreshes the judge list even if the follow-up assign fails, so the new judge appears in the picker.
The admin judging page and the hackathon dashboard tabs kept the glow,
gradient-text and terminal copy the participant pages lost ("Data
Evaluation Layer // SYNC ACTIVE", "Awaiting Data Packet...", "Operations
Personnel"). They now use the portal's house style and plain words
(Results, Votes, Tied scores, Judges).
- Attendees: a failed filter or page refetch shows an inline error above
the rows it kept, instead of passing them off as the new results.
Status cells use StatusBadge.
- Scanner: a failed events load says so with a retry, rather than
telling the organiser to create an event.
- updateParticipantStatus: a check-in whose seated-only WHERE matches nothing (concurrent waitlist or reject) now throws CONFLICT instead of reporting success to the desk. - evictParticipantCaches drops the cached hackathon row, so the public seat count updates after accept and withdraw instead of at TTL. - Judging page shows the toggleJudging error; Start judging refused for missing queues was a silent no-op. - /submit hides Create team and Join team until the registration is approved or checked in, matching TeamsTab and the server check. - Judge page says All done only when progress shows assigned work; loading or failed progress no longer reads as finished.
Contributor
Author
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
Author
|
Visit the preview URL for this PR (updated for commit e6bd765): https://hacklytics2027--pr-452-wf38qmcx.web.app (expires Fri, 09 Oct 2026 19:50:34 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: c48ba34db61581e25fe2978355160b5eefe0e83f |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0342a95. Configure here.
The toggleJudging error stayed on screen after switching events, so a refusal for one hackathon read as a refusal for the next.
aamoghS
enabled auto-merge
October 2, 2026 19:49
aamoghS
approved these changes
Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Finishes the hackathon portal end to end and drops the fake-terminal look in favour of the dashboard's house style.
Behaviour changes (decided with the owner)
assertSeats). A full event still takes applications, which wait on the waitlist.Participants
Judges and organisers
Look
text-text-mutedwas not a real utility, so "muted" text rendered at full brightness in 89 places; fixed site-wide.Checks
Typecheck, lint, 871 tests (run in UTC like CI) and the build pass. New tests cover the acceptance cap, team window, judge rules, withdrawal (including the race) and the judging guard.
Not included: an uncommitted change to
packages/db/src/schemas/events.ts(unique constraint → unique index) that was already in the working tree; it is left for its author.Note
High Risk
Changes core registration/capacity, check-in concurrency, and admin approval flows; mistakes could over-accept participants or block legitimate organisers/judges.
Overview
Capacity and registration:
maxParticipantsnow limits acceptances (approved/checked-in), not applications. Registration no longer incrementscurrentParticipantsor rejects “full” events;assertSeatsruns inside transactions on single/batch approve, accept-wave, and check-in paths.syncCurrentParticipantsand wave sizing respect remaining seats. Participants canwithdrawRegistrationwhen still pending/accepted without team, check-in, or project, with optimistic delete and seat recount.Teams, judges, judging: Team create/join/leave opens from acceptance through +34h (removed the +12h gate).
judge.setActiveis any admin (remove stays super-admin);judge.createaccepts email lookup;judge.registerreturns NOT_FOUND for missing/draft/hidden editions.toggleJudgingrefuses to open when the queue is empty. Team project fetch includes judging table number when promoted.Portal / Hacklytics: Shared
StatusBadgeand a dashboard-aligned restyle (Oswald, accent tokens,text-[var(--text-muted)]instead of brokentext-text-muted, calmer copy on errors/loading). Hacklytics funnel includesclosed; interest form only while announced; registration-closed states link to the event page. Admin judging honors?hackathonId=and surfaces toggle-judging errors.Tests are updated/added for capacity on approve, team window, withdrawal races, judge rules, and judging guards.
Reviewed by Cursor Bugbot for commit e6bd765. Bugbot is set up for automated code reviews on this repo. Configure here.