aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-03-06 02:16:59 +0900
committernsfisis <nsfisis@gmail.com>2026-03-06 02:16:59 +0900
commit27f509ccf4fbfeaa1bc2580ae2251461dc44ebfa (patch)
tree2f8adbbad7af59af35ec428e029863eb0941c397 /frontend
parent1fae954b09a49d93a1361788e859065bea43f0c0 (diff)
downloadphperkaigi-2026-albatross-27f509ccf4fbfeaa1bc2580ae2251461dc44ebfa.tar.gz
phperkaigi-2026-albatross-27f509ccf4fbfeaa1bc2580ae2251461dc44ebfa.tar.zst
phperkaigi-2026-albatross-27f509ccf4fbfeaa1bc2580ae2251461dc44ebfa.zip
feat(frontend): remove standalone submissions page
Submission history is now shown inline on the play screen, making the dedicated /golf/:gameId/submissions page redundant.
Diffstat (limited to 'frontend')
-rw-r--r--frontend/app/App.tsx8
-rw-r--r--frontend/app/pages/DashboardPage.tsx5
-rw-r--r--frontend/app/pages/SubmissionsPage.test.tsx17
-rw-r--r--frontend/app/pages/SubmissionsPage.tsx126
4 files changed, 0 insertions, 156 deletions
diff --git a/frontend/app/App.tsx b/frontend/app/App.tsx
index 31adc28..762dab6 100644
--- a/frontend/app/App.tsx
+++ b/frontend/app/App.tsx
@@ -8,7 +8,6 @@ import GolfProblemPreviewPage from "./pages/GolfProblemPreviewPage";
import GolfWatchPage from "./pages/GolfWatchPage";
import IndexPage from "./pages/IndexPage";
import LoginPage from "./pages/LoginPage";
-import SubmissionsPage from "./pages/SubmissionsPage";
import TournamentPage from "./pages/TournamentPage";
export default function App() {
@@ -42,13 +41,6 @@ export default function App() {
</ProtectedRoute>
)}
</Route>
- <Route path="/golf/:gameId/submissions">
- {(params) => (
- <ProtectedRoute>
- <SubmissionsPage gameId={params.gameId} />
- </ProtectedRoute>
- )}
- </Route>
<Route path="/golf/:gameId/watch">
{(params) => <GolfWatchPage gameId={params.gameId} />}
</Route>
diff --git a/frontend/app/pages/DashboardPage.tsx b/frontend/app/pages/DashboardPage.tsx
index 8f40f22..54bfdd6 100644
--- a/frontend/app/pages/DashboardPage.tsx
+++ b/frontend/app/pages/DashboardPage.tsx
@@ -87,11 +87,6 @@ export default function DashboardPage() {
<NavigateLink to={`/golf/${game.game_id}/watch`}>
観戦
</NavigateLink>
- {isLoggedIn && (
- <NavigateLink to={`/golf/${game.game_id}/submissions`}>
- 提出履歴
- </NavigateLink>
- )}
</div>
</li>
))}
diff --git a/frontend/app/pages/SubmissionsPage.test.tsx b/frontend/app/pages/SubmissionsPage.test.tsx
deleted file mode 100644
index f01f4c9..0000000
--- a/frontend/app/pages/SubmissionsPage.test.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @vitest-environment jsdom
- */
-import { cleanup, render, screen } from "@testing-library/react";
-import { afterEach, describe, expect, test } from "vitest";
-import SubmissionsPage from "./SubmissionsPage";
-
-afterEach(() => {
- cleanup();
-});
-
-describe("SubmissionsPage", () => {
- test("shows loading state initially", () => {
- render(<SubmissionsPage gameId="1" />);
- expect(screen.getByText("Loading...")).toBeDefined();
- });
-});
diff --git a/frontend/app/pages/SubmissionsPage.tsx b/frontend/app/pages/SubmissionsPage.tsx
deleted file mode 100644
index 1f55aa8..0000000
--- a/frontend/app/pages/SubmissionsPage.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import { useEffect, useState } from "react";
-import { createApiClient } from "../api/client";
-import type { components } from "../api/schema";
-import BorderedContainerWithCaption from "../components/BorderedContainerWithCaption";
-import NavigateLink from "../components/NavigateLink";
-import SubmitStatusLabel from "../components/SubmitStatusLabel";
-import { APP_NAME } from "../config";
-import { usePageTitle } from "../hooks/usePageTitle";
-
-type Submission = components["schemas"]["Submission"];
-
-export default function SubmissionsPage({ gameId }: { gameId: string }) {
- usePageTitle(`Submissions | ${APP_NAME}`);
-
- const [submissions, setSubmissions] = useState<Submission[]>([]);
- const [loading, setLoading] = useState(true);
- const [expandedId, setExpandedId] = useState<number | null>(null);
-
- const numericGameId = Number(gameId);
-
- useEffect(() => {
- const apiClient = createApiClient();
- apiClient
- .getGamePlaySubmissions(numericGameId)
- .then(({ submissions }) => setSubmissions(submissions))
- .catch(() => {})
- .finally(() => setLoading(false));
- }, [numericGameId]);
-
- if (loading) {
- return (
- <div className="min-h-screen bg-gray-100 flex items-center justify-center">
- <p className="text-gray-500">Loading...</p>
- </div>
- );
- }
-
- return (
- <div className="p-6 bg-gray-100 min-h-screen flex flex-col items-center gap-4">
- <BorderedContainerWithCaption caption="提出履歴">
- <div className="px-4">
- {submissions.length === 0 ? (
- <p>提出履歴はありません</p>
- ) : (
- <ul className="divide-y divide-gray-300">
- {submissions.map((s) => (
- <li key={s.submission_id} className="py-3">
- <div className="flex justify-between items-center gap-4">
- <div className="flex items-center gap-3">
- <StatusBadge status={s.status} />
- <span className="font-mono text-lg font-bold">
- {s.code_size}
- <span className="text-sm font-normal text-gray-500 ml-1">
- bytes
- </span>
- </span>
- </div>
- <div className="flex items-center gap-3">
- <span className="text-sm text-gray-500">
- {formatDate(s.created_at)}
- </span>
- <button
- type="button"
- onClick={() =>
- setExpandedId(
- expandedId === s.submission_id
- ? null
- : s.submission_id,
- )
- }
- className="text-sm text-brand-600 hover:text-brand-800 underline"
- >
- {expandedId === s.submission_id
- ? "コードを隠す"
- : "コードを見る"}
- </button>
- </div>
- </div>
- {expandedId === s.submission_id && (
- <pre className="mt-2 p-3 bg-gray-800 text-gray-100 rounded text-sm overflow-x-auto">
- {s.code}
- </pre>
- )}
- </li>
- ))}
- </ul>
- )}
- </div>
- </BorderedContainerWithCaption>
- <NavigateLink to={`/golf/${gameId}/play`}>対戦に戻る</NavigateLink>
- <NavigateLink to="/dashboard">ダッシュボードに戻る</NavigateLink>
- </div>
- );
-}
-
-function StatusBadge({
- status,
-}: {
- status: components["schemas"]["ExecutionStatus"];
-}) {
- const colorClass =
- status === "success"
- ? "bg-green-100 text-green-800"
- : status === "running"
- ? "bg-yellow-100 text-yellow-800"
- : status === "none"
- ? "bg-gray-100 text-gray-800"
- : "bg-red-100 text-red-800";
-
- return (
- <span className={`px-2 py-1 rounded text-sm font-medium ${colorClass}`}>
- <SubmitStatusLabel status={status} />
- </span>
- );
-}
-
-function formatDate(unixTimestamp: number): string {
- const date = new Date(unixTimestamp * 1000);
- return date.toLocaleString("ja-JP", {
- month: "2-digit",
- day: "2-digit",
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit",
- });
-}