Add show rankings
This commit is contained in:
parent
cc30b13383
commit
3655d4d456
2 changed files with 282 additions and 9 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Player } from '../types';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Trophy, Medal, RotateCcw } from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { Trophy, Medal, RotateCcw, List, X } from 'lucide-react';
|
||||
import confetti from 'canvas-confetti';
|
||||
import { PlayerAvatar } from './PlayerAvatar';
|
||||
|
||||
|
|
@ -11,6 +11,7 @@ interface PodiumProps {
|
|||
}
|
||||
|
||||
export const Podium: React.FC<PodiumProps> = ({ players, onRestart }) => {
|
||||
const [showRankings, setShowRankings] = useState(false);
|
||||
const sorted = [...players].sort((a, b) => b.score - a.score);
|
||||
const winner = sorted[0];
|
||||
const second = sorted[1];
|
||||
|
|
@ -87,12 +88,78 @@ export const Podium: React.FC<PodiumProps> = ({ players, onRestart }) => {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={onRestart}
|
||||
className="flex items-center gap-3 bg-white text-theme-primary px-10 py-4 rounded-2xl text-2xl font-black hover:scale-105 transition shadow-[0_8px_0_rgba(0,0,0,0.2)] active:shadow-none active:translate-y-[8px]"
|
||||
>
|
||||
<RotateCcw size={28} /> Play Again
|
||||
</button>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => setShowRankings(true)}
|
||||
className="flex items-center gap-2 bg-white/20 text-white px-5 py-4 rounded-2xl text-lg font-bold hover:bg-white/30 transition"
|
||||
>
|
||||
<List size={22} /> All Rankings
|
||||
</button>
|
||||
<button
|
||||
onClick={onRestart}
|
||||
className="flex items-center gap-3 bg-white text-theme-primary px-10 py-4 rounded-2xl text-2xl font-black hover:scale-105 transition shadow-[0_8px_0_rgba(0,0,0,0.2)] active:shadow-none active:translate-y-[8px]"
|
||||
>
|
||||
<RotateCcw size={28} /> Play Again
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AnimatePresence>
|
||||
{showRankings && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 bg-black/70 backdrop-blur-sm flex items-center justify-center z-50 p-4"
|
||||
onClick={() => setShowRankings(false)}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ scale: 0.9, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0.9, opacity: 0 }}
|
||||
className="bg-white rounded-3xl p-6 max-w-md w-full max-h-[80vh] overflow-hidden flex flex-col shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-2xl font-black text-gray-900">Final Rankings</h2>
|
||||
<button
|
||||
onClick={() => setShowRankings(false)}
|
||||
className="p-2 hover:bg-gray-100 rounded-full transition"
|
||||
>
|
||||
<X size={24} className="text-gray-500" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="overflow-y-auto flex-1 -mx-2 px-2">
|
||||
{sorted.map((player, index) => (
|
||||
<div
|
||||
key={player.id}
|
||||
className={`flex items-center gap-3 p-3 rounded-xl mb-2 ${
|
||||
index === 0 ? 'bg-yellow-100' :
|
||||
index === 1 ? 'bg-gray-100' :
|
||||
index === 2 ? 'bg-orange-100' :
|
||||
'bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
<div className={`w-8 h-8 rounded-full flex items-center justify-center font-black text-sm ${
|
||||
index === 0 ? 'bg-yellow-400 text-yellow-900' :
|
||||
index === 1 ? 'bg-gray-300 text-gray-700' :
|
||||
index === 2 ? 'bg-orange-400 text-orange-900' :
|
||||
'bg-gray-200 text-gray-600'
|
||||
}`}>
|
||||
{index + 1}
|
||||
</div>
|
||||
<PlayerAvatar seed={player.avatarSeed} size={36} />
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-bold text-gray-900 truncate">{player.name}</p>
|
||||
</div>
|
||||
<div className="font-black text-lg text-gray-700">{player.score}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue