Skip to content

Commit 6b37b9c

Browse files
committed
Merge branch 'main' into issue-31-Create_match_details_page
2 parents 0df0258 + 8459046 commit 6b37b9c

25 files changed

Lines changed: 1534 additions & 294 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,4 +291,7 @@ dist
291291
# misc
292292
.DS_Store
293293

294-
opt/
294+
opt/
295+
296+
/server/static_files
297+
/server/media

client/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ yarn-error.log*
3333

3434
# typescript
3535
*.tsbuildinfo
36-
next-env.d.ts
36+
next-env.d.ts

client/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ const nextConfig = {
2323
: undefined,
2424
};
2525

26-
export default nextConfig;
26+
export default nextConfig;

client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@
5252
"tailwindcss": "^3.4.17",
5353
"typescript": "^5.8.3"
5454
}
55-
}
55+
}

client/public/Drone.svg

Lines changed: 3 additions & 0 deletions
Loading

client/public/FinishFlag.svg

Lines changed: 3 additions & 0 deletions
Loading

client/public/Line2.svg

Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import React, { useState } from "react";
2+
3+
interface CheckListItem {
4+
id: string;
5+
text: string;
6+
checked: boolean;
7+
}
8+
9+
const CheckList: React.FC = () => {
10+
const [items, setItems] = useState<CheckListItem[]>([
11+
// Equipment Requirements
12+
{ id: "1", text: "Drone is a quadcopter (four rotors)", checked: false },
13+
{ id: "2", text: "Aircraft wheelbase is maximum 180mm", checked: false },
14+
{
15+
id: "3",
16+
text: "Battery-based flight time of at least 5 minutes",
17+
checked: false,
18+
},
19+
{
20+
id: "4",
21+
text: "Takeoff weight is less than 250g (including protective guard and battery)",
22+
checked: false,
23+
},
24+
{
25+
id: "5",
26+
text: "Drone has fully enclosed protective guard for flight safety",
27+
checked: false,
28+
},
29+
{
30+
id: "6",
31+
text: "Drone can be controlled via physical remote controller",
32+
checked: false,
33+
},
34+
]);
35+
36+
const toggleCheck = (id: string) => {
37+
setItems(
38+
items.map((item) =>
39+
item.id === id ? { ...item, checked: !item.checked } : item,
40+
),
41+
);
42+
};
43+
44+
const CheckmarkIcon = () => (
45+
<svg
46+
xmlns="http://www.w3.org/2000/svg"
47+
className="h-4 w-4 text-white"
48+
fill="none"
49+
viewBox="0 0 24 24"
50+
stroke="currentColor"
51+
strokeWidth={2.5}
52+
>
53+
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
54+
</svg>
55+
);
56+
57+
const completedCount = items.filter((item) => item.checked).length;
58+
const completionPercentage = (completedCount / items.length) * 100;
59+
60+
return (
61+
<section className="mx-auto max-w-md">
62+
{/* Main Card Container */}
63+
<div className="overflow-hidden rounded-2xl border border-gray-100 bg-white shadow-lg">
64+
{/* Header Section */}
65+
<div className="border-b border-gray-100 bg-white px-8 py-6">
66+
<h2 className="subtitle mb-2 text-gray-800">
67+
Equipment Requirements Checklist
68+
</h2>
69+
70+
{/* Progress Indicator */}
71+
<div className="caption mb-3 flex items-center justify-between text-gray-600">
72+
<span className="font-medium">
73+
{completedCount} of {items.length} completed
74+
</span>
75+
<span className="medium-md font-semibold text-blue-600">
76+
{Math.round(completionPercentage)}%
77+
</span>
78+
</div>
79+
80+
{/* Progress Bar */}
81+
<div className="h-2 w-full overflow-hidden rounded-full bg-gray-200">
82+
<div
83+
className="h-full rounded-full bg-gradient-to-r from-blue-500 to-indigo-600 transition-all duration-500 ease-out"
84+
style={{ width: `${completionPercentage}%` }}
85+
/>
86+
</div>
87+
</div>
88+
89+
{/* Checklist Items */}
90+
<div className="p-6">
91+
<div className="space-y-3">
92+
{items.map((item, index) => (
93+
<div key={item.id}>
94+
{/* Section Divider */}
95+
{index === 6 && (
96+
<div className="flex items-center gap-3 py-3">
97+
<div className="h-px flex-1 bg-gray-300"></div>
98+
<span className="caption font-medium text-gray-500">
99+
Items to Bring
100+
</span>
101+
<div className="h-px flex-1 bg-gray-300"></div>
102+
</div>
103+
)}
104+
105+
<div
106+
className={`group flex cursor-pointer items-center gap-4 rounded-xl p-4 transition-all duration-200 ${
107+
item.checked
108+
? "border border-green-200 bg-green-50"
109+
: "border border-transparent bg-gray-50 hover:border-blue-200 hover:bg-blue-50 hover:shadow-sm"
110+
}`}
111+
onClick={() => toggleCheck(item.id)}
112+
>
113+
{/* Custom Checkbox */}
114+
<div className="flex-shrink-0">
115+
<div
116+
className={`flex h-6 w-6 items-center justify-center rounded-lg border-2 transition-all duration-200 ${
117+
item.checked
118+
? "border-blue-600 bg-blue-600 shadow-md"
119+
: "border-gray-300 bg-white group-hover:border-blue-400"
120+
}`}
121+
>
122+
{item.checked && (
123+
<div className="scale-110 transform">
124+
<CheckmarkIcon />
125+
</div>
126+
)}
127+
</div>
128+
</div>
129+
130+
{/* Item Text */}
131+
<span
132+
className={`body-sm flex-1 select-none transition-all duration-200 ${
133+
item.checked
134+
? "text-green-700 line-through"
135+
: "text-gray-800 group-hover:text-blue-800"
136+
}`}
137+
>
138+
{item.text}
139+
</span>
140+
</div>
141+
</div>
142+
))}
143+
</div>
144+
</div>
145+
146+
{/* Footer Section */}
147+
{completionPercentage === 100 && (
148+
<div className="border-t border-green-100 bg-gradient-to-r from-green-50 to-emerald-50 px-6 py-4">
149+
<div className="flex items-center gap-3">
150+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-green-600">
151+
<CheckmarkIcon />
152+
</div>
153+
<div>
154+
<p className="body-lg text-green-800">
155+
Equipment ready! Your drone meets all requirements
156+
</p>
157+
<p className="caption text-green-700">
158+
Remember: All equipment will be inspected by organizers. Good
159+
luck! 🚁
160+
</p>
161+
</div>
162+
</div>
163+
</div>
164+
)}
165+
166+
{/* Motivational Footer */}
167+
{completionPercentage < 100 && (
168+
<div className="border-t border-gray-100 bg-gray-50 px-6 py-4">
169+
<p className="caption text-center text-gray-600">
170+
<span className="font-medium text-gray-800">
171+
{items.length - completedCount} requirements remaining
172+
</span>{" "}
173+
• Ensure your drone meets all specifications before competition!
174+
</p>
175+
</div>
176+
)}
177+
</div>
178+
</section>
179+
);
180+
};
181+
182+
export default CheckList;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
interface StageSectionProps {
2+
title: string;
3+
description: string;
4+
}
5+
6+
export default function StageSection({
7+
title,
8+
description,
9+
}: StageSectionProps) {
10+
return (
11+
<section className="rounded-lg border border-gray-200 bg-white p-6 shadow-sm">
12+
<h2 className="mb-4 text-2xl font-semibold text-gray-900">{title}</h2>
13+
<p className="leading-relaxed text-gray-700">{description}</p>
14+
</section>
15+
);
16+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import Image from "next/image";
2+
import { title } from "process";
3+
import * as React from "react";
4+
5+
export default function ProgressBar({ pageName }: { pageName: string }) {
6+
let progress = 0;
7+
let titleName = "";
8+
switch (pageName) {
9+
case "schedule":
10+
progress = 0;
11+
titleName = "Schedule";
12+
break;
13+
case "format-rules":
14+
progress = 25;
15+
titleName = "Format Rules";
16+
break;
17+
case "leaderboard":
18+
titleName = "Leaderboard";
19+
progress = 50;
20+
break;
21+
case "sponsor-guest":
22+
titleName = "Sponsor & Guest";
23+
progress = 75;
24+
break;
25+
}
26+
27+
return (
28+
<div>
29+
<div className="customerBar w-full flex-col justify-center gap-2">
30+
<div className="mb-10 flex items-center justify-center">
31+
<a className="title-large">{titleName}</a>
32+
</div>
33+
<div className="flex flex-1">
34+
<div
35+
className="flex-shrink-0"
36+
style={{
37+
width: `${progress}%`,
38+
transition: "width 3s ease-in-out",
39+
}}
40+
/>
41+
<div>
42+
<Image
43+
src="/Drone.svg"
44+
alt="Drone"
45+
width="50"
46+
height="20"
47+
className="object-contain"
48+
/>
49+
</div>
50+
51+
<div className="ml-auto">
52+
<Image
53+
src="/FinishFlag.svg"
54+
alt="Finish Flag"
55+
width="50"
56+
height="20"
57+
className="object-contain"
58+
/>
59+
</div>
60+
</div>
61+
62+
<div className="flex w-full">
63+
<div className="h-[2px] w-full bg-black" />
64+
</div>
65+
</div>
66+
</div>
67+
);
68+
}

0 commit comments

Comments
 (0)