SPB Git

Repository Public

ArchitectureDiagram.tsx 3.0 KB 54 lines tsx

1import { getDict, type Locale } from "@/lib/i18n";23function Cell({ title, sub, tone = "solid", className = "" }: { title: string; sub?: string; tone?: "solid" | "accent" | "ext"; className?: string }) {4  const tones = { solid: "border-line-strong bg-surface", accent: "border-accent/60 bg-accent-soft", ext: "border-dashed border-line-strong" };5  return (6    <div className={`rounded-xl border px-4 py-3.5 ${tones[tone]} ${className}`}>7      <p className="text-[0.9375rem] font-medium leading-tight">{title}</p>8      {sub ? <p className="mt-1.5 font-mono text-[0.6875rem] leading-snug tracking-[0.04em] text-mute">{sub}</p> : null}9    </div>10  );11}1213const Wire = ({ dashed = false, label }: { dashed?: boolean; label?: string }) => (14  <div className="flex items-center justify-center gap-3 py-1" aria-hidden={label ? undefined : true}>15    <svg width="2" height="30" viewBox="0 0 2 30" aria-hidden="true" className="overflow-visible">16      <line x1="1" y1="0" x2="1" y2="30" stroke={dashed ? "#1D5FD1" : "#0C1322"} strokeOpacity={dashed ? 1 : 0.3} strokeDasharray={dashed ? "4 7" : undefined} className={dashed ? "trace" : undefined} />17    </svg>18    {label ? <span className="font-mono text-[0.6875rem] tracking-[0.08em] text-accent">{label}</span> : null}19  </div>20);2122/** Layered logical diagram in real text (readable, translatable, zoomable). Roles and boundaries only. */23export function ArchitectureDiagram({ locale, nodeCount, memoryMax }: { locale: Locale; nodeCount: number; memoryMax: number | null }) {24  const t = getDict(locale).architecture.diagram;25  const c = getDict(locale).common;26  return (27    <figure aria-label={t.alt}>28      <div className="mx-auto max-w-3xl">29        <Cell title={t.internet} tone="ext" className="mx-auto max-w-[16rem] text-center" />30        <Wire />31        <Cell title={t.external} sub={t.externalSub} tone="ext" className="mx-auto max-w-[24rem] text-center" />32        <Wire dashed label={t.tunnel} />33        <div className="relative rounded-2xl border border-dashed border-line-strong p-4 pt-10 md:p-6 md:pt-11">34          <span className="label absolute left-4 top-3 md:left-6">{t.boundary}</span>35          <div className="grid gap-3 sm:grid-cols-2">36            <Cell title={t.gateway} sub={t.gatewaySub} tone="accent" />37            <Cell title={t.monitor} sub={t.monitorSub} />38          </div>39          <Wire />40          <div className="rounded-xl border border-line-strong bg-surface-2 px-4 py-2.5 text-center font-mono text-[0.75rem] tracking-[0.06em] text-body">{t.switch}</div>41          <Wire />42          <div className="grid gap-3 sm:grid-cols-3">43            <Cell title={t.nodes} sub={`${nodeCount} · ${t.nodesSub}${memoryMax ? ` · max ${memoryMax} ${c.gb}` : ""}`} className="sm:col-span-2" />44            <Cell title={t.storage} sub={t.storageSub} />45          </div>46          <div className="mt-3 grid gap-3 sm:grid-cols-3">47            <Cell title={t.serving} sub={t.servingSub} className="sm:col-span-2" />48          </div>49        </div>50      </div>51    </figure>52  );53}54
Files main
Menu

Theme