import type { ReactNode } from "react"; import type { Health } from "@/lib/discord"; // Shared pieces for the Discord admin page (design-canvas/discord-system-mockup.html, // "DRB admin" view): panels with a title row, dense tables, status dots. const DOT: Record = { ok: "bg-green-500", warn: "bg-sev-moderate", bad: "bg-sev-major", off: "bg-ink-muted", }; export function Status({ health, children }: { health: Health; children: ReactNode }) { return ( {children} ); } export function Panel({ title, description, action, note, children, }: { title: string; description?: ReactNode; action?: ReactNode; note?: ReactNode; children: ReactNode; }) { return (

{title}

{description && {description}} {action &&
{action}
}
{children} {note &&
{note}
}
); } export const TH = "text-left font-medium text-ink-muted text-xs px-4 py-2 border-b border-line whitespace-nowrap"; export const TD = "px-4 py-2.5 border-b border-line align-top text-sm text-ink"; export const DIM = "text-xs text-ink-muted"; export function Table({ head, children }: { head: string[]; children: ReactNode }) { return (
{head.map((h, i) => ( ))} {children}
{h}
); } export function Field({ label, children, hint }: { label: string; children: ReactNode; hint?: ReactNode }) { return ( ); } export const INPUT = "w-full bg-page border border-line rounded-lg px-3 py-2 text-ink text-sm focus:outline-none focus:border-accent"; export function InviteLinks({ invite }: { invite: { name: string; invite_url: string | null }[] }) { if (!invite.length) return null; return ( {invite.map((b) => b.invite_url ? ( Invite {b.name} ) : ( {b.name} (no invite link — refresh it under Radio bots) ), )} ); }