diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-03-20 19:41:38 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-03-20 19:41:39 +0900 |
| commit | 1a08d06be929900fb8d8b61a1ac0611005c277e8 (patch) | |
| tree | b064bfb79cc0021a42c423a04359504369e1faa5 /frontend/app/components/Gaming/RankingTable.tsx | |
| parent | 96081efcce7b7e1f4540cb74cb511a341f2cb4d3 (diff) | |
| download | phperkaigi-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.tsx | 66 |
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> + ); +} |
