diff --git a/apps/web/public/CostalStartupFest2026-02.webp b/apps/web/public/CostalStartupFest2026-02.webp new file mode 100644 index 0000000..b921d0a Binary files /dev/null and b/apps/web/public/CostalStartupFest2026-02.webp differ diff --git a/apps/web/public/Fiza_logo.webp b/apps/web/public/Fiza_logo.webp new file mode 100644 index 0000000..e90f58a Binary files /dev/null and b/apps/web/public/Fiza_logo.webp differ diff --git a/apps/web/public/Nitte_logo.webp b/apps/web/public/Nitte_logo.webp new file mode 100644 index 0000000..d61d3ac Binary files /dev/null and b/apps/web/public/Nitte_logo.webp differ diff --git a/apps/web/public/bg.webp b/apps/web/public/bg.webp new file mode 100644 index 0000000..96eb7c6 Binary files /dev/null and b/apps/web/public/bg.webp differ diff --git a/apps/web/public/cosc.png b/apps/web/public/cosc.png deleted file mode 100644 index 8bcde57..0000000 Binary files a/apps/web/public/cosc.png and /dev/null differ diff --git a/apps/web/public/cosc.webp b/apps/web/public/cosc.webp new file mode 100644 index 0000000..4338c22 Binary files /dev/null and b/apps/web/public/cosc.webp differ diff --git a/apps/web/public/dk24.png b/apps/web/public/dk24.png deleted file mode 100644 index 68b915f..0000000 Binary files a/apps/web/public/dk24.png and /dev/null differ diff --git a/apps/web/public/dk24.webp b/apps/web/public/dk24.webp new file mode 100644 index 0000000..780ea36 Binary files /dev/null and b/apps/web/public/dk24.webp differ diff --git a/apps/web/public/sceptix.png b/apps/web/public/sceptix.png deleted file mode 100644 index a4d77e4..0000000 Binary files a/apps/web/public/sceptix.png and /dev/null differ diff --git a/apps/web/public/sceptix.webp b/apps/web/public/sceptix.webp new file mode 100644 index 0000000..9ab5269 Binary files /dev/null and b/apps/web/public/sceptix.webp differ diff --git a/apps/web/public/sosc.png b/apps/web/public/sosc.png deleted file mode 100644 index 5e2d425..0000000 Binary files a/apps/web/public/sosc.png and /dev/null differ diff --git a/apps/web/public/sosc.webp b/apps/web/public/sosc.webp new file mode 100644 index 0000000..3dff733 Binary files /dev/null and b/apps/web/public/sosc.webp differ diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 4d3c58d..0283d0e 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -36,7 +36,7 @@ export default function App() { }); const [currentStallData, setCurrentStallData] = useState<{ id: number, name: string, description: string, logo: string } | null>(null); - const totalStalls = 13; + const totalStalls = 11; // Sync user to DB after Clerk sign-in and fetch true progress useEffect(() => { @@ -343,8 +343,6 @@ export default function App() { {currentScreen === 'rating' && currentStallData && ( setCurrentScreen('scanner')} - onProgress={() => setCurrentScreen('progress')} onSubmitSuccess={handleRatingSubmit} ratedCount={serverProgress} totalCount={totalStalls} @@ -358,7 +356,7 @@ export default function App() { onScanNext={() => setCurrentScreen('scanner')} totalCount={totalStalls} serverProgress={serverProgress} - onBackToVote={() => setCurrentScreen('scanner')} + /> )} @@ -372,4 +370,4 @@ export default function App() { ); -} +} \ No newline at end of file diff --git a/apps/web/src/components/CompletionScreen.tsx b/apps/web/src/components/CompletionScreen.tsx index 9a9b9d0..073e9dc 100644 --- a/apps/web/src/components/CompletionScreen.tsx +++ b/apps/web/src/components/CompletionScreen.tsx @@ -1,7 +1,5 @@ import { motion } from 'motion/react'; -import { X, CheckCircle2, Star } from 'lucide-react'; -import { UserButton } from "@clerk/react"; -import Footer from "./Footer"; +import { CheckCircle2, Star } from 'lucide-react'; interface CompletionScreenProps { onClose: () => void; @@ -9,78 +7,154 @@ interface CompletionScreenProps { onViewLeaderboard: () => void; } -export default function CompletionScreen({ onClose }: CompletionScreenProps) { +export default function CompletionScreen({ }: CompletionScreenProps) { return ( -
- {/* Header */} -
-

Coastal Startup Fest

