SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
13 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
3.1 KB · 66 lines tsx
Raw Blame History
1import { t } from '@/i18n';2import { adminApi, adminErrorMessage } from '@/lib/admin-api';3import { grouped } from '@/lib/format';4import { routes } from '@/lib/site';5import { AdminSection, AdminTable, Pill, bytes, statusTone, ts } from '@/components/admin/admin-ui';67export const dynamic = 'force-dynamic';89export default async function AdminRawPage({ searchParams }: { searchParams: Promise<{ run_id?: string }> }) {10  const { run_id } = await searchParams;11  let body: React.ReactNode = <p className="py-3 text-xs text-ink-3">{t('admin.raw.pick')}</p>;12  if (run_id) {13    try {14      const r = await adminApi.raw(run_id);15      body = (16        <>17          <AdminTable18            rows={r.runs}19            rowKey={(x, i) => `${x.connector}-${x.dataset}-${i}`}20            className="mb-4"21            columns={[22              { key: 'c', header: t('admin.connectors.connector'), cell: (x) => x.connector },23              { key: 'd', header: t('source.runs.dataset'), cell: (x) => <span className="break-all font-mono">{x.dataset}</span> },24              { key: 's', header: t('source.runs.status'), cell: (x) => <Pill tone={statusTone(x.status)}>{x.status ?? t('admin.na')}</Pill> },25              { key: 'p', header: t('admin.raw.file'), cell: (x) => <span className="break-all font-mono text-ink-2">{x.raw_path}</span> },26              { key: 'r', header: 'rows_raw', numeric: true, cell: (x) => (x.rows_raw != null ? grouped(x.rows_raw) : t('admin.na')) },27            ]}28          />29          <AdminTable30            rows={r.files}31            rowKey={(f) => f.path}32            empty={t('admin.raw.none')}33            columns={[34              { key: 'c', header: t('admin.connectors.connector'), cell: (f) => f.connector },35              { key: 'p', header: t('admin.raw.file'), cell: (f) => <span className={`break-all font-mono ${f.missing ? 'text-down' : 'text-ink'}`}>{f.path}{f.missing ? ` (${t('admin.raw.missing')})` : ''}</span> },36              { key: 's', header: t('admin.raw.size'), numeric: true, cell: (f) => bytes(f.size) },37              { key: 'm', header: t('admin.raw.modified'), cell: (f) => ts(f.modified_at) },38            ]}39          />40        </>41      );42    } catch (e) {43      body = <p className="rounded-sm border border-down/40 px-3 py-2 text-xs text-down">{adminErrorMessage(e)}</p>;44    }45  }46  return (47    <AdminSection48      title={t('admin.raw.title')}49      sub={t('admin.raw.sub')}50      actions={51        <form action={routes.admin('raw')} method="get" className="flex items-center gap-1.5">52          <label className="text-xs text-ink-3" htmlFor="run_id">53            {t('admin.raw.runId')}54          </label>55          <input id="run_id" name="run_id" defaultValue={run_id ?? ''} placeholder="20260911T072322Z" className="h-9 w-48 rounded-sm border border-rule bg-surface px-2 font-mono text-xs outline-none focus:border-accent" />56          <button type="submit" className="inline-flex h-9 items-center rounded-sm border border-rule px-2.5 text-xs text-ink hover:bg-surface-2">57            {t('admin.raw.load')}58          </button>59        </form>60      }61    >62      {body}63    </AdminSection>64  );65}66