From 47e5c2854ec5f95722a18aef09333dffb17aba62 Mon Sep 17 00:00:00 2001 From: AyoubBenziza Date: Thu, 11 Jun 2026 18:17:47 +0200 Subject: [PATCH] fix(web): center end-screen recap + shadcn tooltips - results page: when there are no tracks (quiz-only game), the recap was sitting in the left column of a 2-col grid; now a single section is centered (2 columns only when both tracks and recap exist) - add a shadcn Tooltip component (@workspace/ui, via radix-ui) and replace native browser title= tooltips: connection dot, back-office active toggle, and the locked blindtest tiles (now aria-disabled so the tooltip still triggers) Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/web/src/components/game-end-view.tsx | 24 +++++---- apps/web/src/components/lobby-view.tsx | 47 ++++++++++++++---- apps/web/src/pages/admin.tsx | 21 +++++--- apps/web/src/pages/room.tsx | 19 ++++++-- packages/ui/src/components/tooltip.tsx | 59 +++++++++++++++++++++++ 5 files changed, 139 insertions(+), 31 deletions(-) create mode 100644 packages/ui/src/components/tooltip.tsx diff --git a/apps/web/src/components/game-end-view.tsx b/apps/web/src/components/game-end-view.tsx index ce64d4d..cb18a90 100644 --- a/apps/web/src/components/game-end-view.tsx +++ b/apps/web/src/components/game-end-view.tsx @@ -178,6 +178,8 @@ export function GameEndView({ snapshot }: { snapshot: RoomSnapshot }) { const [first, second, third] = ranked const rest = ranked.slice(3) + const hasTracks = !!gameTracks && gameTracks.length > 0 + const hasRecap = !!gameRecap && gameRecap.length > 0 return (
@@ -256,15 +258,19 @@ export function GameEndView({ snapshot }: { snapshot: RoomSnapshot }) { )}
- {/* Détails (musiques + récap) côte à côte sur desktop. */} - {((gameTracks && gameTracks.length > 0) || - (gameRecap && gameRecap.length > 0)) && ( -
- {gameTracks && gameTracks.length > 0 && ( - - )} - {gameRecap && gameRecap.length > 0 && ( - + {/* Détails : musiques + récap côte à côte sur desktop s'il y a les deux, + sinon une seule colonne centrée (sinon le récap se calait à gauche). */} + {(hasTracks || hasRecap) && ( +
+ {hasTracks && } + {hasRecap && ( + )}
)} diff --git a/apps/web/src/components/lobby-view.tsx b/apps/web/src/components/lobby-view.tsx index 9b42c82..c04740f 100644 --- a/apps/web/src/components/lobby-view.tsx +++ b/apps/web/src/components/lobby-view.tsx @@ -31,9 +31,16 @@ const MIX_LABELS: Record = { blindtest: "Blindtest", } import { Button } from "@workspace/ui/components/button" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@workspace/ui/components/tooltip" import { useRoomStore } from "@/store/room" import { Avatar } from "@/components/avatar" +const BLINDTEST_LOCK_HINT = "3 joueurs dont 2 réels (un bot ne peut pas être DJ)" + const MAX_TRACKS = 10 const GAME_TYPES: { value: GameType @@ -309,13 +316,15 @@ export function LobbyView({ snapshot }: { snapshot: RoomSnapshot }) { {GAME_TYPES.map(({ value, label, Icon, needsThree }) => { const locked = needsThree && !blindtestAvailable const active = effectiveType === value - return ( + const tile = ( ) + return locked ? ( + + {tile} + {BLINDTEST_LOCK_HINT} + + ) : ( + tile + ) })}
{!blindtestAvailable && ( @@ -343,13 +360,15 @@ export function LobbyView({ snapshot }: { snapshot: RoomSnapshot }) { {(["quiz", "image", "blindtest"] as const).map((m) => { const locked = m === "blindtest" && !blindtestAvailable const on = mixedModes.includes(m) && !locked - return ( + const tile = ( ) + return locked ? ( + + {tile} + {BLINDTEST_LOCK_HINT} + + ) : ( + tile + ) })} diff --git a/apps/web/src/pages/admin.tsx b/apps/web/src/pages/admin.tsx index 6e19c64..8550948 100644 --- a/apps/web/src/pages/admin.tsx +++ b/apps/web/src/pages/admin.tsx @@ -4,6 +4,11 @@ import { Link } from "wouter" import { Eye, EyeOff, Trash2, Upload } from "lucide-react" import type { QuizFormat } from "@nerdware/shared" import { Button } from "@workspace/ui/components/button" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@workspace/ui/components/tooltip" import { adminApi, assetUrl, @@ -187,14 +192,14 @@ function QuestionRow({

)} - + + + + + {q.active ? "Désactiver" : "Activer"} +