From f87a991441a00a0ff6545043e056a0f407f2acdd Mon Sep 17 00:00:00 2001 From: Maix0 Date: Wed, 7 Jan 2026 00:16:39 +0100 Subject: [PATCH] feat(ttt): added draw status in ttt match history --- .../TttHistory200ResponsePayloadDataInner.ts | 3 +- frontend/src/pages/tttHistory/tttHistory.ts | 36 +++++++++++++------ src/@shared/src/database/mixin/tictactoe.ts | 4 +-- src/openapi.json | 3 +- src/tic-tac-toe/openapi.json | 3 +- src/tic-tac-toe/src/routes/tttHistory.ts | 2 +- src/tic-tac-toe/src/socket.ts | 2 +- 7 files changed, 36 insertions(+), 17 deletions(-) diff --git a/frontend/src/api/generated/models/TttHistory200ResponsePayloadDataInner.ts b/frontend/src/api/generated/models/TttHistory200ResponsePayloadDataInner.ts index 80b2ee8..75bf629 100644 --- a/frontend/src/api/generated/models/TttHistory200ResponsePayloadDataInner.ts +++ b/frontend/src/api/generated/models/TttHistory200ResponsePayloadDataInner.ts @@ -66,7 +66,8 @@ export interface TttHistory200ResponsePayloadDataInner { export const TttHistory200ResponsePayloadDataInnerOutcomeEnum = { WinX: 'winX', WinO: 'winO', - Other: 'other' + Other: 'other', + Draw: 'draw' } as const; export type TttHistory200ResponsePayloadDataInnerOutcomeEnum = typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum[keyof typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum]; diff --git a/frontend/src/pages/tttHistory/tttHistory.ts b/frontend/src/pages/tttHistory/tttHistory.ts index da03bfa..d7fcf51 100644 --- a/frontend/src/pages/tttHistory/tttHistory.ts +++ b/frontend/src/pages/tttHistory/tttHistory.ts @@ -11,6 +11,18 @@ function getHHMM(d: Date): string { return `${h < 9 ? '0' : ''}${h}:${m < 9 ? '0' : ''}${m}` } +function statusText(side:'X'|'O',status: string): string { + if (status === `win${side}`) return 'WIN'; + if (status === `win${side === 'X'? 'O' : 'X'}`) return 'LOSE'; + return 'DRAW' +} + +function statusColor(side:'X'|'O',status: string): string { + if (status === `win${side}`) return 'text-green-600'; + if (status === `win${side === 'X'? 'O' : 'X'}`) return 'text-red-600'; + return 'text-yellow-600' +} + async function tttHistory(_url: string, args: RouteHandlerParams): Promise { if (isNullish(args.userid)) args.userid = 'me'; @@ -42,32 +54,36 @@ async function tttHistory(_url: string, args: RouteHandlerParams): Promise -
${g.playerX.name}
-
${g.outcome === 'winX' ? 'WON' : 'LOST'}
+
${g.playerX.name}
+
${statusText('X', g.outcome)}
${date.toDateString()}
${getHHMM(date)}
-
${g.playerO.name}
-
${g.outcome === 'winO' ? 'WON' : 'LOST'}
+
${g.playerO.name}
+
${statusText('O', g.outcome)}
`; return e; }).filter(v => !isNullish(v)); diff --git a/src/@shared/src/database/mixin/tictactoe.ts b/src/@shared/src/database/mixin/tictactoe.ts index 74b3019..e431b5d 100644 --- a/src/@shared/src/database/mixin/tictactoe.ts +++ b/src/@shared/src/database/mixin/tictactoe.ts @@ -3,7 +3,7 @@ import type { Database } from './_base'; import { UserId } from './user'; import { isNullish } from '@shared/utils'; -export type TicTacToeOutcome = 'winX' | 'winO' | 'other'; +export type TicTacToeOutcome = 'winX' | 'winO' | 'draw' | 'other'; // describe every function in the object export interface ITicTacToeDb extends Database { setTTTGameOutcome(this: ITicTacToeDb, id: TTTGameId, player1: UserId, player2: UserId, outcome: TicTacToeOutcome): void, @@ -82,7 +82,7 @@ function TicTacToeGameFromRow(r: Partial | undefined): TicTa if (isNullish(r.outcome)) return undefined; if (isNullish(r.time)) return undefined; - if (r.outcome !== 'winX' && r.outcome !== 'winO' && r.outcome !== 'other') return undefined; + if (r.outcome !== 'winX' && r.outcome !== 'winO' && r.outcome !== 'other' && r.outcome !== 'draw') return undefined; const date = Date.parse(r.time); if (Number.isNaN(date)) return undefined; diff --git a/src/openapi.json b/src/openapi.json index f2e86b9..503944a 100644 --- a/src/openapi.json +++ b/src/openapi.json @@ -2013,7 +2013,8 @@ "enum": [ "winX", "winO", - "other" + "other", + "draw" ] } } diff --git a/src/tic-tac-toe/openapi.json b/src/tic-tac-toe/openapi.json index 7adfcef..674c7f2 100644 --- a/src/tic-tac-toe/openapi.json +++ b/src/tic-tac-toe/openapi.json @@ -104,7 +104,8 @@ "enum": [ "winX", "winO", - "other" + "other", + "draw" ] } } diff --git a/src/tic-tac-toe/src/routes/tttHistory.ts b/src/tic-tac-toe/src/routes/tttHistory.ts index 4830b98..fcbcf73 100644 --- a/src/tic-tac-toe/src/routes/tttHistory.ts +++ b/src/tic-tac-toe/src/routes/tttHistory.ts @@ -17,7 +17,7 @@ const TTTHistoryResponse = { playerX: Type.Object({ id: Type.String(), name: Type.String() }), playerO: Type.Object({ id: Type.String(), name: Type.String() }), date: Type.String(), - outcome: Type.Enum(['winX', 'winO', 'other']), + outcome: Type.Enum(['winX', 'winO', 'other', 'draw']), }), ), }), diff --git a/src/tic-tac-toe/src/socket.ts b/src/tic-tac-toe/src/socket.ts index b3a91c5..d549691 100644 --- a/src/tic-tac-toe/src/socket.ts +++ b/src/tic-tac-toe/src/socket.ts @@ -14,7 +14,7 @@ export type GameUpdate = { boardState: CellState[]; currentPlayer: 'X' | 'O'; - gameState: 'winX' | 'winO' | 'concededX' | 'concededO' | 'draw' | 'ongoing'; + gameState: 'winX' | 'winO' | 'draw' | 'ongoing'; } export type GameMove = {