From 00354d392a0bcddaac71fee7b6aae721e5747f59 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 20 Feb 2026 23:44:07 +0900 Subject: feat(frontend): add problem preview page for pre-game viewing Allow participants to view problem descriptions and sample code before a game starts. Dashboard shows a preview link only for games that haven't started yet. Co-Authored-By: Claude Opus 4.6 --- frontend/app/pages/DashboardPage.tsx | 5 +++ frontend/app/pages/GolfProblemPreviewPage.tsx | 60 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 frontend/app/pages/GolfProblemPreviewPage.tsx (limited to 'frontend/app/pages') diff --git a/frontend/app/pages/DashboardPage.tsx b/frontend/app/pages/DashboardPage.tsx index 3191f1b..00db3f0 100644 --- a/frontend/app/pages/DashboardPage.tsx +++ b/frontend/app/pages/DashboardPage.tsx @@ -68,6 +68,11 @@ export default function DashboardPage() {
+ {game.started_at == null && ( + + 問題を見る + + )} 対戦 diff --git a/frontend/app/pages/GolfProblemPreviewPage.tsx b/frontend/app/pages/GolfProblemPreviewPage.tsx new file mode 100644 index 0000000..01ac5b2 --- /dev/null +++ b/frontend/app/pages/GolfProblemPreviewPage.tsx @@ -0,0 +1,60 @@ +import { useEffect, useState } from "react"; +import { useLocation } from "wouter"; +import { createApiClient } from "../api/client"; +import type { components } from "../api/schema"; +import ProblemColumnContent from "../components/Gaming/ProblemColumnContent"; +import NavigateLink from "../components/NavigateLink"; +import { APP_NAME } from "../config"; +import { usePageTitle } from "../hooks/usePageTitle"; + +type Game = components["schemas"]["Game"]; + +export default function GolfProblemPreviewPage({ gameId }: { gameId: string }) { + const [, navigate] = useLocation(); + const [game, setGame] = useState(null); + const [loading, setLoading] = useState(true); + + const gameIdNum = Number(gameId); + + usePageTitle( + game + ? `${game.display_name} - 問題プレビュー | ${APP_NAME}` + : `問題プレビュー | ${APP_NAME}`, + ); + + useEffect(() => { + const apiClient = createApiClient(); + apiClient + .getGame(gameIdNum) + .then(({ game }) => setGame(game)) + .catch(() => navigate("/dashboard")) + .finally(() => setLoading(false)); + }, [gameIdNum, navigate]); + + if (loading || !game) { + return ( +
+

Loading...

+
+ ); + } + + return ( +
+

{game.display_name}

+
+ +
+ {game.started_at != null && ( + + 対戦ページへ + + )} + ダッシュボードへ戻る +
+ ); +} -- cgit v1.3.1