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"}
+