-
- - +
+
+ {/* Dark gradient overlay */} +
+ + {/* Branding - Top Corner Page Overlays */} +
+ Nitte +
+
+ Fiza
-
-
- {/* Hero Illustration */} -
- {/* Background Decorative Frame */} -
-
+
+ {/* Hero Illustration - Balanced size for no-scroll */} +
+ {/* Background Decorative Frame */} +
+
- {/* Main Visual (Red/Orange Card) */} - -
-
- -
- + {/* Main Visual (Purple Card with Pattern) */} + + {/* Subtle Dot Grid Pattern */} +
- {/* Submission Success Card Overlay */} - -
- -
-
- Submission Success -
- 15/15 +
+ +
+ + + {/* Submission Success Card Overlay */} + +
+ +
+
+ VOTED +
+ 11/11 +
+ Rating Success
- Stalls Rated Today +
+
+ + {/* Text Content */} +
+

+ YOU'VE RATED ALL
+ 11 STALLS! +

+

+ Thank you for participating! +

+
+ + {/* Branding Block - Re-enlarged but strictly positioned */} +
+ {/* Powered By Section */} +
+ + Powered By + + +
+ DK24 +
+
- -
- {/* Text Content */} -
-

- You've rated all
- 15 stalls! -

-

- Your votes are now officially counted.
- Thank you for participating! -

