import { useEffect, useRef } from "react" import { AnimatePresence, motion } from "framer-motion" import { Check, Crown } from "lucide-react" import type { RoomSnapshot } from "@nerdware/shared" import { Avatar } from "@/components/avatar" import { celebrateLead } from "@/lib/confetti" import { useI18n } from "@/i18n/context" interface PlayerCardsProps { snapshot: RoomSnapshot playerId: string | null /** Affiche l'état de vote (manche en cours uniquement). */ showVoteStatus?: boolean /** playerIds ayant déjà validé leur réponse. */ votedIds?: string[] } /** HUD persistant : une card par joueur avec son score, couronne au leader. */ export function PlayerCards({ snapshot, playerId, showVoteStatus = false, votedIds = [], }: PlayerCardsProps) { const { t } = useI18n() const scoreOf = (id: string) => snapshot.scores.find((s) => s.playerId === id)?.score ?? 0 const max = Math.max(0, ...snapshot.players.map((p) => scoreOf(p.id))) const ranked = [...snapshot.players].sort( (a, b) => scoreOf(b.id) - scoreOf(a.id) ) const voted = new Set(votedIds) const leaderId = max > 0 ? ranked[0].id : null // Confettis quand un joueur DÉPASSE pour prendre la tête (pas à la 1re prise). const prevLeader = useRef(null) useEffect(() => { if (leaderId && leaderId !== prevLeader.current) { if (prevLeader.current !== null) { celebrateLead() } prevLeader.current = leaderId } }, [leaderId]) return (
{ranked.map((p) => { const score = scoreOf(p.id) const isLeader = max > 0 && score === max const isMe = p.id === playerId const hasVoted = voted.has(p.id) return ( {isLeader && ( )} {p.name} {isMe && ( {t.common.you} )} {score} {showVoteStatus && (hasVoted ? ( {t.playerCards.ready} ) : ( {t.playerCards.waiting} ))} ) })}
) }