58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import Link from 'next/link';
|
|
import { getCountriesSummary } from '@/lib/queries';
|
|
import { countryCodeToFlag, countryCodeToName, formatMinutes } from '@/lib/steam';
|
|
|
|
// This page queries the DB directly with no dynamic route segment, so
|
|
// without this Next.js tries to statically pre-render it at BUILD time
|
|
// (requiring a live DB connection then, not just at request time).
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
export default async function CountriesPage() {
|
|
const countries = await getCountriesSummary();
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<h1 className="text-2xl text-ink mb-1">Countries</h1>
|
|
<p className="text-sm text-ink-muted">
|
|
Where the server's players connect from, most players first.
|
|
</p>
|
|
</div>
|
|
|
|
{countries.length === 0 ? (
|
|
<div className="panel p-6 text-sm text-ink-muted">No countries recorded yet.</div>
|
|
) : (
|
|
<div className="panel row-divide">
|
|
<div className="grid grid-cols-[1fr_auto_auto] gap-6 px-4 py-2 text-xs text-ink-faint uppercase tracking-wide">
|
|
<div>Country</div>
|
|
<div className="text-right w-24">Total playtime</div>
|
|
<div className="text-right w-24">Avg per player</div>
|
|
</div>
|
|
{countries.map((c) => (
|
|
<Link
|
|
key={c.current_country ?? 'unknown'}
|
|
href={`/countries/${c.current_country ? encodeURIComponent(c.current_country) : 'unknown'}`}
|
|
className="grid grid-cols-[1fr_auto_auto] gap-6 items-center px-4 py-3 hover:bg-base transition-colors"
|
|
>
|
|
<div className="flex items-center gap-3 min-w-0">
|
|
<span className="text-lg shrink-0" aria-hidden>
|
|
{countryCodeToFlag(c.current_country)}
|
|
</span>
|
|
<span className="text-ink text-sm truncate">{countryCodeToName(c.current_country)}</span>
|
|
{c.current_country && (
|
|
<span className="text-ink-faint text-xs mono shrink-0">{c.current_country}</span>
|
|
)}
|
|
<span className="text-ink-muted text-xs mono shrink-0">
|
|
{c.player_count} player{c.player_count === 1 ? '' : 's'}
|
|
</span>
|
|
</div>
|
|
<div className="text-sm text-ink mono text-right w-24">{formatMinutes(c.total_minutes)}</div>
|
|
<div className="text-sm text-ink-muted mono text-right w-24">{formatMinutes(Math.round(c.avg_minutes))}</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|