feat(pong): add way to view game list

This commit is contained in:
Maieul BOYER 2026-01-06 16:29:04 +01:00 committed by Nigel
parent 327ba987ed
commit 0ef66cdc10
3 changed files with 106 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import './signin/signin.ts'
import './ttt/ttt.ts'
import './profile/profile.ts'
import './logout/logout.ts'
import './pongHistory/pongHistory.ts'
// ---- Initial load ----
setTitle("");

View file

@ -0,0 +1,18 @@
<div class="fixed inset-0 flex items-center justify-center bg-[#43536b]">
<div
class="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-gray-200 w-212.5 p-6 rounded-xl shadow-2xl text-center z-50">
<h2 class="text-2xl font-bold text-center mb-4 text-gray-700">
Pong Match History For
<span id="name" class="text-amber-500"></span>
</h2>
<div id="matchList" class="max-w-3xl mx-auto space-y-2 max-h-[50dvh] overflow-scroll"></div>
<div style="display: none">
<div class="grid grid-cols-[1fr_auto_1fr] items-center bg-zinc-800 rounded-lg px-4 py-3"></div>
<div class="text-right"></div>
<div class="text-left"></div>
<div class="text-green-400"></div>
<div class="text-red-400"></div>
<div class="text-semibold"></div>
</div>
</div>
</div>

View file

@ -0,0 +1,87 @@
import { addRoute, type RouteHandlerParams, type RouteHandlerReturn } from "@app/routing";
import page from './pongHistory.html?raw';
import { isNullish } from "@app/utils";
import client from "@app/api";
import { updateUser } from "@app/auth";
function getHHMM(d: Date): string {
let h = d.getHours();
let m = d.getMinutes();
return `${h < 9 ? '0' : ''}${h}:${m < 9 ? '0' : ''}${m}`
}
async function pongHistory(_url: string, args: RouteHandlerParams): Promise<RouteHandlerReturn> {
if (isNullish(args.userid))
args.userid = 'me';
let user = await updateUser();
if (isNullish(user)) {
return { html: '<span> You aren\'t logged in </span>' };
}
let userInfoRes = await client.getUser({user: args.userid});
if (userInfoRes.kind !== 'success')
{
return { html: '<span> You tried to open a game history with no data :(</span>' };
}
let userInfo = userInfoRes.payload;
let res = await client.pongHistory({ user: args.userid });
if (res.kind === 'failure' || res.kind === 'notLoggedIn') {
// todo: make a real page on no data
return { html: '<span> You tried to open a game history with no data :(</span>' };
}
let games = res.payload.data;
games.reverse();
let gameElement = games.map(g => {
let rdate = Date.parse(g.date);
if (Number.isNaN(rdate)) return undefined;
let date = new Date(rdate);
const e = document.createElement('div');
let color = 'bg-amber-200';
if (!g.local) {
let youwin = false;
if (g.left.id === user.id && g.outcome === 'winL')
youwin = true;
else if (g.right.id === user.id && g.outcome === 'winR')
youwin = true;
if (youwin)
color = 'bg-green-300';
else
color = 'bg-red-300';
}
e.className =
'grid grid-cols-[1fr_auto_1fr] items-center rounded-lg px-4 py-3 ' + color;
e.innerHTML = `
<div class="text-right">
<div class="font-semibold ${g.outcome === 'winL' ? 'text-green-600' : 'text-red-600'}">${g.left.name}</div>
<div class="text-lg ${g.outcome === 'winL' ? 'text-green-600' : 'text-red-600'}">${g.left.score}</div>
</div>
<div class="text-center text-sm text-gray-800 px-4 whitespace-nowrap">${date.toDateString()}<br />${getHHMM(date)}</div>
<div class="text-left">
<div class="font-semibold ${g.outcome === 'winR' ? 'text-green-600' : 'text-red-600'}">${g.right.name}</div>
<div class="text-lg ${g.outcome === 'winR' ? 'text-green-600' : 'text-red-600'}">${g.right.score}</div>
</div>`;
return e;
}).filter(v => !isNullish(v));
return {
html: page, postInsert: async (app) => {
if (!app) return;
const matchBox = app.querySelector<HTMLDivElement>("#matchList");
if (!matchBox) return;
gameElement.forEach(c => matchBox.appendChild(c));
const userBox = app.querySelector<HTMLDivElement>("#name");
if (!userBox) return;
userBox.innerText = userInfo.name;
}
};
}
addRoute('/pong/games', pongHistory);
addRoute('/pong/games/:userid', pongHistory);