Add global match history and ending timestamps

This commit is contained in:
2026-09-20 21:44:36 -04:00
parent fc681c56c9
commit 3c8b5b2e40
8 changed files with 68 additions and 14 deletions
+10 -5
View File
@@ -2,21 +2,23 @@
import type { ServerMatch } from '$lib/match-history.js';
import { pollVisible } from '$ui/poll.js';
import { formatDuration } from '$ui/duration.js';
import { serverTitle } from '$ui/server-labels.js';
import Card from './primitives/Card.svelte';
import Button from './primitives/Button.svelte';
import EmptyState from './primitives/EmptyState.svelte';
import ListFooter from './primitives/ListFooter.svelte';
let { server }: { server: string } = $props();
let { server }: { server?: string } = $props();
let matches = $state<ServerMatch[]>([]);
let total = $state(0);
let limit = $state(25);
let loading = $state(true);
let error = $state('');
async function refresh(currentServer: string, currentLimit: number) {
async function refresh(currentServer: string | undefined, currentLimit: number) {
try {
const response = await fetch(`/api/servers/${encodeURIComponent(currentServer)}/matches?limit=${currentLimit}`);
const endpoint = currentServer === undefined ? '/api/matches' : `/api/servers/${encodeURIComponent(currentServer)}/matches`;
const response = await fetch(`${endpoint}?limit=${currentLimit}`);
if (!response.ok) throw new Error('Could not load match history.');
const body = await response.json();
if (server !== currentServer || limit !== currentLimit) return;
@@ -45,17 +47,19 @@
{#if loading}
<EmptyState title="Loading matches…" />
{:else if matches.length === 0 && !error}
<EmptyState title="No matches recorded yet" description="Matches appear here when this server reports gameplay." />
<EmptyState title="No matches recorded yet" description={server === undefined ? 'Matches appear here when servers report gameplay.' : 'Matches appear here when this server reports gameplay.'} />
{:else if matches.length}
<!-- Keyboard focus lets users scroll the wide table horizontally. -->
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<div class="table-scroll" tabindex="0" role="region" aria-label="Match history">
<table>
<thead><tr><th>Started</th><th>Map</th><th>Status</th><th>Players at start</th><th>Unique players</th><th>Players at end</th><th>Game time</th><th>Final round</th></tr></thead>
<thead><tr><th>Started</th><th>Ended</th>{#if server === undefined}<th>Server</th>{/if}<th>Map</th><th>Status</th><th>Players at start</th><th>Unique players</th><th>Players at end</th><th>Game time</th><th>Final round</th></tr></thead>
<tbody>
{#each matches as match (match.id)}
<tr>
<td><time datetime={match.startedAt}>{new Date(match.startedAt).toLocaleString()}</time></td>
<td>{#if match.endedAt}<time datetime={match.endedAt}>{new Date(match.endedAt).toLocaleString()}</time>{:else}—{/if}</td>
{#if server === undefined}<td><a href={`/servers/${encodeURIComponent(match.server)}?tab=matches`}>{serverTitle(match.server)}</a></td>{/if}
<td>{match.map}</td>
<td>{match.status === 'active' ? 'In progress' : match.status === 'completed' ? 'Completed' : 'Interrupted'}</td>
<td>{match.startPlayers ?? '—'}</td><td>{match.uniquePlayers}</td><td>{match.endPlayers ?? '—'}</td>
@@ -79,4 +83,5 @@
th, td { padding: var(--space-3); text-align: left; border-bottom: 1px solid var(--border-subtle); white-space: nowrap; }
th { color: var(--text-secondary); font-size: var(--text-xs); }
td { font-variant-numeric: tabular-nums; }
a { color: var(--accent-primary-hover); }
</style>