Remove command-center page and dependencies
Deploy to route.crispygoat.com / deploy (push) Successful in 4m20s

The /admin/command-center route was platform_admin-only, used a heavy
custom theme (Major Mono / JetBrains / Inter Tight + ~700 lines of
schematic CSS), called three RPCs, and overlapped with the per-brand
dashboards reachable at /admin, /admin/orders, /admin/stops, and
/admin/reports. The page is being removed; it didn't justify the
build complexity, font payload, or schema surface area.

Changes:
- Drop page, dashboard component, CSS, and server actions
- Remove the platform_admin nav entry from header + sidebar
- Remove the cmd+K palette entry
- Add migration 0042 to drop the 3 RPCs, founder_pain_log table,
  and founder_pain_log_platform view it owned
- Decrement route count in docs/pricing-assessment.md (88 -> 87)

Verification: tsc clean, eslint clean, npm run build clean, command-
center absent from the route list.
This commit is contained in:
Tyler
2026-06-17 10:18:33 -06:00
parent 3d4b98d703
commit 0a534222e8
9 changed files with 21 additions and 2190 deletions
+1 -3
View File
@@ -80,9 +80,7 @@ export default function AdminHeader({ userRole, canManageUsers, routeTraceEnable
? [{ href: "/admin/route-trace", label: "Route Trace" }]
: [];
const fullNavLinks = BASE_NAV_LINKS.concat(
userRole === "platform_admin" ? [{ href: "/admin/command-center", label: "Command Center" }] : []
).concat(moduleLinks);
const fullNavLinks = BASE_NAV_LINKS.concat(moduleLinks);
const navLinks = isStoreEmployee ? EMPLOYEE_NAV_LINKS : fullNavLinks;
const homeHref = isStoreEmployee ? "/admin/wholesale" : "/admin";
-7
View File
@@ -12,7 +12,6 @@ import {
Ship,
Mail,
Store,
Sparkles,
Upload,
BrainCircuit,
Clock,
@@ -74,12 +73,6 @@ const NAV_GROUPS: NavGroup[] = [
label: "Workspace",
items: [
{ href: "/admin", label: "Dashboard", icon: LayoutDashboard },
{
href: "/admin/command-center",
label: "Command Center",
icon: Sparkles,
requiresPlatformAdmin: true,
},
],
},
{
@@ -1,811 +0,0 @@
"use client";
/* eslint-disable react-hooks/set-state-in-effect */
import { useState, useEffect, useCallback, useMemo } from "react";
import {
getPlatformMetrics,
getPlatformActivityFeed,
getBrandHealthSnapshot,
getPainLog,
resolvePainLogItem,
createPainLogItem,
type PlatformMetrics,
type ActivityEvent,
type BrandHealth,
type PainLogItem,
} from "@/actions/platform/command-center";
// ── Constants ──────────────────────────────────────────────────────────────
const REFRESH_INTERVAL = 30000;
const SEVERITY_LED: Record<string, string> = {
critical: "cc-led--critical",
high: "cc-led--warn",
medium: "cc-led cc-led--info",
low: "cc-led--off",
};
const HEALTH_LED: Record<string, string> = {
healthy: "cc-led--healthy",
warning: "cc-led--warn",
critical: "cc-led--critical",
};
const HEALTH_CLASS: Record<string, string> = {
healthy: "cc-brand--healthy",
warning: "cc-brand--warning",
critical: "cc-brand--critical",
};
const HEALTH_LABEL: Record<string, string> = {
healthy: "OPERATIONAL",
warning: "ATTENTION",
critical: "CRITICAL",
};
const FEED_CODE_CLASS: Record<string, string> = {
order_placed: "cc-feed__code--order_placed",
order_completed: "cc-feed__code--order_completed",
pickup_completed: "cc-feed__code--pickup_completed",
payment_failed: "cc-feed__code--payment_failed",
stop_created: "cc-feed__code--stop_created",
route_updated: "cc-feed__code--route_updated",
};
const QUICK_ACCESS = [
{ label: "Reports", href: "/admin/reports" },
{ label: "Orders", href: "/admin/orders" },
{ label: "Stops", href: "/admin/stops" },
{ label: "Settings", href: "/admin/settings" },
];
// ── Helpers ────────────────────────────────────────────────────────────────
function formatCurrency(n: number): string {
return new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD",
minimumFractionDigits: 0, maximumFractionDigits: 0,
}).format(n);
}
function formatCurrencyFull(n: number): string {
return new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD",
minimumFractionDigits: 2, maximumFractionDigits: 2,
}).format(n);
}
function timeAgo(dateStr: string): string {
const diff = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);
if (diff < 60) return `${diff}s ago`;
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
if (diff < 86400)return `${Math.floor(diff / 3600)}h ago`;
return `${Math.floor(diff / 86400)}d ago`;
}
function formatTime(dateStr: string): string {
const d = new Date(dateStr);
return d.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
}
function formatToday(): string {
return new Date().toLocaleDateString("en-US", {
weekday: "short", month: "short", day: "2-digit", year: "numeric",
}).toUpperCase();
}
function formatClock(): string {
return new Date().toLocaleTimeString("en-US", {
hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit",
});
}
/**
* Stable pseudo-random sparkline series. Deterministic from a string seed so
* the bars don't reshuffle on every render — important for the live-data feel.
* 12 bars, values 0.11.0.
*/
function spark(seed: string, len = 12): number[] {
const out: number[] = [];
let h = 0;
for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) | 0;
for (let i = 0; i < len; i++) {
h = (h * 1103515245 + 12345) | 0;
out.push(0.1 + (Math.abs(h) % 1000) / 1111);
}
return out;
}
function barClass(v: number, critical: boolean, warn: boolean): string {
if (critical) return "cc-kpi__bar cc-kpi__bar--critical";
if (warn) return "cc-kpi__bar cc-kpi__bar--warn";
if (v > 0.55) return "cc-kpi__bar cc-kpi__bar--lit";
if (v > 0.3) return "cc-kpi__bar cc-kpi__bar--healthy";
return "cc-kpi__bar";
}
// ── Corner Crosshairs ──────────────────────────────────────────────────────
function Corners() {
return (
<>
<span className="cc-corner cc-corner--tl" />
<span className="cc-corner cc-corner--tr" />
<span className="cc-corner cc-corner--bl" />
<span className="cc-corner cc-corner--br" />
</>
);
}
// ── Top Status Bar ─────────────────────────────────────────────────────────
function TopBar({ brands }: { brands: BrandHealth[] }) {
const [clock, setClock] = useState<string>(formatClock());
useEffect(() => {
const iv = setInterval(() => setClock(formatClock()), 1000);
return () => clearInterval(iv);
}, []);
// Build a long-enough ticker sequence (duplicated for seamless loop)
const tickerItems = useMemo(() => {
const list = brands.length > 0
? brands.map(b => ({ name: b.brand_name, slug: b.brand_slug, plan: b.plan_tier.toUpperCase() }))
: [
{ name: "Tuxedo Corn", slug: "tuxedo-corn", plan: "FARM" },
{ name: "Indian River Direct", slug: "indian-river-direct", plan: "ENTERPRISE" },
];
// Duplicate to enable seamless loop
return [...list, ...list, ...list, ...list];
}, [brands]);
return (
<header className="cc-topbar" role="banner">
<div className="cc-topbar__brand">
<span className="cc-topbar__brand-mark">RC</span>
<span>route.commerce</span>
<span className="cc-topbar__sep">/</span>
<span className="cc-topbar__scope">
scope <b>PLATFORM</b>
</span>
</div>
<div className="cc-ticker" aria-label="Live brand ticker">
<div className="cc-ticker__track">
{tickerItems.map((b, i) => (
<span key={i} className="cc-ticker__chip">
<b>{b.name}</b>
<span>· {b.slug} · {b.plan}</span>
</span>
))}
</div>
</div>
<div className="cc-topbar__meta">
<span className="cc-led cc-led--live" />
<span style={{ color: "var(--cc-amber)" }}>LIVE</span>
<span className="cc-topbar__clock">{clock}</span>
<span style={{ color: "var(--cc-faint)" }}>UTC</span>
<span className="cc-topbar__sep">·</span>
<span>{formatToday()}</span>
</div>
</header>
);
}
// ── KPI Card ──────────────────────────────────────────────────────────────
function KPICard({
serial, label, value, unit, sub, sparkSeed, status, delay,
}: {
serial: string;
label: string;
value: string | number;
unit?: string;
sub?: string;
sparkSeed: string;
status: "healthy" | "warn" | "critical";
delay: number;
}) {
const valueClass =
status === "critical" ? "cc-kpi__value cc-kpi__value--critical"
: status === "warn" ? "cc-kpi__value cc-kpi__value--warn"
: "cc-kpi__value cc-kpi__value--healthy";
const ledClass =
status === "critical" ? "cc-led cc-led--critical"
: status === "warn" ? "cc-led cc-led--warn"
: "cc-led cc-led--healthy";
const bars = spark(sparkSeed);
return (
<div className="cc-kpi cc-rise" data-stagger={delay}>
<Corners />
<div className="cc-kpi__head">
<span className="cc-kpi__label">{label}</span>
<span className={ledClass} />
</div>
<div className={valueClass}>
{typeof value === "number" ? value.toLocaleString() : value}
{unit && <span className="cc-kpi__unit"> {unit}</span>}
</div>
{sub && <div className="cc-kpi__sub">{sub}</div>}
<div className="cc-kpi__spark" aria-hidden>
{bars.map((v, i) => (
<span
key={i}
className={barClass(v, status === "critical", status === "warn")}
style={{ height: `${Math.max(2, v * 22)}px` }}
/>
))}
</div>
<span className="cc-kpi__serial" style={{ position: "absolute", right: 12, bottom: 8 }}>
{serial}
</span>
</div>
);
}
// ── AI Briefing ────────────────────────────────────────────────────────────
function AIBriefing({ metrics, brandHealth }: {
metrics: PlatformMetrics | null;
brandHealth: BrandHealth[];
}) {
const items = useMemo(() => {
if (!metrics) return [] as { idx: string; text: React.ReactNode }[];
const out: { idx: string; text: React.ReactNode }[] = [];
if (metrics.orders_today > 0) {
out.push({ idx: "01", text: <><b>{metrics.orders_today}</b> order{metrics.orders_today !== 1 ? "s" : ""} placed across all brands today.</> });
}
if (Number(metrics.revenue_today) > 0) {
out.push({ idx: "02", text: <><b>{formatCurrencyFull(Number(metrics.revenue_today))}</b> in revenue processed · target pacing on track.</> });
}
if (metrics.active_routes > 0) {
out.push({ idx: "03", text: <><b>{metrics.active_routes}</b> active route{metrics.active_routes !== 1 ? "s" : ""} running · all on schedule.</> });
}
if (metrics.pending_orders_today > 0) {
out.push({ idx: "04", text: <><b>{metrics.pending_orders_today}</b> order{metrics.pending_orders_today !== 1 ? "s" : ""} pending confirmation · review queue.</> });
}
if (metrics.failed_orders_today > 0) {
out.push({ idx: "05", text: <><em>{metrics.failed_orders_today} failed</em> · payment retry window open · triage required.</> });
}
const crit = brandHealth.filter(b => b.health_status === "critical").length;
if (crit > 0) {
out.push({ idx: "06", text: <><em>{crit} brand{crit !== 1 ? "s" : ""}</em> in critical state · investigate pain log entries.</> });
}
const warn = brandHealth.filter(b => b.health_status === "warning").length;
if (warn > 0 && crit === 0) {
out.push({ idx: "07", text: <><b>{warn}</b> brand{warn !== 1 ? "s" : ""} flagged for attention · monitoring.</> });
}
if (out.length === 0) {
out.push({ idx: "00", text: <span className="cc-briefing__line-ok">PLATFORM NOMINAL · no active issues · all channels green</span> });
}
return out;
}, [metrics, brandHealth]);
return (
<section className="cc-briefing cc-rise" data-stagger="4">
<Corners />
<div className="cc-briefing__main">
<div className="cc-briefing__head">
<span>Platform Briefing</span>
<span className="cc-briefing__head-meta">
<span className="cc-led cc-led--live" />
<span>GENERATED · {new Date().toLocaleTimeString("en-US", { hour12: false })}</span>
</span>
</div>
<div className="cc-briefing__lines">
{items.map(it => (
<div key={it.idx} className="cc-briefing__line">
<span className="cc-briefing__line-idx">{it.idx}</span>
<span>{it.text}</span>
</div>
))}
</div>
</div>
<div className="cc-briefing__model" aria-label="Model metadata">
<div className="cc-briefing__model-row"><span>Source</span><b>live.rpc</b></div>
<div className="cc-briefing__model-row"><span>Window</span><b>24h</b></div>
<div className="cc-briefing__model-row"><span>Build</span><b>cc-26.6</b></div>
</div>
</section>
);
}
// ── Brand Health Panel ─────────────────────────────────────────────────────
function BrandPanel({ brand, delay }: { brand: BrandHealth; delay: number }) {
const ledClass = HEALTH_LED[brand.health_status] ?? "cc-led--off";
const statusClass = HEALTH_CLASS[brand.health_status] ?? "";
const statusLabel = HEALTH_LABEL[brand.health_status] ?? "UNKNOWN";
return (
<article className={`cc-brand ${statusClass} cc-rise`} data-stagger={delay}>
<Corners />
<div className="cc-brand__head">
<div>
<div className="cc-brand__name">
<span className={`cc-led ${ledClass}`} />
{brand.brand_name}
</div>
<div className="cc-brand__slug">
<b>/{brand.brand_slug}</b> · {brand.plan_tier}
</div>
</div>
<span className={`cc-brand__status cc-brand__status--${brand.health_status}`}>
{statusLabel}
</span>
</div>
<div className="cc-brand__metrics">
<div className="cc-brand__metric">
<span className="cc-brand__metric-label">Orders</span>
<span className="cc-brand__metric-value">{brand.orders_today}</span>
</div>
<div className="cc-brand__metric">
<span className="cc-brand__metric-label">Revenue</span>
<span className="cc-brand__metric-value">{formatCurrency(Number(brand.revenue_today))}</span>
</div>
<div className="cc-brand__metric">
<span className="cc-brand__metric-label">Routes</span>
<span className={`cc-brand__metric-value ${brand.failed_orders > 0 ? "cc-brand__metric-value--critical" : ""}`}>
{brand.active_stops}
</span>
</div>
</div>
{brand.open_pain_items > 0 && (
<div className="cc-brand__pain">
<span className="cc-led cc-led--critical" />
<span><b>{brand.open_pain_items}</b> open issue{brand.open_pain_items !== 1 ? "s" : ""} on this brand</span>
<span>Founder Queue</span>
</div>
)}
</article>
);
}
// ── Pain Log Item ─────────────────────────────────────────────────────────
function PainItem({
item, idx, onResolve, onSnooze,
}: {
item: PainLogItem;
idx: number;
onResolve: (id: string) => void;
onSnooze: (id: string) => void;
}) {
const ledClass = SEVERITY_LED[item.severity] ?? "cc-led--off";
const severityClass = `cc-pain--${item.severity}`;
const serial = `P.${String(idx).padStart(3, "0")}`;
return (
<article className={`cc-pain ${severityClass} cc-rise`} data-stagger={Math.min(idx + 1, 10)}>
<Corners />
<div className="cc-pain__head">
<span className="cc-pain__severity" style={{
color: item.severity === "critical" ? "var(--cc-critical)"
: item.severity === "high" ? "var(--cc-warn)"
: item.severity === "medium" ? "var(--cc-amber)"
: "var(--cc-muted)"
}}>
<span className={ledClass} />
{item.severity}
</span>
<span className="cc-pain__title">{item.title}</span>
<div className="cc-pain__actions">
<button onClick={() => onSnooze(item.id)} className="cc-btn cc-btn--snooze">Snooze</button>
<button onClick={() => onResolve(item.id)} className="cc-btn cc-btn--resolved">Done</button>
</div>
</div>
<div className="cc-pain__foot">
<span>{serial}</span>
<span className="cc-pain__foot-sep">·</span>
{item.brand_name && <><span><b>{item.brand_name}</b></span><span className="cc-pain__foot-sep">·</span></>}
<span><b>{item.category}</b></span>
<span className="cc-pain__foot-sep">·</span>
<span>{item.created_at ? timeAgo(item.created_at) : ""}</span>
</div>
</article>
);
}
// ── Activity Feed Row ──────────────────────────────────────────────────────
function ActivityRow({ event, idx }: { event: ActivityEvent; idx: number }) {
const codeClass = FEED_CODE_CLASS[event.event_type] ?? "cc-feed__code--default";
const code = event.event_type.replace(/_/g, " ").toUpperCase();
return (
<div className="cc-feed__row cc-rise" data-stagger={Math.min(idx + 1, 10)}>
<span className="cc-feed__time">
{event.created_at ? formatTime(event.created_at) : "—"}
</span>
<span className={`cc-feed__code ${codeClass}`}>{code}</span>
<span className="cc-feed__detail">
{event.brand_name && <span className="cc-feed__brand">{event.brand_name}</span>}
<span className="cc-feed__entity">{event.entity_type ?? "event"}</span>
{event.entity_id && (
<span className="cc-feed__entity-id">#{event.entity_id.slice(0, 8)}</span>
)}
</span>
<span className="cc-feed__ago">{event.created_at ? timeAgo(event.created_at) : ""}</span>
</div>
);
}
// ── Main ──────────────────────────────────────────────────────────────────
export default function CommandCenterDashboard() {
const [metrics, setMetrics] = useState<PlatformMetrics | null>(null);
const [activity, setActivity] = useState<ActivityEvent[]>([]);
const [brandHealth, setBrandHealth] = useState<BrandHealth[]>([]);
const [painLog, setPainLog] = useState<PainLogItem[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [resolving, setResolving] = useState<Set<string>>(new Set());
const [showAddForm, setShowAddForm] = useState(false);
const [tvMode, setTvMode] = useState(false);
const [addForm, setAddForm] = useState({ severity: "medium", category: "operations", title: "", description: "" });
const [snoozed, setSnoozed] = useState<Set<string>>(new Set());
const fetchAll = useCallback(async () => {
try {
const [m, a, b, p] = await Promise.all([
getPlatformMetrics(),
getPlatformActivityFeed(),
getBrandHealthSnapshot(),
getPainLog(),
]);
setMetrics(m);
setActivity(a);
setBrandHealth(b);
setPainLog(p);
setError(null);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to load");
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchAll();
const iv = setInterval(fetchAll, REFRESH_INTERVAL);
return () => clearInterval(iv);
}, [fetchAll]);
const handleResolve = async (id: string) => {
if (resolving.has(id)) return;
setResolving(prev => new Set([...prev, id]));
try {
const r = await resolvePainLogItem(id);
if (r.success) setPainLog(prev => prev.filter(i => i.id !== id));
} finally {
setResolving(prev => { const n = new Set(prev); n.delete(id); return n; });
}
};
const handleSnooze = (id: string) => {
setSnoozed(prev => new Set([...prev, id]));
setTimeout(() => {
setSnoozed(prev => { const n = new Set(prev); n.delete(id); return n; });
}, 3600000);
};
const handleAdd = async () => {
if (!addForm.title.trim()) return;
const r = await createPainLogItem({
severity: addForm.severity as "low" | "medium" | "high" | "critical",
category: addForm.category,
title: addForm.title,
description: addForm.description || null,
});
if (r.success) {
setAddForm({ severity: "medium", category: "operations", title: "", description: "" });
setShowAddForm(false);
fetchAll();
}
};
const openItems = painLog.filter(p => p.status === "open" && !snoozed.has(p.id));
// ── Loading state ─────────────────────────────────────────────────────
if (loading) {
return (
<div className="cc-schematic" data-tv={tvMode ? "true" : "false"}>
<TopBar brands={[]} />
<div className="cc-frame">
<div className="cc-masthead cc-rise">
<div>
<div className="cc-masthead__eyebrow">{"// "}00 · BOOT SEQUENCE</div>
<h1 className="cc-masthead__title">Command <em>Center</em></h1>
</div>
</div>
<div className="cc-skeleton cc-rise" data-stagger="1" style={{ marginTop: 32 }}>
<span className="cc-skeleton__bar"><span></span><span></span></span>
<span>Initializing platform channels</span>
<span style={{ marginLeft: "auto", color: "var(--cc-faint)" }}>{"// "}awaiting telemetry</span>
</div>
</div>
</div>
);
}
// ── Error state ("Signal Lost") ────────────────────────────────────────
if (error) {
return (
<div className="cc-schematic" data-tv={tvMode ? "true" : "false"}>
<TopBar brands={[]} />
<div className="cc-signal-lost">
<div className="cc-signal-lost__panel cc-rise">
<Corners />
<div className="cc-signal-lost__eyebrow">
<span>SIGNAL LOST · COMMS OFFLINE</span>
</div>
<h2 className="cc-signal-lost__title">
Platform <em>Disconnected</em>
</h2>
<p className="cc-signal-lost__sub">
The Command Center cannot reach the platform RPCs right now.
This is usually a transient database or auth issue the data is safe, the connection isn{`'`}t.
</p>
<div className="cc-signal-lost__error">{error}</div>
<div className="cc-signal-lost__actions">
<button onClick={fetchAll} className="cc-btn cc-btn--primary">
<span></span> Reconnect
</button>
<a href="/admin" className="cc-btn cc-btn--ghost">Return to admin</a>
</div>
<div className="cc-signal-lost__hint">
<span>{"// "}SUGGESTED · check DATABASE_URL · re-run migrations</span>
<span>CODE: <b style={{ color: "var(--cc-critical)" }}>RPC_UNREACHABLE</b></span>
</div>
</div>
</div>
</div>
);
}
// ── Main state ────────────────────────────────────────────────────────
return (
<div className="cc-schematic" data-tv={tvMode ? "true" : "false"}>
<TopBar brands={brandHealth} />
<div className="cc-frame">
{/* ── Masthead ───────────────────────────────────────────────────── */}
<div className="cc-masthead cc-rise">
<div>
<div className="cc-masthead__eyebrow">{"// "}01 · PLATFORM OPERATIONS</div>
<h1 className="cc-masthead__title">Command <em>Center</em></h1>
<p className="cc-masthead__sub">
Real-time platform telemetry · {brandHealth.length} active brand{brandHealth.length !== 1 ? "s" : ""} ·
last sync <b>just now</b> · refresh every <b>30s</b>
</p>
</div>
<div className="cc-masthead__actions">
<button onClick={fetchAll} className="cc-btn cc-btn--ghost">
<span></span> Refresh
</button>
<button onClick={() => setTvMode(v => !v)} className="cc-btn">
{tvMode ? "Exit TV" : "TV Mode"}
</button>
</div>
</div>
{/* ── KPI Row ────────────────────────────────────────────────────── */}
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}02</span>
<span className="cc-section__title">KPI OVERVIEW</span>
<span className="cc-section__rule" />
<span className="cc-section__count">06</span>
</div>
<div className="cc-kpi-grid">
<KPICard
serial="M.01" label="Active Brands" delay={1}
value={metrics?.active_brands ?? 0}
sub={`${brandHealth.filter(b => b.health_status === "healthy").length} healthy`}
sparkSeed="brands" status="healthy"
/>
<KPICard
serial="M.02" label="Orders Today" delay={2}
value={metrics?.orders_today ?? 0}
sub={`${metrics?.pending_orders_today ?? 0} pending`}
sparkSeed="orders" status={(metrics?.failed_orders_today ?? 0) > 0 ? "critical" : "healthy"}
/>
<KPICard
serial="M.03" label="Revenue Today" delay={3}
value={formatCurrency(Number(metrics?.revenue_today ?? 0))}
sub="24h window"
sparkSeed="revenue" status="healthy"
/>
<KPICard
serial="M.04" label="Active Routes" delay={4}
value={metrics?.active_routes ?? 0}
sub="In field"
sparkSeed="routes" status={(metrics?.pending_orders_today ?? 0) > 5 ? "warn" : "healthy"}
/>
<KPICard
serial="M.05" label="Failed Orders" delay={5}
value={metrics?.failed_orders_today ?? 0}
sub={metrics?.failed_orders_today ? "Needs attention" : "All clean"}
sparkSeed="failed" status={(metrics?.failed_orders_today ?? 0) > 0 ? "critical" : "healthy"}
/>
<KPICard
serial="M.06" label="Pending Orders" delay={6}
value={metrics?.pending_orders_today ?? 0}
sub="Awaiting confirmation"
sparkSeed="pending" status={(metrics?.pending_orders_today ?? 0) > 5 ? "warn" : "healthy"}
/>
</div>
</section>
{/* ── AI Briefing ─────────────────────────────────────────────────── */}
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}03</span>
<span className="cc-section__title">DAILY BRIEFING</span>
<span className="cc-section__rule" />
<span className="cc-section__count">AUTO</span>
</div>
<AIBriefing metrics={metrics} brandHealth={brandHealth} />
</section>
{/* ── Two-column body ────────────────────────────────────────────── */}
<div className="cc-grid">
{/* LEFT: Brand Health + Activity */}
<div>
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}04</span>
<span className="cc-section__title">BRAND HEALTH</span>
<span className="cc-section__rule" />
<span className="cc-section__count">{brandHealth.length}</span>
</div>
{brandHealth.length === 0 ? (
<div className="cc-empty cc-rise">
<div className="cc-empty__title">{"// "}NO ACTIVE BRANDS</div>
<div className="cc-empty__sub">No brands registered on this platform.</div>
</div>
) : (
<div style={{ display: "grid", gap: 16 }}>
{brandHealth.map((b, i) => (
<BrandPanel key={b.brand_id} brand={b} delay={i + 1} />
))}
</div>
)}
</section>
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}05</span>
<span className="cc-section__title">LIVE ACTIVITY</span>
<span className="cc-section__rule" />
<span className="cc-section__count">{activity.length}</span>
</div>
<div className="cc-feed cc-rise" data-stagger="3">
<Corners />
<div className="cc-feed__list">
{activity.length === 0 ? (
<div className="cc-empty">
<div className="cc-empty__title">{"// "}NO EVENTS</div>
<div className="cc-empty__sub">Waiting for telemetry.</div>
</div>
) : (
activity.slice(0, 30).map((e, i) => (
<ActivityRow key={e.id} event={e} idx={i} />
))
)}
</div>
</div>
</section>
</div>
{/* RIGHT: Founder Queue + Quick Access */}
<div>
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}06</span>
<span className="cc-section__title">FOUNDER QUEUE</span>
<span className="cc-section__rule" />
<span className="cc-section__count">{openItems.length}</span>
<button
onClick={() => setShowAddForm(v => !v)}
className="cc-btn cc-btn--ghost"
style={{ marginLeft: 12 }}
>
{showAddForm ? "Cancel" : "+ Log Issue"}
</button>
</div>
{showAddForm && (
<div className="cc-form cc-rise" data-stagger="1" style={{ marginBottom: 16 }}>
<div className="cc-form__head">NEW PAIN LOG ENTRY</div>
<div className="cc-form__row">
<select
value={addForm.severity}
onChange={e => setAddForm(f => ({ ...f, severity: e.target.value }))}
className="cc-field"
>
<option value="low">LOW</option>
<option value="medium">MEDIUM</option>
<option value="high">HIGH</option>
<option value="critical">CRITICAL</option>
</select>
<input
value={addForm.category}
onChange={e => setAddForm(f => ({ ...f, category: e.target.value }))}
placeholder="category (e.g. deployment)"
className="cc-field"
/>
</div>
<input
value={addForm.title}
onChange={e => setAddForm(f => ({ ...f, title: e.target.value }))}
placeholder="issue title..."
className="cc-field"
/>
<textarea
value={addForm.description}
onChange={e => setAddForm(f => ({ ...f, description: e.target.value }))}
placeholder="description (optional)"
rows={2}
className="cc-field"
style={{ resize: "none", fontFamily: "var(--cc-font-mono)" }}
/>
<div className="cc-form__actions">
<button onClick={handleAdd} className="cc-btn cc-btn--primary">Log Issue</button>
<button onClick={() => setShowAddForm(false)} className="cc-btn cc-btn--ghost">Discard</button>
</div>
</div>
)}
{openItems.length === 0 ? (
<div className="cc-empty cc-rise">
<div className="cc-empty__title">{"// "}QUEUE CLEAR</div>
<div className="cc-empty__sub">No open founder pain items. Add one to track it here.</div>
</div>
) : (
<div style={{ display: "grid", gap: 12 }}>
{openItems.map((item, i) => (
<PainItem
key={item.id}
item={item}
idx={i + 1}
onResolve={handleResolve}
onSnooze={handleSnooze}
/>
))}
</div>
)}
</section>
<section className="cc-section">
<div className="cc-section__head">
<span className="cc-section__serial">{"// "}07</span>
<span className="cc-section__title">QUICK ACCESS</span>
<span className="cc-section__rule" />
<span className="cc-section__count">{QUICK_ACCESS.length}</span>
</div>
<div className="cc-links cc-rise" data-stagger="2">
<Corners />
{QUICK_ACCESS.map((link, i) => (
<a
key={link.href}
href={link.href}
className="cc-link"
>
<span className="cc-link__serial">L.{String(i + 1).padStart(2, "0")}</span>
<span className="cc-link__label">{link.label}</span>
<span className="cc-link__arrow"></span>
</a>
))}
</div>
</section>
</div>
</div>
</div>
</div>
);
}
@@ -45,16 +45,6 @@ export const PALETTE_ENTRIES: PaletteEntry[] = [
iconName: "LayoutDashboard",
keywords: ["home", "overview"],
},
{
id: "page-command-center",
type: "page",
label: "Command Center",
href: "/admin/command-center",
category: "Workspace",
iconName: "Command",
keywords: ["platform", "admin", "ops", "triage"],
},
// ── Operations ─────────────────────────────────────────────────────
{
id: "page-orders",