Skip to content

Refactor Winners Tab to Match Organizer Design #399

Description

@Benjtalkshow

Refactor Winners Tab to Match Organizer Design (app/hackathons/[slug])

Objective

Upgrade the participant-facing "Winners" tab to use the premium design already established in the organizer's PublishWinnersWizard, and ensure all project and participant links are fully functional with correct deep-linking parameters. The current implementation renders a basic card grid that lacks the visual hierarchy, deep linking, and premium "Podium" aesthetics that the organizer-side already delivers. This refactor closes that gap — the participant-facing winners experience should be indistinguishable in quality from what organizers see when publishing results.


Context & Current Implementation

Route

  • app/(landing)/hackathons/[slug]/page.tsx

Primary Component

  • components/hackathons/winners/WinnersTab.tsx

How It Currently Works

  • The page uses the useHackathonData() hook to fetch the winners dataset
  • WinnersTab is conditionally rendered when winners.length > 0 and the winnersTab feature is enabled in currentHackathon.enabledTabs
  • The current implementation renders a basic grid of winner cards that lack:
    • Clickable deep links for projects and participant profiles
    • The premium "Podium" visual hierarchy for top 3 ranks
    • USDC financial branding next to prize amounts
    • The Ribbon rank display and high-quality avatar treatments from the organizer design

UI & Design Replication

Design Source

  • Mirror the design found in components/organization/hackathons/rewards/WinnerCard.tsx exactly — this is the canonical reference and the participant-facing card must reach the same level of visual quality

Card Aesthetics

  • Use the Ribbon component for rank display on each winner tile — the ribbon should be prominently placed and visually distinct per rank position
  • Use high-quality Avatar circles for winner profile images, with appropriate fallback initials if no avatar is available
  • Include a stylized project preview card at the bottom of each winner tile, showing the project image or thumbnail alongside the project name
  • Prize amounts must display the USDC logo inline next to the value to ensure clear, unambiguous financial branding

Card Hierarchy & Podium Layout

  • Replicate the WinnersGrid layout from components/organization/hackathons/rewards/WinnersGrid.tsx as the structural foundation
  • Where applicable (i.e., when the top 3 ranked winners are present), implement the "Podium" effect — visually elevating 1st place above 2nd and 3rd, with proportional sizing or vertical offset that communicates rank at a glance
  • Cards beyond the top 3 should render in a standard grid below the podium section, maintaining the same card design without the podium elevation treatment
  • The overall layout must be responsive — the podium and grid should reflow gracefully at tablet and mobile breakpoints without breaking the visual hierarchy

Deep Linking & Logic

Project Link

  • Refactor the project name and project image/thumbnail on each winner card to be clickable links
  • Path: /projects/${projectId}?type=submission
  • The ?type=submission query parameter is required — it must always be appended to ensure the project page renders in the correct submission view context. Do not omit this parameter under any circumstance.

Participant Link

  • Refactor the participant name and avatar on each winner card to be clickable links
  • Path: /profile/${username} — linking to the participant's public profile page

Fallback Rendering

  • Both links must degrade gracefully when metadata is missing:
    • If projectId is null or undefined, render the project name and image as non-clickable text/image rather than a broken link
    • If username is null or undefined, render the participant name and avatar as non-clickable elements
    • If avatar image fails to load, fall back to styled initials using the existing Avatar component fallback pattern
  • Missing metadata must never cause a rendering error or blank card — the tile should always display whatever information is available

Technical Details

Hooks & Data Path

  • All winner data is provided by the useHackathonData() hook in the parent HackathonPage — no additional API calls should be introduced
  • Map the winners array (typed as Array<HackathonWinner>) from the hook's context output to the new WinnerCard component props
  • The mapping should be explicit and type-safe — strictly no any types

Components to Modify

  • Overhaul components/hackathons/winners/WinnersTab.tsx — this is the primary deliverable
  • Reference the logic and structure from components/organization/hackathons/rewards/PublishWinnersWizard.tsx for implementation guidance
  • Reference components/organization/hackathons/rewards/WinnerCard.tsx for the card design spec
  • Reference components/organization/hackathons/rewards/WinnersGrid.tsx for the grid and podium layout

⚠️ Caution

This is a production environment — not a sandbox.

  • Code must be performant, accessible, and clean
  • No dummy data — all winner data must come exclusively from the useHackathonData() hook; no hardcoded or mock values
  • 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 types

Manual Verification

  • Confirm WinnersTab is only rendered when winners.length > 0 and winnersTab is present in currentHackathon.enabledTabs
  • Verify the Podium layout correctly elevates 1st place above 2nd and 3rd when top 3 winners are present
  • Confirm the Ribbon component displays the correct rank on each card
  • Verify the USDC logo appears inline next to all prize amounts
  • Test project deep links — clicking a project name or image navigates to /projects/${projectId}?type=submission with the query parameter correctly appended
  • Test participant profile links — clicking a participant name or avatar navigates to /profile/${username}
  • Verify fallback rendering — cards with missing projectId, username, or avatar image render gracefully without broken links, blank tiles, or console errors
  • Confirm no additional API calls are made — all data flows exclusively from useHackathonData()
  • Confirm no TypeScript any types are present in the winner data mapping layer
  • Test the layout at multiple breakpoints — confirm the podium and card grid reflow correctly at tablet and mobile sizes
  • Verify the card design visually matches components/organization/hackathons/rewards/WinnerCard.tsx at full fidelity
  • Provide video evidence

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions