aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/components/Gaming/RankingTable.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-03-20 19:41:38 +0900
committernsfisis <nsfisis@gmail.com>2025-03-20 19:41:39 +0900
commit1a08d06be929900fb8d8b61a1ac0611005c277e8 (patch)
treeb064bfb79cc0021a42c423a04359504369e1faa5 /frontend/app/components/Gaming/RankingTable.tsx
parent96081efcce7b7e1f4540cb74cb511a341f2cb4d3 (diff)
downloadphperkaigi-2025-albatross-1a08d06be929900fb8d8b61a1ac0611005c277e8.tar.gz
phperkaigi-2025-albatross-1a08d06be929900fb8d8b61a1ac0611005c277e8.tar.zst
phperkaigi-2025-albatross-1a08d06be929900fb8d8b61a1ac0611005c277e8.zip
feat: show submission date on ranking
Diffstat (limited to 'frontend/app/components/Gaming/RankingTable.tsx')
-rw-r--r--frontend/app/components/Gaming/RankingTable.tsx66
1 files changed, 66 insertions, 0 deletions
diff --git a/frontend/app/components/Gaming/RankingTable.tsx b/frontend/app/components/Gaming/RankingTable.tsx
new file mode 100644
index 0000000..e712ed9
--- /dev/null
+++ b/frontend/app/components/Gaming/RankingTable.tsx
@@ -0,0 +1,66 @@
+import React from "react";
+import type { components } from "../../api/schema";
+
+type RankingEntry = components["schemas"]["RankingEntry"];
+
+type Props = {
+ ranking: RankingEntry[];
+};
+
+function TableHeaderCell({ children }: { children: React.ReactNode }) {
+ return (
+ <th scope="col" className="px-6 py-3 text-left font-medium text-gray-800">
+ {children}
+ </th>
+ );
+}
+
+function TableBodyCell({ children }: { children: React.ReactNode }) {
+ return (
+ <td className="px-6 py-4 whitespace-nowrap text-gray-900">{children}</td>
+ );
+}
+
+function formatUnixTimestamp(timestamp: number) {
+ const date = new Date(timestamp * 1000);
+
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, "0");
+ const day = date.getDate().toString().padStart(2, "0");
+ const hours = date.getHours().toString().padStart(2, "0");
+ const minutes = date.getMinutes().toString().padStart(2, "0");
+
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
+}
+
+export default function RankingTable({ ranking }: Props) {
+ return (
+ <div className="overflow-hidden border-2 border-blue-600 rounded-xl">
+ <table className="min-w-full divide-y divide-gray-400 border-collapse">
+ <thead className="bg-gray-50">
+ <tr>
+ <TableHeaderCell>順位</TableHeaderCell>
+ <TableHeaderCell>プレイヤー</TableHeaderCell>
+ <TableHeaderCell>スコア</TableHeaderCell>
+ <TableHeaderCell>提出時刻</TableHeaderCell>
+ </tr>
+ </thead>
+ <tbody className="bg-white divide-y divide-gray-300">
+ {ranking.map((entry, index) => (
+ <tr key={entry.player.user_id}>
+ <TableBodyCell>{index + 1}</TableBodyCell>
+ <TableBodyCell>
+ {entry.player.display_name}
+ {entry.player.label && ` (${entry.player.label})`}
+ </TableBodyCell>
+ <TableBodyCell>{entry.score}</TableBodyCell>
+ <TableBodyCell>
+ {formatUnixTimestamp(entry.submitted_at)}
+ </TableBodyCell>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ );
+}