"use client"; import { useEffect, useRef, useState } from "react"; import { Avatar } from "@/components/avatar"; import { LaurelWreath } from "@/components/laurel-wreath"; import type { ProfileRow } from "./page"; const ITEM_WIDTH = 96; const REPEATS = 6; const SPIN_MS = 3200; function useReducedMotion() { const [reduced, setReduced] = useState( () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches, ); useEffect(() => { const query = window.matchMedia("(prefers-reduced-motion: reduce)"); const handler = () => setReduced(query.matches); query.addEventListener("change", handler); return () => query.removeEventListener("change", handler); }, []); return reduced; } export function RouletteSection({ profiles }: { profiles: ProfileRow[] }) { const reducedMotion = useReducedMotion(); const [citizensOnly, setCitizensOnly] = useState(false); const [spinning, setSpinning] = useState(false); const [strip, setStrip] = useState([]); const [offset, setOffset] = useState(0); const [transitionOn, setTransitionOn] = useState(false); const [winner, setWinner] = useState(null); const [lastWinner, setLastWinner] = useState(null); const containerRef = useRef(null); const pool = citizensOnly ? profiles.filter((m) => m.role !== "judge") : profiles; function handleSpin() { if (spinning || pool.length === 0) return; const chosen = pool[Math.floor(Math.random() * pool.length)]; if (reducedMotion) { setWinner(chosen); setLastWinner(chosen); return; } setWinner(null); setSpinning(true); const built: ProfileRow[] = []; for (let i = 0; i < REPEATS; i++) built.push(...pool); built.push(chosen); setStrip(built); setTransitionOn(false); setOffset(0); requestAnimationFrame(() => { const containerWidth = containerRef.current?.offsetWidth ?? 320; const finalIndex = built.length - 1; const target = finalIndex * ITEM_WIDTH + ITEM_WIDTH / 2 - containerWidth / 2; requestAnimationFrame(() => { setTransitionOn(true); setOffset(-target); }); }); } function handleTransitionEnd() { if (!spinning) return; setSpinning(false); const chosen = strip[strip.length - 1]; setWinner(chosen); setLastWinner(chosen); } return (

La Roulette

Que le sort désigne l'élu.

{profiles.length === 0 ? (

Personne n'est encore inscrit.

) : ( <>
{strip.length > 0 && (
{strip.map((member, index) => (
{member.pseudo}
))}
)}
{winner && (
{winner.pseudo} a été désigné(e) par le sort
)}
{lastWinner && !winner && (

Dernier élu : {lastWinner.pseudo}

)} )}
); }