Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
'use client';

import Link from 'next/link';
import Image from 'next/image';
import mapIcon from '@public/hackers/table-number-checkin/map.svg';
import checkmarkIcon from '@public/hackers/table-number-checkin/check.svg';

interface ConfirmStageProps {
tableNumber: string | null;
onConfirm: () => void;
onReset: () => void;
}

export default function ConfirmStage({
tableNumber,
onConfirm,
onReset,
}: ConfirmStageProps) {
return (
<div
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
md:flex-row md:items-center md:justify-between md:p-[60px]"
>
{/* RIGHT column — first in DOM so it appears at top on mobile, right on desktop */}
<div className="flex flex-col flex-1 w-full gap-3 md:order-2 md:self-stretch">
{/* Table Number Card */}
<div className="flex flex-col justify-center items-center gap-4 rounded-[16px] w-full h-[171px] bg-[#0B2638] md:h-full">
<h1 className="text-6xl text-[#FAFAFF] text-center font-medium tracking-[1.2px] md:text-[120px]">
TABLE
</h1>
<h1 className="text-6xl text-[#FAFAFF] text-center font-medium tracking-[1.2px] md:text-[120px]">
{tableNumber ?? '---'}
</h1>
</div>
</div>

{/* LEFT column — second in DOM, reordered to first on desktop */}
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
<div className="flex flex-col gap-1">
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
Your Table Number
</h3>

<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
Check that you and your team members received the same table number.
It is extremely important to be
<span className="text-[#5E5E65]"> present at your table </span> when
the judges arrive.
</p>

<div className="flex gap-2 items-center mt-2">
<div className="relative w-4 h-4 md:w-6 md:h-6">
<Image
src={mapIcon}
alt="Map Icon"
fill
className="object-cover"
/>
</div>

<Link
href="#"
className="text-[14px] font-normal text-[#5E5E65] border-b border-[#5E5E65] leading-none tracking-wide md:text-[18px]"
>
MAP LINK
</Link>
</div>
</div>

{/* Buttons */}
<div className="flex justify-between items-center md:justify-normal md:gap-[56px] text-left">
<button
onClick={onReset}
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent text-left"
>
<span className="md:hidden">Not my team</span>
<span className="hidden md:inline">Wait, this is not my team</span>
</button>

<button
onClick={onConfirm}
className="bg-[#CCFFFE] text-[#1A3819] font-semibold text-base flex gap-2 justify-center items-center px-8 py-3 rounded-[40px] cursor-pointer md:px-[44px] md:py-5 whitespace-nowrap"
>
Got it
<div className="relative hidden md:block w-4 h-4">
<Image
src={checkmarkIcon}
alt="Checkmark"
fill
className="object-cover"
/>
</div>
</button>
</div>
</div>
</div>
);
}
124 changes: 124 additions & 0 deletions app/(pages)/(hackers)/_components/TableNumberCheckin/DevpostStage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
'use client';

import Image from 'next/image';
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';
import devpostNumber from '@public/hackers/table-number-checkin/Filler.svg';

interface DevpostStageProps {
teamNumber: string;
error: string | null;
onChange: (value: string) => void;
onSubmit: () => void;
onBack: () => void;
}

export default function DevpostStage({
teamNumber,
error,
onChange,
onSubmit,
onBack,
}: DevpostStageProps) {
const hasTeamNumber = teamNumber.length && Number(teamNumber) > 0;

return (
<div
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
md:flex-row md:items-center md:justify-between md:p-[60px]"
>
{/* RIGHT column — first in DOM so image appears at top on mobile, right on desktop */}
<div className="flex flex-col flex-1 w-full gap-3 md:order-2">
{/* Screenshot image */}
<div className="w-full rounded-[16px] overflow-hidden md:flex-1">
<Image
src={devpostNumber}
alt="devpost number screenshot"
className="w-full h-auto object-contain"
/>
</div>

{/* Devpost Number Input — below image */}
<div className="flex flex-col gap-1">
<p className="text-[14px] font-normal text-[#878796] tracking-wide">
DEVPOST NUMBER
</p>
<input
type="text"
placeholder="#####"
value={teamNumber}
inputMode="numeric"
maxLength={5}
pattern="[0-9]*"
className="w-full border border-[#E0E0F0] rounded-[12px] px-4 py-3 text-base bg-white placeholder:text-[#ACACB9] focus:outline-none focus:ring-2 focus:ring-[#CCFFFE]"
onChange={(e) => {
const val = e.target.value.replace(/\D/g, '').slice(0, 5);
onChange(val);
}}
/>
</div>
</div>

{/* LEFT column — second in DOM, reordered to first on desktop */}
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
<div className="flex flex-col gap-1">
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px] md:leading-normal">
{error
? 'Oops! We did not find your Devpost number.'
: 'Find your Devpost number.'}
</h3>

{error ? (
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
Please double check you have entered the same number listed on
Devpost.
</p>
) : (
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
This can be found by going to{' '}
<a
href="https://hackdavis-2026.devpost.com/tables"
target="_blank"
rel="noopener noreferrer"
className="text-[#5E5E65] underline decoration-[#5E5E65] underline-offset-4 break-all"
>
hackdavis-2026.devpost.com/tables
</a>{' '}
and finding your project submission name. Enter the number exactly
as it is presented.
</p>
)}
</div>

{/* Buttons — bottom of left column on desktop, bottom of card on mobile */}
<div className="flex justify-between items-center md:justify-normal md:gap-[56px]">
<button
onClick={onBack}
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent"
>
Back
</button>

<button
className={`${
hasTeamNumber
? 'bg-[#CCFFFE] text-[#1A3819]'
: 'bg-[#F3F3FC] text-[#ACACB9]'
} font-semibold text-base flex justify-center items-center px-8 py-3 rounded-[40px] cursor-pointer disabled:opacity-30 md:px-[44px] md:py-5`}
disabled={!hasTeamNumber}
onClick={onSubmit}
>
{hasTeamNumber ? 'Next' : 'Got it'}
<div className="relative w-6 h-6 ml-2">
<Image
src={rightArrow}
alt="Right Arrow"
fill
className="object-cover"
/>
</div>
</button>
</div>
</div>
</div>
);
}
56 changes: 56 additions & 0 deletions app/(pages)/(hackers)/_components/TableNumberCheckin/InitStage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client';

