SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
2.0 KB · 35 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import { TargetsRegistry } from '@/components/targets/TargetsRegistry';3import { apiGet } from '@/lib/api';4import { fmtInt } from '@/lib/format';5import type { Target } from '@/lib/types';67export const dynamic = 'force-dynamic';8export const metadata: Metadata = { title: 'Target registry', description: 'The representative endpoints we measure: cloud, CDN, DNS, developer platforms, social, finance, government, streaming and more.' };910const PAGE = 250;1112type TargetsResponse = { total: number; limit: number; offset: number; categories: string[]; targets: Target[] };1314export default async function TargetsPage({ searchParams }: { searchParams: Promise<{ q?: string; category?: string; page?: string; tier?: string; country?: string }> }) {15  const sp = await searchParams;16  const page = Math.max(1, Number(sp.page ?? '1') || 1);17  const params = new URLSearchParams({ limit: String(PAGE), offset: String((page - 1) * PAGE) });18  if (sp.q) params.set('q', sp.q);19  if (sp.category) params.set('category', sp.category);20  if (sp.tier) params.set('tier', sp.tier);21  if (sp.country) params.set('country', sp.country);22  const res = await apiGet<TargetsResponse>(`/api/v1/targets?${params.toString()}`);23  const pages = Math.max(1, Math.ceil(res.total / PAGE));24  return (25    <div className="pb-8">26      <header className="pt-6 pb-4">27        <p className="label">Registry</p>28        <h1 className="mt-1 text-[26px] font-medium tracking-tight sm:text-[32px]">Targets</h1>29        <p className="mt-1 max-w-[760px] text-[13px] text-ink-2">{fmtInt(res.total)} endpoints across {res.categories.length} categories. Tier 1 is checked every 20 s, tier 2 every 45 s, tier 3 every 5 min, tier 4 every 15 min; traceroutes every 15 min. Importance (1–5) weights each target in the aggregates.</p>30      </header>31      <TargetsRegistry targets={res.targets} categories={res.categories} initialQuery={sp.q ?? ''} initialCategory={sp.category ?? ''} total={res.total} page={page} pages={pages} pageSize={PAGE} />32    </div>33  );34}35