aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/api
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-20 23:32:22 +0900
committernsfisis <nsfisis@gmail.com>2026-02-20 23:32:22 +0900
commit8e73d12a703e90ad908962143951178c13d0d6fe (patch)
tree8bed43aa4b115f8bc50ed258aa192a94b6d2903e /frontend/app/api
parentaa07ba2e0a40b0097a4f9aee3c06dcbd9a749105 (diff)
downloadphperkaigi-2026-albatross-8e73d12a703e90ad908962143951178c13d0d6fe.tar.gz
phperkaigi-2026-albatross-8e73d12a703e90ad908962143951178c13d0d6fe.tar.zst
phperkaigi-2026-albatross-8e73d12a703e90ad908962143951178c13d0d6fe.zip
feat: add user submission history page
Allow users to view their own past submissions (code, size, status, timestamp) for each game. Adds API endpoint, backend handler, SQL query, and frontend page with expandable code display. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'frontend/app/api')
-rw-r--r--frontend/app/api/client.ts13
-rw-r--r--frontend/app/api/schema.d.ts75
2 files changed, 88 insertions, 0 deletions
diff --git a/frontend/app/api/client.ts b/frontend/app/api/client.ts
index c9647ba..db5f8c8 100644
--- a/frontend/app/api/client.ts
+++ b/frontend/app/api/client.ts
@@ -85,6 +85,19 @@ class AuthenticatedApiClient {
return data;
}
+ async getGamePlaySubmissions(gameId: number) {
+ const { data, error } = await client.GET(
+ "/games/{game_id}/play/submissions",
+ {
+ params: {
+ path: { game_id: gameId },
+ },
+ },
+ );
+ if (error) throw new Error(error.message);
+ return data;
+ }
+
async getGameWatchRanking(gameId: number) {
const { data, error } = await client.GET("/games/{game_id}/watch/ranking", {
params: {
diff --git a/frontend/app/api/schema.d.ts b/frontend/app/api/schema.d.ts
index b891bfa..e720f52 100644
--- a/frontend/app/api/schema.d.ts
+++ b/frontend/app/api/schema.d.ts
@@ -68,6 +68,22 @@ export interface paths {
patch?: never;
trace?: never;
};
+ "/games/{game_id}/play/submissions": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ get: operations["getGamePlaySubmissions"];
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
"/games/{game_id}/play/submit": {
parameters: {
query?: never;
@@ -222,6 +238,14 @@ export interface components {
submitted_at: number;
code: string | null;
};
+ Submission: {
+ submission_id: number;
+ game_id: number;
+ code: string;
+ code_size: number;
+ status: components["schemas"]["ExecutionStatus"];
+ created_at: number;
+ };
Tournament: {
tournament_id: number;
display_name: string;
@@ -458,6 +482,57 @@ export interface operations {
};
};
};
+ getGamePlaySubmissions: {
+ parameters: {
+ query?: never;
+ header?: never;
+ path: {
+ game_id: number;
+ };
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description The request has succeeded. */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": {
+ submissions: components["schemas"]["Submission"][];
+ };
+ };
+ };
+ /** @description Access is unauthorized. */
+ 401: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
+ /** @description Access is forbidden. */
+ 403: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
+ /** @description The server cannot find the requested resource. */
+ 404: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
+ };
+ };
postGamePlaySubmit: {
parameters: {
query?: never;