import Image from 'next/image';
import mascotsCelebrate from '@public/hackers/table-number-checkin/end-of-hackathon.svg';
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';

interface InitStageProps {
onNext: () => void;
}

export default function InitStage({ onNext }: InitStageProps) {
return (
<div className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF] md:flex-row md:items-center md:justify-between md:p-[60px]">
{/* Image - top half on mobile, right side on desktop */}
<div className="flex flex-1 w-full h-full justify-center md:order-2 md:justify-end md:rounded-[16px]">
<Image
src={mascotsCelebrate}
alt="mascots hanging out"
className="w-full object-contain"
/>
</div>

{/* Content - bottom on mobile, left side on desktop */}
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8">
<div className="flex flex-col gap-1 text-black">
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px]">
The Hackathon has ended!
</h3>
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px]">
Thank you for all your hard work. Next, please follow the directions
to find your assigned table number.
</p>
</div>

<div className="flex flex-row w-full">
<button
className="text-[#1A3819] font-semibold text-[16px] flex justify-center items-center px-8 py-3 rounded-[40px] bg-[#CCFFFE] cursor-pointer shrink-0 md:px-[44px] md:py-5"
onClick={() => {
onNext();
}}
>
Ready to find my table
<div className="relative w-6 aspect-square ml-2">
<Image
src={rightArrow}
alt="Right Arrow"
fill
className="object-cover"
/>
</div>
</button>
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'use client';

import Image from 'next/image';
import loadingBus from '@public/hackers/table-number-checkin/bus_loading.gif';
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';

interface LoadingStageProps {
teamNumber: string;
}

export default function LoadingStage({ teamNumber }: LoadingStageProps) {
return (
<div
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
md:flex-row md:items-center md:justify-between md:p-[60px]"
>
{/* RIGHT column — first in DOM so image appears at top on mobile, right on desktop */}
<div className="flex flex-col flex-1 w-full gap-3 md:order-2 md:self-stretch">
{/* Image */}
<div className="relative w-full h-[349px] bg-[#F3F3FC] rounded-[20px] flex items-center justify-center md:rounded-[16px] md:overflow-hidden">
<Image
src={loadingBus}
alt="animated bus loading"
fill
unoptimized
className="object-contain object-center rounded-[20px]"
/>
</div>

{/* Devpost Number — below image */}
<div className="flex flex-col gap-1">
<p className="text-[12px] font-normal text-[#878796] tracking-wide md:text-[14px]">
DEVPOST NUMBER
</p>

<input
type="text"
value={teamNumber}
readOnly
placeholder="#####"
inputMode="numeric"
maxLength={5}
pattern="[0-9]*"
className="w-full border border-[#E0E0F0] rounded-[12px] px-4 py-5 text-base bg-white placeholder:text-[#ACACB9] focus:outline-none cursor-default"
/>
</div>
</div>

{/* LEFT column — second in DOM, reordered to first on desktop */}
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
<div className="flex flex-col gap-1">
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px]">
Searching high and low...
</h3>

<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
Did you know that this year is HackDavis's 10 year anniversary?
</p>
</div>

{/* Buttons */}
<div className="flex justify-between items-center md:justify-normal md:gap-[56px]">
<button
disabled
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent opacity-30"
>
Back
</button>

<button
disabled
className="bg-[#F3F3FC] text-[#ACACB9] font-semibold text-base flex justify-center items-center px-8 py-3 rounded-[40px] opacity-30 md:px-[44px] md:py-5"
>
Next
<div className="relative w-6 h-6 ml-2">
<Image
src={rightArrow}
alt="Right Arrow"
fill
className="object-cover"
/>
</div>
</button>
</div>
</div>
</div>
);
}
Loading
Loading