"use client"; import { useEffect, useRef } from "react"; import { ArticleView } from "./ArticleView"; import { Breadcrumbs } from "./Breadcrumbs"; import type { Room } from "../api/rooms/route"; import { useCtrlFBlock } from "../../lib/useSearchAllowed"; type GameScreenProps = { room: Room; playerId: string; html: string; title: string; loading: boolean; loadError: string | null; history: string[]; clicks: number; elapsed: string; countdown: number | null; timeLeft: number | null; onNavigate: (title: string) => void; onGoBack: () => void; canGoBack: boolean; onRetry: () => void; onNextRound: () => void; onStartGame: () => void; onResetGame: () => void; onSurrender: () => void; }; export function GameScreen({ room, playerId, html, title, loading, loadError, history, clicks, elapsed, countdown, timeLeft, onNavigate, onGoBack, canGoBack, onRetry, onNextRound, onStartGame, onResetGame, onSurrender, }: GameScreenProps) { const breadcrumbEndRef = useRef(null); useCtrlFBlock(room.searchAllowed); function fmtMs(ms: number): string { const s = Math.floor(ms / 1000); const m = Math.floor(s / 60); const sec = s % 60; return m > 0 ? `${m}:${String(sec).padStart(2, "0")}` : `${sec}s`; } const myPlayer = room.players.find((p) => p.id === playerId); const isHost = myPlayer?.isHost ?? false; const myFinished = myPlayer?.hasWon || myPlayer?.hasSurrendered; const sortedPlayers = [...room.players].sort((a, b) => b.score - a.score); const winner = room.roundWinner ? room.players.find((p) => p.id === room.roundWinner) : null; useEffect(() => { breadcrumbEndRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "end", }); }, [history]); const btnPrimary = "w-full min-h-11 px-5 rounded-xl text-sm font-semibold bg-[#7c3aed] text-white hover:bg-[#6d28d9] cursor-pointer transition-colors"; const btnGhost = "w-full min-h-11 px-5 rounded-xl text-sm font-semibold bg-[#242424] border border-[#2e2e2e] text-[#f0f0f0] hover:bg-[#1a1a1a] cursor-pointer transition-colors"; // Results if (room.phase === "results") return (
{winner ? ( <>
🏆
{winner.name} a gagné la manche !
) : (
Manche terminée !
)}
{room.startArticle} → {room.targetArticle}

Classement

    {sortedPlayers.map((p, i) => (
  • #{i + 1} {p.name} {p.hasWon && ( ✓ TrouvĂ© )} {p.hasSurrendered && ( Forfait )} {p.score} pts
    {p.path && p.path.length > 0 && (
    {p.path.map((t, j) => ( {j > 0 && â€ș} {t} ))} ({p.path.length - 1} clic {p.path.length - 1 > 1 ? "s" : ""} {p.hasWon && p.wonAt && room.roundStart ? ` · ${fmtMs(p.wonAt - room.roundStart)}` : ""} )
    )}
  • ))}
Manche {room.round}/{room.totalRounds}
{isHost ? (
{room.round < room.totalRounds ? ( ) : ( )} {room.round < room.totalRounds && ( )}
) : (

En attente de l'hĂŽte...

)}
); // Entre les manches : attente que l'hÎte démarre la suivante if (room.phase === "waiting") return (
Manche {room.round}/{room.totalRounds} terminée

{isHost ? "Lance la manche suivante quand tu veux." : "En attente que l'hÎte démarre la prochaine manche..."}

{isHost && (
)}
); // Countdown if (room.phase === "countdown") return (
Départ {room.startArticle}
→
Cible {room.targetArticle}
{countdown !== null && countdown > 0 ? countdown : "Partez !"}
); // Playing return (
{/* Topbar */}
Cible → {room.targetArticle}
{timeLeft !== null && ( {timeLeft}s )} {elapsed} {clicks} clics {myPlayer?.score ?? 0} pts
{!myFinished && canGoBack && ( )} {!myFinished && ( )} {myFinished && myPlayer?.hasWon && ( ✓ TrouvĂ© ! )} {myFinished && myPlayer?.hasSurrendered && ( Forfait )}
{/* Content */}
{loading && (
Chargement...
)} {loadError && (

{loadError}

)} {!loading && !loadError && html && (

{title}

)}
{/* Sidebar - desktop seulement */}
); }