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%
3.5 KB · 81 lines tsx
Raw Blame History
1'use client';23import Link from 'next/link';4import { Bar, ConfBar, Empty, StatusDot } from '@/components/ui/primitives';5import { fmt, fmtInt, fmtRatio } from '@/lib/format';6import { useLive } from '@/lib/live';7import { pressureColor } from '@/lib/pressure';8import { Time } from '@/lib/time';9import type { Front } from '@/lib/types';1011const DIR: Record<string, string> = { east: '→ E', west: '← W', north: '↑ N', south: '↓ S', northeast: '↗ NE', northwest: '↖ NW', southeast: '↘ SE', southwest: '↙ SW' };1213/** Active Pressure Fronts (spec §20) — the signature feature, expressed as source → destination. */14export function Fronts({ initial }: { initial: Front[] | null }) {15  const live = useLive((s) => s.fronts);16  const fronts = live ?? initial ?? [];17  if (!fronts.length) return <Empty>No Pressure Front detected. Regions are not rising together.</Empty>;18  return (19    <ul className="divide-y divide-line">20      {fronts.map((f) => (21        <li key={f.id} className="grid gap-x-6 gap-y-2 py-3 md:grid-cols-[1fr_auto]">22          <div className="min-w-0">23            <div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">24              <h3 className="text-[14px] font-medium text-ink">{f.name}</h3>25              <StatusDot status={f.status} />26              <span className="num text-[11px] text-ink-3">27                since <Time ts={f.since} style="time" />28              </span>29            </div>30            <p className="mt-1 text-[12.5px] text-ink-2">31              <Link href={`/internet/${f.from.region}`} className="text-ink hover:text-accent">32                {f.from.name}33              </Link>{' '}34              <span className="num text-ink-3">{DIR[f.direction] ?? f.direction}</span>{' '}35              <Link href={`/internet/${f.to.region}`} className="text-ink hover:text-accent">36                {f.to.name}37              </Link>38            </p>39            <dl className="num mt-2 grid grid-cols-3 gap-x-4 gap-y-1 text-[11.5px] text-ink-2 sm:grid-cols-6">40              <div>41                <dt className="label">latency</dt>42                <dd className="text-ink">+{fmt(f.observed.latency_pct, 0)} %</dd>43              </div>44              <div>45                <dt className="label">churn</dt>46                <dd className="text-ink">{fmtRatio(f.observed.churn_x)}</dd>47              </div>48              <div>49                <dt className="label">loss</dt>50                <dd className="text-ink">{fmt(f.observed.loss_pct)} %</dd>51              </div>52              <div>53                <dt className="label">pairs</dt>54                <dd className="text-ink">{fmtInt(f.observed.pairs)}</dd>55              </div>56              <div>57                <dt className="label">targets</dt>58                <dd className="text-ink">{fmtInt(f.observed.targets)}</dd>59              </div>60              <div>61                <dt className="label">route Δ</dt>62                <dd className="text-ink">{fmtInt(f.observed.route_changes)}</dd>63              </div>64            </dl>65          </div>66          <div className="flex items-center gap-6 md:flex-col md:items-end md:gap-2">67            <div className="text-right">68              <div className="label">intensity</div>69              <div className="num text-[26px] leading-none" style={{ color: pressureColor(f.intensity) }}>70                {fmt(f.intensity)}71              </div>72              <Bar value={f.intensity} className="mt-1 w-24" />73            </div>74            <ConfBar value={f.confidence} />75          </div>76        </li>77      ))}78    </ul>79  );80}81