-
- -
-
-
-
+ {/* In Collaboration Section */} +
+ + In Collaboration with + +
+ {[ + { + id: 1, + src: "/cosc.webp", + alt: "COSC", + url: "https://www.linkedin.com/company/canara-students-open-source-community/", + }, + { + id: 2, + src: "/sosc.webp", + alt: "SOSC", + url: "https://sosc.org.in/", + }, + { + id: 3, + src: "/sceptix.webp", + alt: "Sceptix", + url: "https://www.sceptix.in/", + }, + ].map((logo) => ( + + {logo.alt} + + ))} +
+
+
+
+
); } diff --git a/apps/web/src/components/Footer.tsx b/apps/web/src/components/Footer.tsx index 0ff91dd..67ed36b 100644 --- a/apps/web/src/components/Footer.tsx +++ b/apps/web/src/components/Footer.tsx @@ -29,7 +29,7 @@ export default function Footer({ >
DK24 @@ -50,19 +50,19 @@ export default function Footer({ {[ { id: 1, - src: "/cosc.png", + src: "/cosc.webp", alt: "COSC", url: "https://www.linkedin.com/company/canara-students-open-source-community/", }, { id: 2, - src: "/sosc.png", + src: "/sosc.webp", alt: "SOSC", url: "https://sosc.org.in/", }, { id: 3, - src: "/sceptix.png", + src: "/sceptix.webp", alt: "Sceptix", url: "https://www.sceptix.in/", }, diff --git a/apps/web/src/components/LoginScreen.tsx b/apps/web/src/components/LoginScreen.tsx index 2bbbb11..217382d 100644 --- a/apps/web/src/components/LoginScreen.tsx +++ b/apps/web/src/components/LoginScreen.tsx @@ -9,7 +9,7 @@ export default function LoginScreen({ onStart }: LoginScreenProps) { return (
diff --git a/apps/web/src/components/ProgressScreen.tsx b/apps/web/src/components/ProgressScreen.tsx index 1673588..f1187a6 100644 --- a/apps/web/src/components/ProgressScreen.tsx +++ b/apps/web/src/components/ProgressScreen.tsx @@ -1,10 +1,16 @@ import { motion } from 'motion/react'; -import { QrCode, CheckCircle2, Lock, Vote, BarChart3, User, ChevronLeft } from 'lucide-react'; -import { UserButton } from "@clerk/react"; -import Footer from "./Footer"; +import { QrCode, CheckCircle2, Lock } from 'lucide-react'; + +function cn(...classes: (string | undefined | boolean | null | Record)[]) { + return classes.filter(Boolean).map(c => { + if (typeof c === 'object') { + return Object.entries(c!).filter(([_, v]) => v).map(([k, _]) => k).join(' '); + } + return c; + }).join(' '); +} interface ProgressScreenProps { - onBackToVote?: () => void; onProfile?: () => void; onScanNext?: () => void; ratings?: Record; @@ -14,200 +20,216 @@ interface ProgressScreenProps { } export default function ProgressScreen({ - onBackToVote, - onProfile, onScanNext, ratings = {}, - ratedStalls = [], - totalCount = 13, + totalCount = 11, serverProgress = 0 }: ProgressScreenProps) { // Always use the server's synced progress as the ultimate source of truth, fallback to local if 0 const localRatedCount = Object.keys(ratings).length; const ratedCount = Math.max(serverProgress, localRatedCount); - const progressPercentage = Math.round((ratedCount / totalCount) * 100); + return ( -
- {/* Header */} -
-
- -

Coastal Startup Fest

+
+
+ {/* Dark gradient overlay */} +
+ + {/* Branding - Top Corner Page Overlays */} +
+ Nitte
-
- + +
+ Fiza
-
- -
- {/* Hero Section */} -
- Your Journey -

You're making progress!

- - {/* Progress Summary Card */} - -
-
-
- {ratedCount} - /{totalCount} + +
+ {/* Hero Section */} +
+
+ Coastal Startup Fest +
+ {/* Directory Section */} +
+
+

Stall Directory

+
+
+ Live Updates
- Stalls Rated -
-
- {progressPercentage}% Complete
-
-
- -
-
-
+
+ {Array.from({ length: totalCount }).map((_, i) => { + const status = ratings[String(i + 1)] !== undefined ? 'rated' : 'locked'; -

- You are voting for the People’s Choice Award. -

-
+ return ( + + {status === 'rated' ? ( + + ) : ( + + )} -
- ⚠️ -

- Your votes will be counted only if you rate at least 12 different stalls. -

+ {status === 'rated' && ( + +
+ + )} + + ); + })}
-
- - {/* Scan Button / Completion Action */} - {ratedCount < totalCount ? ( - - - Scan the next QR code - - ) : ( - - - All Stalls Rated! - - )} -
+ {/* Inner subtle glow */} +
+
+
+ 🏆 +

+ You are voting for the People’s Choice Award. +

+
- {/* Directory Section */} -
-
-

Stall Directory

-
+
+ ⚠️ +

+ Your votes will be counted only if you rate all 11 stalls. +

+
+
+ + + {/* Scan Button / Completion Action */} + {ratedCount < totalCount ? ( + + + Scan QR Code + + ) : ( +
+ + All Stalls Rated! +
+ )} -
- {Array.from({ length: totalCount }).map((_, i) => { - // We map purely by index for the visual directory slots. - // Now we explicitly match the DB stallId to the strict slot index so 6 maps to 6! - const expectedStallId = i + 1; - const ratedStall = ratedStalls.find(s => s.stallId === expectedStallId); - - const status = ratedStall ? 'rated' : 'locked'; - - const displayId = String(i + 1).padStart(2, '0'); - const stallName = ratedStall ? ratedStall.stallName : 'Locked Stall'; - - return ( - + {/* Powered By Section */} +
+ + Powered By + + -
-
- {displayId} -
-
-

- {stallName} -

- - {status === 'rated' ? 'Rating submitted' : 'Scan QR to unlock'} - -
+
+ DK24
-
- {status === 'rated' ? ( -
- -
- ) : ( -
+ + {/* In Collaboration Section */} +
+ + In Collaboration with + +
+ {[ + { + id: 1, + src: "/cosc.webp", + alt: "COSC", + url: "https://www.linkedin.com/company/canara-students-open-source-community/", + }, + { + id: 2, + src: "/sosc.webp", + alt: "SOSC", + url: "https://sosc.org.in/", + }, + { + id: 3, + src: "/sceptix.webp", + alt: "Sceptix", + url: "https://www.sceptix.in/", + }, + ].map((logo) => ( + +
+ {logo.alt}
- )} -
- - ); - })} + + ))} +
+
+
-
- - {/* Footer */} -
-
-
-
- - {/* Bottom Navigation */} - + + {/* Directory Section */} + +
+
); } diff --git a/apps/web/src/components/RatingScreen.tsx b/apps/web/src/components/RatingScreen.tsx index faa2e3c..532c5ae 100644 --- a/apps/web/src/components/RatingScreen.tsx +++ b/apps/web/src/components/RatingScreen.tsx @@ -1,214 +1,283 @@ import { useState } from 'react'; import { motion } from 'motion/react'; -import { User, ChevronLeft, Send, BarChart3, Vote } from 'lucide-react'; -import { UserButton } from "@clerk/react"; -import Footer from "./Footer"; +import { Send } from 'lucide-react'; interface RatingScreenProps { stallData: { id: number; name: string; description: string; logo: string | null }; - onBack?: () => void; - onProgress?: () => void; onSubmitSuccess?: (rating: number) => void; ratedCount?: number; totalCount?: number; } -export default function RatingScreen({ stallData, onBack, onProgress, onSubmitSuccess, ratedCount = 0, totalCount = 13 }: RatingScreenProps) { +export default function RatingScreen({ stallData, onSubmitSuccess }: RatingScreenProps) { const [selectedRating, setSelectedRating] = useState(null); const [isSubmitted, setIsSubmitted] = useState(false); + const handleSliderChange = (e: React.ChangeEvent) => { + setSelectedRating(parseInt(e.target.value, 10)); + }; + + const getRatingColor = (val: number | null) => { + if (val === null) return "#94a3b8"; + if (val <= 3) return "#f43f5e"; + if (val <= 7) return "#fbbf24"; + return "#22c55e"; + }; + const handleSubmit = () => { if (selectedRating !== null) { setIsSubmitted(true); - - // Simulate network delay then redirect setTimeout(() => { onSubmitSuccess?.(selectedRating); }, 1500); } }; - const ratings = Array.from({ length: 11 }, (_, i) => i); - return ( -
- {/* Header */} -
-
- -

Coastal Startup Fest

+
+
+ {/* Dark gradient overlay for readability if the image is too bright */} +
+ + {/* Branding - Top Corner Page Overlays */} +
+ Nitte
-
- + +
+ Fiza
-
- -
- {/* Progress Section */} -
-
-
- Your Progress -

{ratedCount}/{totalCount} stalls rated

-
- {Math.round((ratedCount / totalCount) * 100)}% -
-
- + +
+ {/* CURRENT STALL */} +
+
+ Current Stall +
-
- {/* Current Stall Card */} -
- - {/* Topographic Pattern Overlay */} - - - - - - -
-
-
- -
-
- Current Stall -

{stallData.name}

-
-

- {stallData.description || "No description provided."} -

-
-
-
-
+

+ {stallData.name} +

- {/* Rating Grid */} -
- {!isSubmitted ? ( -
-
- 🏆 -
-

- You are voting for the People’s Choice Award. -

-

- Please rate this Startup on a scale of 0–10. -

-
-
+ {/* Info Card */} +
+ {/* Inner subtle glow */} +
-
- ⚠️ -

- Your votes will be counted only if you rate at least 12 different stalls. + {/* Trophy Info */} +

+ 🏆 +
+

+ You are voting for the People's Choice Award. +

+

+ Please rate this Startup on a scale of 0–10.

- ) : ( -
-

- Your rating has been recorded ✔️ -

-

- You voted {selectedRating}/10 for this stall. + + {/* Warning Badge */} +

+ ⚠️ +

+ Your votes will be counted only if you rate all 11 stalls.

- )} +
+
+
+ +
-
- {ratings.map((rating) => ( - + {/* Liquid Glow Effect */} +
+ +
+ + {/* Tick Marks - Enhanced */} +
+ {[...Array(11)].map((_, i) => ( +
+ ))} +
+ + {/* Native Input Range */} + setSelectedRating(rating)} - className={` - aspect-square rounded-2xl flex items-center justify-center text-xl font-bold transition-all border-2 - ${selectedRating === rating - ? 'bg-[#FF2D55] border-[#FF2D55] text-white shadow-lg shadow-red-500/30' - : 'bg-slate-50 border-slate-100 text-slate-400 hover:border-slate-200'} - ${isSubmitted && selectedRating !== rating ? 'opacity-40' : ''} - ${isSubmitted ? 'cursor-default' : ''} - `} - > - {rating} - - ))} -
-
+ className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-30 disabled:cursor-default" + /> - {/* Submit Button */} -
- - {isSubmitted ? 'Vote Recorded' : 'Submit Rating'} - {!isSubmitted && } - {isSubmitted && ( + {/* Enhanced Custom Thumb - Rectangular Design */} -
+ {/* Number inside Thumb */} +
+ + {selectedRating ?? 0} + +
+
+ - )} - -
+
+
- {/* Footer */} -
-
-
-
- - {/* Bottom Navigation */} - + {/* Submit Button */} +
+ + {isSubmitted ? 'Vote Recorded' : 'Submit Rating'} + {!isSubmitted && } + {isSubmitted && ( + + )} + +
+ + {/* Branding Block - Vertical stacking for better visibility */} +
+ {/* Powered By Section */} +
+ + Powered By + + +
+ DK24 +
+ + + +
+
+ + {/* In Collaboration Section */} +
+ + In Collaboration with + +
+ {[ + { + id: 1, + src: "/cosc.webp", + alt: "COSC", + url: "https://www.linkedin.com/company/canara-students-open-source-community/", + }, + { + id: 2, + src: "/sosc.webp", + alt: "SOSC", + url: "https://sosc.org.in/", + }, + { + id: 3, + src: "/sceptix.webp", + alt: "Sceptix", + url: "https://www.sceptix.in/", + }, + ].map((logo) => ( + +
+ {logo.alt} +
+
+ ))} +
+
+
+ + {/* About this Startup */} +
+
+
+
+ About this Startup +
+
+

+ {stallData.description || "Innovating sustainable hardware for the next digital era."} +

+
+
+
+
); -} +} \ No newline at end of file