feat(game): enhance leaderboard structure and animation in Leaderboard component

This commit is contained in:
Ralex
2025-10-26 17:41:04 +01:00
parent 2b499190a2
commit 349c9337e6
5 changed files with 125 additions and 21 deletions

View File

@@ -1,26 +1,63 @@
import { ManagerStatusDataMap } from "@rahoot/common/types/game/status"
import { AnimatePresence, motion } from "motion/react"
import { useEffect, useState } from "react"
type Props = {
data: ManagerStatusDataMap["SHOW_LEADERBOARD"]
}
const Leaderboard = ({ data: { leaderboard } }: Props) => (
<section className="relative mx-auto flex w-full max-w-7xl flex-1 flex-col items-center justify-center px-2">
<h2 className="mb-6 text-5xl font-bold text-white drop-shadow-md">
Leaderboard
</h2>
<div className="flex w-full flex-col gap-2">
{leaderboard.map(({ username, points }, key) => (
<div
key={key}
className="bg-primary flex w-full justify-between rounded-md p-3 text-2xl font-bold text-white"
>
<span className="drop-shadow-md">{username}</span>
<span className="drop-shadow-md">{points}</span>
</div>
))}
</div>
</section>
)
const Leaderboard = ({ data: { oldLeaderboard, leaderboard } }: Props) => {
const [displayedLeaderboard, setDisplayedLeaderboard] =
useState(oldLeaderboard)
useEffect(() => {
setDisplayedLeaderboard(oldLeaderboard)
const timer = setTimeout(() => {
setDisplayedLeaderboard(leaderboard)
}, 2000)
return () => clearTimeout(timer)
}, [oldLeaderboard, leaderboard])
return (
<section className="relative mx-auto flex w-full max-w-3xl flex-1 flex-col items-center justify-center px-2">
<h2 className="mb-6 text-5xl font-bold text-white drop-shadow-md">
Leaderboard
</h2>
<div className="flex w-full flex-col gap-2">
<AnimatePresence mode="popLayout">
{displayedLeaderboard.map(({ username, points }) => (
<motion.div
key={username}
layout
initial={{ opacity: 0, y: 50 }}
animate={{
opacity: 1,
y: 0,
}}
exit={{
opacity: 0,
y: 50,
transition: { duration: 0.2 },
}}
transition={{
layout: {
type: "spring",
stiffness: 350,
damping: 25,
},
}}
className="bg-primary flex w-full justify-between rounded-md p-3 text-2xl font-bold text-white"
>
<span className="drop-shadow-md">{username}</span>
<span className="drop-shadow-md">{points}</span>
</motion.div>
))}
</AnimatePresence>
</div>
</section>
)
}
export default Leaderboard