import Link from 'next/link';
import { t } from '@/i18n';
import { adminApi, adminErrorMessage } from '@/lib/admin-api';
import { ApiError } from '@/lib/api';
import { grouped } from '@/lib/format';
import { routes } from '@/lib/site';
import type { AdminOverview } from '@/lib/types-explore';
import { AdminSection, AdminTable, Kv, Pill, bytes, statusTone, ts } from '@/components/admin/admin-ui';
import { clearCacheAction, refreshAction } from '../actions';
export const dynamic = 'force-dynamic';
function hb(o: AdminOverview, key: string): string | null {
const h = o.scheduler.heartbeat;
if (!h) return null;
const v = h[key];
return v == null ? null : String(v);
}
export default async function AdminOverviewPage({ searchParams }: { searchParams: Promise<{ ok?: string; err?: string }> }) {
const sp = await searchParams;
let o: AdminOverview | null = null;
let error: string | null = null;
try {
o = await adminApi.overview();
} catch (e) {
error = e instanceof ApiError ? t('admin.unavailable', { status: e.status || 'network' }) + ` ${adminErrorMessage(e)}` : adminErrorMessage(e);
}
const actions = (
<>
>
);
return (
<>
{sp.ok ? {t('admin.actions.done', { msg: sp.ok })}
: null}
{sp.err ? {t('admin.actions.failed', { msg: sp.err })}
: null}
{error ? {error}
: null}
{o ? (
<>
{t('admin.snapshot')}
{o.status}],
['run_id', o.meta?.run_id ?? null],
['built_at', ts(o.meta?.built_at ?? null)],
['schema', o.meta?.schema_version != null ? String(o.meta.schema_version) : null],
['build_duration_s', o.meta?.build_duration_s != null ? String(o.meta.build_duration_s) : null],
]}
/>
{t('admin.db')}
{t('admin.scheduler')}
{t('admin.scheduler.alive', { pid: o.scheduler.pid })} : {t('admin.scheduler.dead', { pid: o.scheduler.pid })}],
[t('admin.scheduler.last'), ts(hb(o, 'last_run_at') ?? hb(o, 'last_run') ?? hb(o, 'finished_at'))],
[t('admin.scheduler.next'), ts(hb(o, 'next_run_at') ?? hb(o, 'next_run'))],
['heartbeat', ts(hb(o, 'heartbeat_at') ?? hb(o, 'updated_at') ?? hb(o, 'at'))],
['refresh', t('admin.scheduler.refreshAt', { time: o.settings.refresh_at })],
]}
/>
[k, grouped(v)] as [string, string])} />
[k, grouped(v)] as [string, string])} />
[k, String(v)] as [string, string])} />
r.connector}
columns={[
{ key: 'c', header: t('admin.connectors.connector'), cell: (r) => {r.connector} },
{ key: 'n', header: t('admin.connectors.runs'), numeric: true, cell: (r) => grouped(r.n_runs) },
{ key: 'last', header: t('admin.connectors.last'), cell: (r) => ts(r.last_finished_at) },
{ key: 's', header: t('admin.connectors.status'), cell: (r) => {r.last_status ?? t('admin.na')} },
{ key: 'ok', header: t('admin.connectors.ok'), numeric: true, cell: (r) => grouped(r.n_ok) },
{ key: 'f', header: t('admin.connectors.failed'), numeric: true, cell: (r) => (r.n_failed ? {grouped(r.n_failed)} : '0') },
{ key: 'rows', header: t('admin.connectors.rows'), numeric: true, cell: (r) => (r.rows_valid != null ? grouped(r.rows_valid) : t('admin.na')) },
{ key: 'w', header: t('admin.connectors.warnings'), numeric: true, cell: (r) => (r.warnings != null ? grouped(r.warnings) : t('admin.na')) },
{ key: 'e', header: t('admin.connectors.errors'), numeric: true, cell: (r) => (r.errors ? {grouped(r.errors)} : '0') },
]}
/>
r.source_id}
columns={[
{ key: 's', header: t('admin.stale.source'), cell: (r) => {r.source_id} },
{ key: 'n', header: t('admin.stale.observations'), numeric: true, cell: (r) => grouped(r.n_observations) },
{ key: 'u', header: t('admin.stale.updated'), cell: (r) => ts(r.source_updated_at) },
{ key: 'r', header: t('admin.stale.retrieved'), cell: (r) => ts(r.retrieved_at) },
{ key: 'st', header: t('admin.stale.n'), numeric: true, cell: (r) => (r.n_stale ? {grouped(r.n_stale)} : '0') },
]}
/>
>
) : !error ? (
{t('admin.empty')}
) : null}
>
);
}