feat(tournament): better frontend and database handling

This commit is contained in:
Maieul BOYER 2026-01-12 16:36:51 +01:00 committed by Maix0
parent ca618d64ca
commit 43e3b9af26
41 changed files with 2484 additions and 278 deletions

View file

@ -54,24 +54,7 @@
<kbd class="disp-key">L</kbd>
</span>
</div>
<div id="tourscore-box" class="white-color rounded-elem focus-elem text-2xl hidden">
up:
<kbd class="pong-protips-key">W</kbd>
down:
<kbd class="pong-protips-key">S</kbd>
<br />
You are <span class="text-red-500">red</span>.
<br />
Your goal is to bounce the ball back to the adversary.
<br />
<span class="text-gray-400">local games keys for the left paddle:
<br />
up:
<kbd class="disp-key">O</kbd>
down:
<kbd class="disp-key">L</kbd>
</span>
</div>
<div id="tourscore-box" class="white-color rounded-elem focus-elem text-2xl hidden">We havent seen any tournament yet !</div>
<button id="readyup-btn" class="justify-center white-color focus-elem rounded-elem">ready!</button>
<div class="pong-field">
<div id="batleft" class="pong-bat pong-batleft top-0"></div>

View file

@ -6,6 +6,7 @@ import {
type RouteHandlerReturn,
} from "@app/routing";
import authHtml from "./pong.html?raw";
import tourScoresHtml from "./tourTable.html?raw";
import io from "socket.io-client";
import { JoinRes, type CSocket, type GameMove, type GameUpdate, type TourInfo } from "./socket";
import { showError, showInfo, showSuccess } from "@app/toast";
@ -301,39 +302,28 @@ function pongClient(
const renderTournamentScores = (info: TourInfo) => {
let players = info.players.sort((l, r) => r.score - l.score);
tour_scores.innerHTML = `
<div class="overflow-x-auto">
<table class="min-w-full border border-gray-200 rounded-lg shadow-sm">
<thead class="bg-gray-100">
<tr>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 border-b">
Name
</th>
<th class="px-4 py-2 text-right text-sm font-semibold text-gray-700 border-b">
Score
</th>
</tr>
</thead>
<tbody>
${players
.map(
(player) => `
<tr class="hover:bg-gray-50" key="${player.id}">
<td class="px-4 py-2 text-sm text-gray-800 border-b">
${player.name}
</td>
<td class="px-4 py-2 text-sm text-gray-800 text-right border-b">
${player.score}
</td>
</tr>
`,
)
.join("")}
</tbody>
</table>
</div>`;
const medals = ["🥇", "🥈", "🥉"];
tour_scores.innerHTML = tourScoresHtml;
let table = tour_scores.querySelector("#tour-score-body");
if (table)
table.innerHTML = players.map((player, idx) =>
`<tr class="${player.id === user.id ? "bg-amber-400 hover:bg-amber-500" : "hover:bg-gray-50"}" key="${player.id}">
<td class="px-4 py-2 text-sm text-gray-800 text-center border-b font-semibold min-w-100px">${idx < medals.length ? `<span class="font-lg">${medals[idx]}</span>` : ''}${player.name}</td>
<td class="px-4 py-2 text-sm text-gray-800 text-center border-b font-bold min-w-100px">${player.score}</td>
</tr>`)
.join("");
};
// TODO: REMOVE THIS
// const makePlayer = (n: number) => ({ name: `user${n}`, id: `${n}`, score: n })
//
// renderTournamentScores({
// state: "playing",
// ownerId: "ownerID",
// remainingMatches: null,
// players: [...Array.from(Array(10).keys()).map(makePlayer), { id: user.id, name: user.name, score: 99 }],
// });
const render = (state: GameUpdate) => {
batLeft.style.top = `${state.left.paddle.y}px`;
batLeft.style.left = `${state.left.paddle.x}px`;

View file

@ -0,0 +1,22 @@
<div class="px-4">
<span class="block mb-2 font-semibold">Tournament Scores</span>
<div class="max-h-[320px] overflow-y-auto overflow-x-auto border rounded-lg">
<table class="min-w-full border-collapse table-fixed">
<thead class="sticky top-0 z-10 bg-gray-100">
<tr>
<th class="px-4 py-2 text-right text-sm font-semibold text-gray-700 border-b">
Name
</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 border-b">
Score
</th>
</tr>
</thead>
<tbody id="tour-score-body">
<!-- rows -->
</tbody>
</table>
</div>
</div>