From 9477788709127ffd5611caed0fa7ee191326ce00 Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Sat, 10 Aug 2024 13:31:52 +0900
Subject: feat(frontend): partially implement watch page

---
 .../GolfWatchApps/GolfWatchAppGaming.tsx           | 137 +++++++++++++++++----
 1 file changed, 113 insertions(+), 24 deletions(-)

(limited to 'frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx')

diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx
index 22277f8..470a00c 100644
--- a/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx
+++ b/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx
@@ -1,41 +1,130 @@
 type Props = {
 	problem: string;
-	codeA: string;
-	scoreA: number | null;
-	codeB: string;
-	scoreB: number | null;
+	playerInfoA: PlayerInfo;
+	playerInfoB: PlayerInfo;
+	leftTimeSeconds: number;
+};
+
+export type PlayerInfo = {
+	displayName: string | null;
+	iconPath: string | null;
+	score: number | null;
+	code: string | null;
+	submissionResult?: SubmissionResult;
+};
+
+type SubmissionResult = {
+	status: string;
+	nextScore: number;
+	executionResults: ExecutionResult[];
+};
+
+type ExecutionResult = {
+	status: string;
+	label: string;
+	output: string;
 };
 
 export default function GolfWatchAppGaming({
 	problem,
-	codeA,
-	scoreA,
-	codeB,
-	scoreB,
+	playerInfoA,
+	playerInfoB,
+	leftTimeSeconds,
 }: Props) {
+	const leftTime = (() => {
+		const m = Math.floor(leftTimeSeconds / 60);
+		const s = leftTimeSeconds % 60;
+		return `${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
+	})();
+	const scoreRatio = (() => {
+		const scoreA = playerInfoA.score ?? 0;
+		const scoreB = playerInfoB.score ?? 0;
+		const totalScore = scoreA + scoreB;
+		return totalScore === 0 ? 50 : (scoreA / totalScore) * 100;
+	})();
+
 	return (
-		<div style={{ display: "flex", flexDirection: "column" }}>
-			<div style={{ display: "flex", flex: 1, justifyContent: "center" }}>
-				<div>{problem}</div>
+		<div className="grid h-full w-full grid-rows-[auto_auto_1fr_auto]">
+			<div className="grid grid-cols-[1fr_auto_1fr]">
+				<div className="grid justify-start bg-red-500 p-2 text-white">
+					{playerInfoA.displayName}
+				</div>
+				<div className="grid justify-center p-2">{leftTime}</div>
+				<div className="grid justify-end bg-blue-500 p-2 text-white">
+					{playerInfoB.displayName}
+				</div>
 			</div>
-			<div style={{ display: "flex", flex: 3 }}>
-				<div style={{ display: "flex", flex: 3, flexDirection: "column" }}>
-					<div style={{ flex: 1, justifyContent: "center" }}>{scoreA}</div>
-					<div style={{ flex: 3 }}>
-						<pre>
-							<code>{codeA}</code>
-						</pre>
+			<div className="grid grid-cols-[auto_1fr_auto]">
+				<div className="grid justify-start bg-red-500 p-2 text-lg font-bold text-white">
+					{playerInfoA.score ?? "-"}
+				</div>
+				<div className="w-full bg-blue-500">
+					<div
+						className="h-full bg-red-500"
+						style={{ width: `${scoreRatio}%` }}
+					></div>
+				</div>
+				<div className="grid justify-end bg-blue-500 p-2 text-lg font-bold text-white">
+					{playerInfoB.score ?? "-"}
+				</div>
+			</div>
+			<div className="grid grid-cols-[2fr_1fr_2fr_1fr] p-2">
+				<div>
+					<pre>
+						<code>{playerInfoA.code}</code>
+					</pre>
+				</div>
+				<div>
+					<div>
+						{playerInfoA.submissionResult?.status}(
+						{playerInfoA.submissionResult?.nextScore})
+					</div>
+					<div>
+						<ol>
+							{playerInfoA.submissionResult?.executionResults.map(
+								(result, idx) => (
+									<li key={idx}>
+										<div>
+											<div>
+												{result.status} {result.label}
+											</div>
+											<div>{result.output}</div>
+										</div>
+									</li>
+								),
+							)}
+						</ol>
 					</div>
 				</div>
-				<div style={{ display: "flex", flex: 3, flexDirection: "column" }}>
-					<div style={{ flex: 1, justifyContent: "center" }}>{scoreB}</div>
-					<div style={{ flex: 3 }}>
-						<pre>
-							<code>{codeB}</code>
-						</pre>
+				<div>
+					<pre>
+						<code>{playerInfoB.code}</code>
+					</pre>
+				</div>
+				<div>
+					<div>
+						{playerInfoB.submissionResult?.status}(
+						{playerInfoB.submissionResult?.nextScore})
+					</div>
+					<div>
+						<ol>
+							{playerInfoB.submissionResult?.executionResults.map(
+								(result, idx) => (
+									<li key={idx}>
+										<div>
+											<div>
+												{result.status} {result.label}
+											</div>
+											<div>{result.output}</div>
+										</div>
+									</li>
+								),
+							)}
+						</ol>
 					</div>
 				</div>
 			</div>
+			<div className="grid justify-center p-2 bg-slate-300">{problem}</div>
 		</div>
 	);
 }
-- 
cgit v1.3.1

