-
Notifications
You must be signed in to change notification settings - Fork 77
Description
Hackathon Participation Registration & Status-Based Banner States
Objective
Ensure the Hackathon Banner and Registration Modal strictly enforce the registrationDeadlinePolicy when a user attempts to join a hackathon event. All registration UI must accurately reflect the current participation window at all times — no "Join" affordance should ever be accessible outside of a valid registration period.
Important Context: This issue concerns Hackathon Participation Registration — the act of a user joining a specific hackathon event — and is entirely separate from general Boundless app account signup.
Registration Policy Enforcement
Supported Policy Types
The registration system must support all three values of registrationDeadlinePolicy:
| Policy | Behavior |
|---|---|
BEFORE_START |
Registration is open until the hackathon officially starts. Once the start date passes, registration closes automatically. |
BEFORE_SUBMISSION_DEADLINE |
Registration remains open until the submission deadline is reached. Users can join even after the hackathon has started. |
CUSTOM |
Registration closes at the explicit registrationDeadline timestamp. This field must be respected exactly — no approximations or fallbacks to other dates. |
registrationOpen Flag
- If the API returns
registrationOpen: false, all "Join" UI must be permanently disabled — regardless of what theregistrationDeadlinePolicyor any other timestamp suggests - This flag is the authoritative override and must be evaluated before any policy-based logic runs
- A disabled registration state should be clearly communicated to the user — not silently hidden — so they understand why the option is unavailable
Button Text States
The registration button text must dynamically reflect the current context to set accurate user expectations:
| Context | Button Text |
|---|---|
| Hackathon has not started yet | "Early Register" |
| Hackathon is live, registration still open | "Register" |
| Registration window is closing soon | "Late Register" |
| Registration period not yet open | "Register Interest" |
registrationOpen is false or deadline passed |
Button disabled with appropriate label |
- Button text must update reactively as time progresses — if a user has the page open across a registration boundary, the button state should update without requiring a page refresh
Technical Implementation
Primary Files
components/hackathons/hackathonBanner.tsxcomponents/hackathons/overview/RegisterHackathonModal.tsx
Hooks
useRegisterHackathon()
- Update this hook to consume and surface the
registrationOpenstatus returned from the API - The hook should expose
registrationOpenas part of its return value so consuming components can gate their UI without re-fetching or duplicating logic - Ensure the hook handles the
registrationOpen: falsestate as a first-class condition, not an edge case
useHackathonStatus()
- Use this hook for all reactive timeline calculations — deriving whether the current moment falls within the registration window, before the start, after the submission deadline, etc.
- All time-based evaluations must flow through this hook to ensure consistency across components and to avoid duplicated
Date.now()comparisons scattered across the codebase - The hook must remain reactive — components consuming it should automatically reflect state changes as time progresses, without requiring a manual refresh
Logic Enforcement
Banner — canRegister Memo
- Refactor the
canRegistercomputed value inHackathonBanner.tsxto strictly respect theregistrationDeadlinePolicy - The memo must evaluate all three policy types (
BEFORE_START,BEFORE_SUBMISSION_DEADLINE,CUSTOM) using the timestamps provided byuseHackathonStatus() - The
registrationOpenflag must be checked first within the memo — iffalse,canRegistermust resolve tofalseimmediately without evaluating any further policy logic - The memo's dependencies must be correctly declared to ensure it recalculates whenever relevant timestamps or the
registrationOpenflag change
Button — renderRegistrationButton
- Update the
renderRegistrationButtonfunction to handleregistrationOpen: falseas a hard override — when this flag is false, the button must render in a permanently disabled state regardless of any other condition - The function must map the current registration context to the correct button text from the states table above
- Disabled button states must remain visible and descriptive — the user must always understand why they cannot register, not simply encounter a missing button
Banner States
- The Hackathon Banner must reflect the current registration state at all times, acting as the primary visual indicator of the hackathon's lifecycle position
- Banner states must be driven by the same
canRegistermemo anduseHackathonStatus()logic — the banner and the registration button must always be in agreement; they must never contradict each other - When
registrationOpenisfalse, the banner must surface a clear, on-brand message communicating that registration is closed - When the policy is
CUSTOM, the banner should surface theregistrationDeadlinetimestamp as a human-readable deadline or countdown so users understand the urgency
⚠️ Caution
This is a production environment — not a sandbox.
- Code must be performant, accessible, and clean
- No dummy data — all enforcement logic must operate on real
registrationDeadlinePolicy,registrationOpen, and deadline timestamp values from the API - AI-generated code will be scrutinized; poorly structured or "hallucinated" code will result in immediate issue closure
- Follow the existing design system: shadcn/ui, Tailwind, Framer Motion
Testing & Verification
Automated Tests
npm run lint # Ensure code quality
npm run build # Verify no breaking changes in routing or typesManual Verification
- Set
registrationOpen: false— confirm all "Join" UI is permanently disabled regardless of policy type or timestamps, in both the banner and the modal - Test
BEFORE_STARTpolicy — confirm the registration button is active before the start date and automatically disables once the start date passes - Test
BEFORE_SUBMISSION_DEADLINEpolicy — confirm registration remains open after hackathon start and closes exactly at the submission deadline - Test
CUSTOMpolicy — confirm registration closes precisely at theregistrationDeadlinetimestamp with no fallback to other dates - Verify button text updates correctly across all states (
"Early Register","Register","Late Register","Register Interest", disabled) - Confirm the
canRegistermemo inHackathonBanner.tsxevaluatesregistrationOpenfirst before any policy logic - Leave the page open across a registration boundary — confirm the button and banner update reactively via
useHackathonStatus()without a page refresh - Confirm the banner and button are always in agreement — no scenario where the banner indicates registration is open while the button is disabled, or vice versa
- Test all time comparisons with timestamps near DST boundaries — confirm no off-by-one errors at registration window edges
- Verify the disabled registration button remains visible with a descriptive label — it must not simply disappear
- Provide video evidence