From 4af93cae1ca54ad7c9bc7eb4b56c010f55c4c72d Mon Sep 17 00:00:00 2001
From: Claude <noreply@anthropic.com>
Date: Fri, 20 Feb 2026 17:53:55 +0000
Subject: feat: allow viewing/spectating games without login

Make watch, ranking, game list, and tournament endpoints accessible
without authentication. Unauthenticated users can browse games and
spectate from the index page, while play/submit/preview still require
login.

https://claude.ai/code/session_019j9tNcnLsLz15e1qtbmeqe
---
 frontend/app/pages/GolfWatchPage.tsx | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

(limited to 'frontend/app/pages/GolfWatchPage.tsx')

diff --git a/frontend/app/pages/GolfWatchPage.tsx b/frontend/app/pages/GolfWatchPage.tsx
index 4f76136..168bd6f 100644
--- a/frontend/app/pages/GolfWatchPage.tsx
+++ b/frontend/app/pages/GolfWatchPage.tsx
@@ -1,6 +1,5 @@
 import { createStore, Provider as JotaiProvider } from "jotai";
 import { useEffect, useMemo, useState } from "react";
-import { useLocation } from "wouter";
 import { ApiClientContext, createApiClient } from "../api/client";
 import type { components } from "../api/schema";
 import GolfWatchApp from "../components/GolfWatchApp";
@@ -12,14 +11,13 @@ type LatestGameState = components["schemas"]["LatestGameState"];
 type RankingEntry = components["schemas"]["RankingEntry"];
 
 export default function GolfWatchPage({ gameId }: { gameId: string }) {
-	const [, navigate] = useLocation();
-
 	const [game, setGame] = useState<Game | null>(null);
 	const [ranking, setRanking] = useState<RankingEntry[]>([]);
 	const [gameStates, setGameStates] = useState<{
 		[key: string]: LatestGameState;
 	}>({});
 	const [loading, setLoading] = useState(true);
+	const [error, setError] = useState(false);
 
 	const gameIdNum = Number(gameId);
 
@@ -41,16 +39,16 @@ export default function GolfWatchPage({ gameId }: { gameId: string }) {
 				setRanking(ranking);
 				setGameStates(states);
 			})
-			.catch(() => navigate("/dashboard"))
+			.catch(() => setError(true))
 			.finally(() => setLoading(false));
-	}, [gameIdNum, navigate]);
+	}, [gameIdNum]);
 
 	const store = useMemo(() => {
 		if (!game) return null;
 		return createStore();
 	}, [game]);
 
-	if (loading || !game || !store) {
+	if (loading) {
 		return (
 			<div className="min-h-screen bg-gray-100 flex items-center justify-center">
 				<p className="text-gray-500">Loading...</p>
@@ -58,6 +56,14 @@ export default function GolfWatchPage({ gameId }: { gameId: string }) {
 		);
 	}
 
+	if (error || !game || !store) {
+		return (
+			<div className="min-h-screen bg-gray-100 flex items-center justify-center">
+				<p className="text-red-500">試合が見つかりませんでした</p>
+			</div>
+		);
+	}
+
 	return (
 		<JotaiProvider store={store}>
 			<ApiClientContext.Provider value={createApiClient()}>
-- 
cgit v1.3.1

