From 2aafe8fce9b3ce3c1e1fe9b8d512f48f2c6b2848 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 13 Jan 2026 11:28:39 -0700 Subject: [PATCH] Update UI --- components/Lobby.tsx | 7 ++-- components/PlayerAvatar.tsx | 58 ++++++++++++++++++++++++++ components/Podium.tsx | 13 +++--- components/Scoreboard.tsx | 83 +++++++++++++++++++++++-------------- 4 files changed, 119 insertions(+), 42 deletions(-) create mode 100644 components/PlayerAvatar.tsx diff --git a/components/Lobby.tsx b/components/Lobby.tsx index 8743df5..3a860a1 100644 --- a/components/Lobby.tsx +++ b/components/Lobby.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { Player } from '../types'; import { motion, AnimatePresence } from 'framer-motion'; -import { User, Sparkles } from 'lucide-react'; +import { Sparkles, User } from 'lucide-react'; +import { PlayerAvatar } from './PlayerAvatar'; interface LobbyProps { quizTitle: string; @@ -60,9 +61,7 @@ export const Lobby: React.FC = ({ quizTitle, players, gamePin, role, exit={{ scale: 0, opacity: 0 }} className="bg-white text-black px-6 py-3 rounded-full font-black text-xl shadow-[0_4px_0_rgba(0,0,0,0.2)] flex items-center gap-3 border-b-4 border-gray-200" > -
- -
+ {player.name} ))} diff --git a/components/PlayerAvatar.tsx b/components/PlayerAvatar.tsx new file mode 100644 index 0000000..67c51ca --- /dev/null +++ b/components/PlayerAvatar.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { + Cat, Dog, Bird, Fish, Rabbit, Turtle, + Ghost, Skull, Heart, Star, Moon, Sun, + Flame, Zap, Cloud, Snowflake, Leaf, Flower2, + Crown, Diamond, Gem, Trophy, Target, Anchor, + Rocket, Plane, Car, Bike, Train, Ship +} from 'lucide-react'; + +const ICONS = [ + Cat, Dog, Bird, Fish, Rabbit, Turtle, + Ghost, Skull, Heart, Star, Moon, Sun, + Flame, Zap, Cloud, Snowflake, Leaf, Flower2, + Crown, Diamond, Gem, Trophy, Target, Anchor, + Rocket, Plane, Car, Bike, Train, Ship +]; + +const GRADIENT_PAIRS = [ + ['#f472b6', '#c026d3'], + ['#fb923c', '#ea580c'], + ['#facc15', '#ca8a04'], + ['#4ade80', '#16a34a'], + ['#2dd4bf', '#0d9488'], + ['#38bdf8', '#0284c7'], + ['#818cf8', '#6366f1'], + ['#f87171', '#dc2626'], + ['#a78bfa', '#7c3aed'], + ['#fb7185', '#e11d48'], + ['#34d399', '#059669'], + ['#60a5fa', '#2563eb'], +]; + +interface PlayerAvatarProps { + seed: number; + size?: number; + className?: string; +} + +export const PlayerAvatar: React.FC = ({ seed, size = 24, className = '' }) => { + const iconIndex = Math.floor(seed * 1000) % ICONS.length; + const gradientIndex = Math.floor(seed * 10000) % GRADIENT_PAIRS.length; + + const Icon = ICONS[iconIndex]; + const [colorFrom, colorTo] = GRADIENT_PAIRS[gradientIndex]; + const gradientId = `avatar-gradient-${seed.toString().replace('.', '-')}`; + + return ( +
+ +
+ ); +}; diff --git a/components/Podium.tsx b/components/Podium.tsx index e1d4bd1..31526be 100644 --- a/components/Podium.tsx +++ b/components/Podium.tsx @@ -3,6 +3,7 @@ import { Player } from '../types'; import { motion } from 'framer-motion'; import { Trophy, Medal, RotateCcw } from 'lucide-react'; import confetti from 'canvas-confetti'; +import { PlayerAvatar } from './PlayerAvatar'; interface PodiumProps { players: Player[]; @@ -45,9 +46,9 @@ export const Podium: React.FC = ({ players, onRestart }) => { transition={{ type: 'spring', bounce: 0.5, delay: 0.5 }} className="w-1/3 bg-gray-200 rounded-t-[3rem] flex flex-col items-center justify-end p-6 relative border-x-4 border-t-4 border-white/50 shadow-xl" > -
+
{second.name} -
+
{second.score} @@ -61,9 +62,9 @@ export const Podium: React.FC = ({ players, onRestart }) => { transition={{ type: 'spring', bounce: 0.6, delay: 1 }} className="w-1/3 bg-yellow-400 rounded-t-[3rem] flex flex-col items-center justify-end p-6 relative z-10 shadow-2xl border-x-4 border-t-4 border-white/50" > -
+
{winner.name} -
+
{winner.score} @@ -77,9 +78,9 @@ export const Podium: React.FC = ({ players, onRestart }) => { transition={{ type: 'spring', bounce: 0.5, delay: 0 }} className="w-1/3 bg-orange-400 rounded-t-[3rem] flex flex-col items-center justify-end p-6 relative border-x-4 border-t-4 border-white/50 shadow-xl" > -
+
{third.name} -
+
{third.score} diff --git a/components/Scoreboard.tsx b/components/Scoreboard.tsx index 3833449..c8c952d 100644 --- a/components/Scoreboard.tsx +++ b/components/Scoreboard.tsx @@ -3,6 +3,7 @@ import { Player } from '../types'; import { motion } from 'framer-motion'; import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Cell, LabelList } from 'recharts'; import { Loader2 } from 'lucide-react'; +import { PlayerAvatar } from './PlayerAvatar'; interface ScoreboardProps { players: Player[]; @@ -24,39 +25,57 @@ export const Scoreboard: React.FC = ({ players, onNext, isHost,

Scoreboard

-
- - - - - - {sortedPlayers.map((entry, index) => ( - +
+ {sortedPlayers.map((player) => ( +
+ + {player.displayName} +
+ ))} +
+
+ + + + + + {sortedPlayers.map((entry, index) => ( + + ))} + { + const player = sortedPlayers[index as number]; + return ( + + {value} + + ); + }} /> - ))} - - - - + + + +