import type { Metadata } from 'next'; import Link from 'next/link'; import { ActionButton, AdminFilters, AdminTitle, JsonPre, Mono, Notice, StatusChip } from '@/components/admin/ui'; import { EntityBadge } from '@/components/ui/badges'; import { DataTable, EmptyRow, Td, Th } from '@/components/ui/data-table'; import { LiveAgo } from '@/components/ui/live'; import { Pagination, withParams } from '@/components/ui/pagination'; import { EmptyState, Unavailable } from '@/components/ui/unavailable'; import { anomalyAction } from '@/lib/admin/actions'; import { adminApi, load, requireAdmin } from '@/lib/admin/admin-api'; import { cn } from '@/lib/cn'; import { fmtDateTime, fmtInt, fmtValue } from '@/lib/format'; import { routes } from '@/lib/site'; export const metadata: Metadata = { title: 'Anomalies', robots: { index: false, follow: false } }; export const dynamic = 'force-dynamic'; const LIMIT = 50; const SEV: Record = { critical: 'text-danger', warning: 'text-warning', info: 'text-ink-3' }; export default async function AdminAnomaliesPage({ searchParams }: { searchParams: Promise> }) { await requireAdmin(); const sp = await searchParams; const current: Record = { status: sp.status ?? 'open' }; if (sp.severity) current.severity = sp.severity; if (sp.check) current.check = sp.check; if (sp.offset) current.offset = sp.offset; const offset = Math.max(0, Number(current.offset) || 0); const href = (patch: Record) => withParams('/admin/anomalies', current, patch); const ret = href({}); const res = await load(adminApi.anomalies({ status: current.status, severity: current.severity, check: current.check, limit: LIMIT, offset })); const byCheck = res.ok ? (res.data.by_check ?? []) : []; const checks = [...new Set(byCheck.map((c) => c.check_name))].sort(); return ( <> Check definitions → {byCheck.length > 0 && (
    {byCheck.map((c) => (
  • {c.severity} {c.check_name} {fmtInt(c.n)}
  • ))}
)} ({ value: s, label: s })) }, { kind: 'select', name: 'severity', label: 'Severity', value: current.severity, options: ['critical', 'warning', 'info'].map((s) => ({ value: s, label: s })) }, { kind: 'select', name: 'check', label: 'Check', value: current.check, options: checks.map((c) => ({ value: c, label: c })) }, ]} /> {!res.ok ? ( ) : res.data.items.length === 0 ? ( ) : ( <> Severity Check Entity Message Value Status Seen Actions {res.data.items.length === 0 && No rows.} {res.data.items.map((a) => ( {a.severity} {a.check_name} {a.slug ? ( {a.entity_name ?? a.slug} ) : ( {a.entity_id ?? '—'} )} {a.message} {a.detail && (
detail
)} {fmtValue(a.value)} {a.resolution && typeof a.resolution.note === 'string' && {a.resolution.note}}
{a.status !== 'resolved' && (
Resolve
)} {a.status !== 'ignored' && (
Ignore
)} {a.status !== 'open' && (
Reopen
)}
))}
href({ offset: o || undefined })} className="mt-4" /> )} ); }