Skip to content

Commit eea2634

Browse files
396 table number check in (#447)
* feat: add first mobile card * chore: change folder structure for each stage of ending of hackathon * feat: add devpost stage mobile * feat: add loading stage mobile * feat: add confirm stage mobile * feat: add initial stage desktop * feat: add devpost stage desktop * feat: add loading stage desktop * feat: add confirm stage desktop * chore: update names and delete unnecessary files * chore: fix padding, devpost number lnegth, and text spacing * chore: Add missing `px` and remove console.log() from TableNumberCheckin.tsx * fix string error * update image paths * fix ui, force loading modal * link devpost tables * error handling --------- Co-authored-by: michelleyeoh <michellew.yeoh@gmail.com>
1 parent ef391a1 commit eea2634

17 files changed

Lines changed: 724 additions & 564 deletions
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
'use client';
2+
3+
import Link from 'next/link';
4+
import Image from 'next/image';
5+
import mapIcon from '@public/hackers/table-number-checkin/map.svg';
6+
import checkmarkIcon from '@public/hackers/table-number-checkin/check.svg';
7+
8+
interface ConfirmStageProps {
9+
tableNumber: string | null;
10+
onConfirm: () => void;
11+
onReset: () => void;
12+
}
13+
14+
export default function ConfirmStage({
15+
tableNumber,
16+
onConfirm,
17+
onReset,
18+
}: ConfirmStageProps) {
19+
return (
20+
<div
21+
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
22+
md:flex-row md:items-center md:justify-between md:p-[60px]"
23+
>
24+
{/* RIGHT column — first in DOM so it appears at top on mobile, right on desktop */}
25+
<div className="flex flex-col flex-1 w-full gap-3 md:order-2 md:self-stretch">
26+
{/* Table Number Card */}
27+
<div className="flex flex-col justify-center items-center gap-4 rounded-[16px] w-full h-[171px] bg-[#0B2638] md:h-full">
28+
<h1 className="text-6xl text-[#FAFAFF] text-center font-medium tracking-[1.2px] md:text-[120px]">
29+
TABLE
30+
</h1>
31+
<h1 className="text-6xl text-[#FAFAFF] text-center font-medium tracking-[1.2px] md:text-[120px]">
32+
{tableNumber ?? '---'}
33+
</h1>
34+
</div>
35+
</div>
36+
37+
{/* LEFT column — second in DOM, reordered to first on desktop */}
38+
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
39+
<div className="flex flex-col gap-1">
40+
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
41+
Your Table Number
42+
</h3>
43+
44+
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
45+
Check that you and your team members received the same table number.
46+
It is extremely important to be
47+
<span className="text-[#5E5E65]"> present at your table </span> when
48+
the judges arrive.
49+
</p>
50+
51+
<div className="flex gap-2 items-center mt-2">
52+
<div className="relative w-4 h-4 md:w-6 md:h-6">
53+
<Image
54+
src={mapIcon}
55+
alt="Map Icon"
56+
fill
57+
className="object-cover"
58+
/>
59+
</div>
60+
61+
<Link
62+
href="#"
63+
className="text-[14px] font-normal text-[#5E5E65] border-b border-[#5E5E65] leading-none tracking-wide md:text-[18px]"
64+
>
65+
MAP LINK
66+
</Link>
67+
</div>
68+
</div>
69+
70+
{/* Buttons */}
71+
<div className="flex justify-between items-center md:justify-normal md:gap-[56px] text-left">
72+
<button
73+
onClick={onReset}
74+
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent text-left"
75+
>
76+
<span className="md:hidden">Not my team</span>
77+
<span className="hidden md:inline">Wait, this is not my team</span>
78+
</button>
79+
80+
<button
81+
onClick={onConfirm}
82+
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"
83+
>
84+
Got it
85+
<div className="relative hidden md:block w-4 h-4">
86+
<Image
87+
src={checkmarkIcon}
88+
alt="Checkmark"
89+
fill
90+
className="object-cover"
91+
/>
92+
</div>
93+
</button>
94+
</div>
95+
</div>
96+
</div>
97+
);
98+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
'use client';
2+
3+
import Image from 'next/image';
4+
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';
5+
import devpostNumber from '@public/hackers/table-number-checkin/Filler.svg';
6+
7+
interface DevpostStageProps {
8+
teamNumber: string;
9+
error: string | null;
10+
onChange: (value: string) => void;
11+
onSubmit: () => void;
12+
onBack: () => void;
13+
}
14+
15+
export default function DevpostStage({
16+
teamNumber,
17+
error,
18+
onChange,
19+
onSubmit,
20+
onBack,
21+
}: DevpostStageProps) {
22+
const hasTeamNumber = teamNumber.length && Number(teamNumber) > 0;
23+
24+
return (
25+
<div
26+
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
27+
md:flex-row md:items-center md:justify-between md:p-[60px]"
28+
>
29+
{/* RIGHT column — first in DOM so image appears at top on mobile, right on desktop */}
30+
<div className="flex flex-col flex-1 w-full gap-3 md:order-2">
31+
{/* Screenshot image */}
32+
<div className="w-full rounded-[16px] overflow-hidden md:flex-1">
33+
<Image
34+
src={devpostNumber}
35+
alt="devpost number screenshot"
36+
className="w-full h-auto object-contain"
37+
/>
38+
</div>
39+
40+
{/* Devpost Number Input — below image */}
41+
<div className="flex flex-col gap-1">
42+
<p className="text-[14px] font-normal text-[#878796] tracking-wide">
43+
DEVPOST NUMBER
44+
</p>
45+
<input
46+
type="text"
47+
placeholder="#####"
48+
value={teamNumber}
49+
inputMode="numeric"
50+
maxLength={5}
51+
pattern="[0-9]*"
52+
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]"
53+
onChange={(e) => {
54+
const val = e.target.value.replace(/\D/g, '').slice(0, 5);
55+
onChange(val);
56+
}}
57+
/>
58+
</div>
59+
</div>
60+
61+
{/* LEFT column — second in DOM, reordered to first on desktop */}
62+
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
63+
<div className="flex flex-col gap-1">
64+
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px] md:leading-normal">
65+
{error
66+
? 'Oops! We did not find your Devpost number.'
67+
: 'Find your Devpost number.'}
68+
</h3>
69+
70+
{error ? (
71+
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
72+
Please double check you have entered the same number listed on
73+
Devpost.
74+
</p>
75+
) : (
76+
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
77+
This can be found by going to{' '}
78+
<a
79+
href="https://hackdavis-2026.devpost.com/tables"
80+
target="_blank"
81+
rel="noopener noreferrer"
82+
className="text-[#5E5E65] underline decoration-[#5E5E65] underline-offset-4 break-all"
83+
>
84+
hackdavis-2026.devpost.com/tables
85+
</a>{' '}
86+
and finding your project submission name. Enter the number exactly
87+
as it is presented.
88+
</p>
89+
)}
90+
</div>
91+
92+
{/* Buttons — bottom of left column on desktop, bottom of card on mobile */}
93+
<div className="flex justify-between items-center md:justify-normal md:gap-[56px]">
94+
<button
95+
onClick={onBack}
96+
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent"
97+
>
98+
Back
99+
</button>
100+
101+
<button
102+
className={`${
103+
hasTeamNumber
104+
? 'bg-[#CCFFFE] text-[#1A3819]'
105+
: 'bg-[#F3F3FC] text-[#ACACB9]'
106+
} 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`}
107+
disabled={!hasTeamNumber}
108+
onClick={onSubmit}
109+
>
110+
{hasTeamNumber ? 'Next' : 'Got it'}
111+
<div className="relative w-6 h-6 ml-2">
112+
<Image
113+
src={rightArrow}
114+
alt="Right Arrow"
115+
fill
116+
className="object-cover"
117+
/>
118+
</div>
119+
</button>
120+
</div>
121+
</div>
122+
</div>
123+
);
124+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use client';
2+
3+
import Image from 'next/image';
4+
import mascotsCelebrate from '@public/hackers/table-number-checkin/end-of-hackathon.svg';
5+
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';
6+
7+
interface InitStageProps {
8+
onNext: () => void;
9+
}
10+
11+
export default function InitStage({ onNext }: InitStageProps) {
12+
return (
13+
<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]">
14+
{/* Image - top half on mobile, right side on desktop */}
15+
<div className="flex flex-1 w-full h-full justify-center md:order-2 md:justify-end md:rounded-[16px]">
16+
<Image
17+
src={mascotsCelebrate}
18+
alt="mascots hanging out"
19+
className="w-full object-contain"
20+
/>
21+
</div>
22+
23+
{/* Content - bottom on mobile, left side on desktop */}
24+
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8">
25+
<div className="flex flex-col gap-1 text-black">
26+
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px]">
27+
The Hackathon has ended!
28+
</h3>
29+
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px]">
30+
Thank you for all your hard work. Next, please follow the directions
31+
to find your assigned table number.
32+
</p>
33+
</div>
34+
35+
<div className="flex flex-row w-full">
36+
<button
37+
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"
38+
onClick={() => {
39+
onNext();
40+
}}
41+
>
42+
Ready to find my table
43+
<div className="relative w-6 aspect-square ml-2">
44+
<Image
45+
src={rightArrow}
46+
alt="Right Arrow"
47+
fill
48+
className="object-cover"
49+
/>
50+
</div>
51+
</button>
52+
</div>
53+
</div>
54+
</div>
55+
);
56+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
'use client';
2+
3+
import Image from 'next/image';
4+
import loadingBus from '@public/hackers/table-number-checkin/bus_loading.gif';
5+
import rightArrow from '@public/hackers/table-number-checkin/arrow-right.svg';
6+
7+
interface LoadingStageProps {
8+
teamNumber: string;
9+
}
10+
11+
export default function LoadingStage({ teamNumber }: LoadingStageProps) {
12+
return (
13+
<div
14+
className="flex flex-col p-[20px] gap-4 rounded-[20px] bg-[#FAFAFF]
15+
md:flex-row md:items-center md:justify-between md:p-[60px]"
16+
>
17+
{/* RIGHT column — first in DOM so image appears at top on mobile, right on desktop */}
18+
<div className="flex flex-col flex-1 w-full gap-3 md:order-2 md:self-stretch">
19+
{/* Image */}
20+
<div className="relative w-full h-[349px] bg-[#F3F3FC] rounded-[20px] flex items-center justify-center md:rounded-[16px] md:overflow-hidden">
21+
<Image
22+
src={loadingBus}
23+
alt="animated bus loading"
24+
fill
25+
unoptimized
26+
className="object-contain object-center rounded-[20px]"
27+
/>
28+
</div>
29+
30+
{/* Devpost Number — below image */}
31+
<div className="flex flex-col gap-1">
32+
<p className="text-[12px] font-normal text-[#878796] tracking-wide md:text-[14px]">
33+
DEVPOST NUMBER
34+
</p>
35+
36+
<input
37+
type="text"
38+
value={teamNumber}
39+
readOnly
40+
placeholder="#####"
41+
inputMode="numeric"
42+
maxLength={5}
43+
pattern="[0-9]*"
44+
className="w-full border border-[#E0E0F0] rounded-[12px] px-4 py-5 text-base bg-white placeholder:text-[#ACACB9] focus:outline-none cursor-default"
45+
/>
46+
</div>
47+
</div>
48+
49+
{/* LEFT column — second in DOM, reordered to first on desktop */}
50+
<div className="flex flex-col flex-1 md:self-stretch justify-between gap-8 md:order-1">
51+
<div className="flex flex-col gap-1">
52+
<h3 className="text-[18px] font-semibold sm:text-[22px] md:text-[26px] lg:text-[32px]">
53+
Searching high and low...
54+
</h3>
55+
56+
<p className="text-[18px] font-semibold text-[#878796] sm:text-[22px] md:text-[26px] lg:text-[32px] leading-normal">
57+
Did you know that this year is HackDavis's 10 year anniversary?
58+
</p>
59+
</div>
60+
61+
{/* Buttons */}
62+
<div className="flex justify-between items-center md:justify-normal md:gap-[56px]">
63+
<button
64+
disabled
65+
className="text-[#5E5E65] text-base font-semibold border-none bg-transparent opacity-30"
66+
>
67+
Back
68+
</button>
69+
70+
<button
71+
disabled
72+
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"
73+
>
74+
Next
75+
<div className="relative w-6 h-6 ml-2">
76+
<Image
77+
src={rightArrow}
78+
alt="Right Arrow"
79+
fill
80+
className="object-cover"
81+
/>
82+
</div>
83+
</button>
84+
</div>
85+
</div>
86+
</div>
87+
);
88+
}

0 commit comments

Comments
 (0)