Gold is the primary in both themes, Bricolage Grotesque carries the wordmark, titles and the score, and Movie A / Movie B wear the blue and magenta of three-strip Technicolor on their posters instead of colouring whole rows. The loop closes on screen - connectors light, a gold line draws back to Movie A, the row glows, then the result arrives - in place of confetti, on every play mode, scaled to the chain's length. Every page shares one header and hairline lists; copy is sentence case with one verb per flow, and the Home hero shows a real finished loop. Also clamps link counts at zero: an opponent who had not moved yet showed "-1 links".
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { CheckCircle2, Circle, Crown, Eye } from 'lucide-react';
|
|
import type { GameNightPlayer } from '@/api/game-night';
|
|
|
|
interface PlayerCardProps {
|
|
player: GameNightPlayer;
|
|
isCurrentUser: boolean;
|
|
onToggleReady?: () => void;
|
|
}
|
|
|
|
export default function PlayerCard({
|
|
player,
|
|
isCurrentUser,
|
|
onToggleReady,
|
|
}: PlayerCardProps) {
|
|
return (
|
|
<div
|
|
className={`rounded-lg bg-card p-5 space-y-2 ring-1 ${
|
|
isCurrentUser ? 'ring-2 ring-primary' : 'ring-foreground/10'
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<p className="font-medium">{player.user.username}</p>
|
|
{player.isHost && (
|
|
<Crown className="h-4 w-4 text-primary" />
|
|
)}
|
|
</div>
|
|
{player.isSpectator ? (
|
|
<Badge variant="secondary" className="text-xs">
|
|
<Eye className="mr-1 h-3 w-3" />
|
|
Spectator
|
|
</Badge>
|
|
) : player.isReady ? (
|
|
<CheckCircle2 className="h-5 w-5 text-success" />
|
|
) : (
|
|
<Circle className="h-5 w-5 text-muted-foreground" />
|
|
)}
|
|
</div>
|
|
|
|
{onToggleReady && !player.isSpectator && (
|
|
<Button
|
|
variant={player.isReady ? 'outline' : 'default'}
|
|
size="sm"
|
|
className="w-full"
|
|
onClick={onToggleReady}
|
|
>
|
|
{player.isReady ? 'Unready' : 'Ready'}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|