feat(pong): add way to view game list
This commit is contained in:
parent
327ba987ed
commit
0ef66cdc10
3 changed files with 106 additions and 0 deletions
|
|
@ -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("");
|
||||
|
|
|
|||
18
frontend/src/pages/pongHistory/pongHistory.html
Normal file
18
frontend/src/pages/pongHistory/pongHistory.html
Normal 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>
|
||||
87
frontend/src/pages/pongHistory/pongHistory.ts
Normal file
87
frontend/src/pages/pongHistory/pongHistory.ts
Normal 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);
|
||||
Loading…
Add table
Add a link
Reference in a new issue