refactor: migrate page components to Design System v4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-22 02:04:16 -04:00
parent fd28921373
commit e4ef904707
58 changed files with 1416 additions and 1416 deletions

View File

@@ -144,7 +144,7 @@ export default function FlowPilotAnalyticsPage() {
if (loading) {
return (
<div className="flex items-center justify-center min-h-[60vh]">
<Loader2 size={24} className="animate-spin text-muted-foreground" />
<Loader2 size={24} className="animate-spin text-[#848b9b]" />
</div>
)
}
@@ -152,7 +152,7 @@ export default function FlowPilotAnalyticsPage() {
if (!dashboard) {
return (
<div className="flex items-center justify-center min-h-[60vh]">
<p className="text-sm text-muted-foreground">Failed to load analytics</p>
<p className="text-sm text-[#848b9b]">Failed to load analytics</p>
</div>
)
}
@@ -165,21 +165,21 @@ export default function FlowPilotAnalyticsPage() {
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="flex items-center gap-3">
<span title="FlowPilot Analytics">
<BarChart3 size={24} className="text-foreground" />
<BarChart3 size={24} className="text-[#e2e5eb]" />
</span>
<h1 className="text-xl sm:text-2xl font-bold font-heading text-foreground">FlowPilot Analytics</h1>
<h1 className="text-xl sm:text-2xl font-bold font-heading text-[#e2e5eb]">FlowPilot Analytics</h1>
</div>
<div className="flex items-center gap-3">
<Link
to="/analytics"
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
className="text-sm text-[#848b9b] hover:text-[#e2e5eb] transition-colors"
>
Team Analytics
</Link>
<select
value={period}
onChange={(e) => setPeriod(e.target.value)}
className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:outline-hidden focus:ring-1 focus:ring-primary/20 [&>option]:bg-[#1a1c21] [&>option]:text-foreground"
className="rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-1.5 text-sm text-[#e2e5eb] focus:outline-hidden focus:ring-1 focus:ring-primary/20 [&>option]:bg-[#1a1c21] [&>option]:text-[#e2e5eb]"
>
{PERIOD_OPTIONS.map((opt) => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
@@ -189,7 +189,7 @@ export default function FlowPilotAnalyticsPage() {
</div>
{/* Tab bar */}
<div className="flex gap-1 border-b border-border overflow-x-auto">
<div className="flex gap-1 border-b border-[#1e2130] overflow-x-auto">
{TABS.map((tab) => (
<button
key={tab.id}
@@ -197,8 +197,8 @@ export default function FlowPilotAnalyticsPage() {
className={cn(
'px-4 py-2 text-sm transition-colors',
activeTab === tab.id
? 'border-b-2 border-primary text-foreground font-medium'
: 'text-muted-foreground hover:text-foreground'
? 'border-b-2 border-primary text-[#e2e5eb] font-medium'
: 'text-[#848b9b] hover:text-[#e2e5eb]'
)}
>
{tab.label}
@@ -246,8 +246,8 @@ export default function FlowPilotAnalyticsPage() {
{/* Second row — Charts */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{/* MTTR Trend */}
<div className="glass-card-static p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-foreground mb-4">
<div className="card-flat p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-[#e2e5eb] mb-4">
MTTR Trend
</h3>
{dashboard.mttr_trend.length > 0 ? (
@@ -284,15 +284,15 @@ export default function FlowPilotAnalyticsPage() {
</AreaChart>
</ResponsiveContainer>
) : (
<div className="flex items-center justify-center h-[220px] text-sm text-muted-foreground">
<div className="flex items-center justify-center h-[220px] text-sm text-[#848b9b]">
No data for this period
</div>
)}
</div>
{/* Domain Breakdown */}
<div className="glass-card-static p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-foreground mb-4">
<div className="card-flat p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-[#e2e5eb] mb-4">
Sessions by Domain
</h3>
{dashboard.sessions_by_domain.length > 0 ? (
@@ -315,7 +315,7 @@ export default function FlowPilotAnalyticsPage() {
</BarChart>
</ResponsiveContainer>
) : (
<div className="flex items-center justify-center h-[220px] text-sm text-muted-foreground">
<div className="flex items-center justify-center h-[220px] text-sm text-[#848b9b]">
No domain data
</div>
)}
@@ -325,8 +325,8 @@ export default function FlowPilotAnalyticsPage() {
{/* Third row — Confidence + Knowledge Coverage */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{/* Confidence Breakdown */}
<div className="glass-card-static p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-foreground mb-4">
<div className="card-flat p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-[#e2e5eb] mb-4">
Confidence Tiers
</h3>
<div className="space-y-3">
@@ -355,32 +355,32 @@ export default function FlowPilotAnalyticsPage() {
</div>
{/* Knowledge Coverage */}
<div className="glass-card-static p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-foreground mb-4">
<div className="card-flat p-3 sm:p-5">
<h3 className="font-heading text-sm font-semibold text-[#e2e5eb] mb-4">
Knowledge Coverage
</h3>
<div className="grid grid-cols-2 gap-3 mb-4">
<div className="rounded-lg bg-card/50 p-3">
<p className="text-xs text-muted-foreground">Total Flows</p>
<p className="text-lg font-semibold text-foreground">{dashboard.knowledge_coverage.total_flows}</p>
<div className="rounded-lg bg-[#14161d]/50 p-3">
<p className="text-xs text-[#848b9b]">Total Flows</p>
<p className="text-lg font-semibold text-[#e2e5eb]">{dashboard.knowledge_coverage.total_flows}</p>
</div>
<div className="rounded-lg bg-card/50 p-3">
<p className="text-xs text-muted-foreground">AI-Generated</p>
<p className="text-lg font-semibold text-gradient-brand">{dashboard.knowledge_coverage.ai_generated_flows}</p>
<div className="rounded-lg bg-[#14161d]/50 p-3">
<p className="text-xs text-[#848b9b]">AI-Generated</p>
<p className="text-lg font-semibold text-[#67e8f9]">{dashboard.knowledge_coverage.ai_generated_flows}</p>
</div>
<div className="rounded-lg bg-card/50 p-3">
<p className="text-xs text-muted-foreground">Pending Review</p>
<div className="rounded-lg bg-[#14161d]/50 p-3">
<p className="text-xs text-[#848b9b]">Pending Review</p>
<p className="text-lg font-semibold text-amber-400">{dashboard.knowledge_coverage.total_proposals_pending}</p>
</div>
<div className="rounded-lg bg-card/50 p-3">
<p className="text-xs text-muted-foreground">Approved This Period</p>
<div className="rounded-lg bg-[#14161d]/50 p-3">
<p className="text-xs text-[#848b9b]">Approved This Period</p>
<p className="text-lg font-semibold text-emerald-400">{dashboard.knowledge_coverage.proposals_approved_this_period}</p>
</div>
</div>
{dashboard.knowledge_coverage.total_proposals_pending > 0 && (
<Link
to="/review-queue"
className="flex items-center gap-2 text-xs text-primary hover:underline"
className="flex items-center gap-2 text-xs text-[#22d3ee] hover:underline"
>
<ArrowUpRight size={12} />
Review {dashboard.knowledge_coverage.total_proposals_pending} pending proposals
@@ -394,7 +394,7 @@ export default function FlowPilotAnalyticsPage() {
<div className="space-y-3">
<div className="flex items-center gap-2 px-1">
<AlertTriangle size={14} className="text-amber-400" />
<h3 className="font-heading text-sm font-semibold text-foreground">
<h3 className="font-heading text-sm font-semibold text-[#e2e5eb]">
Knowledge Gaps ({gaps.gaps.length})
</h3>
</div>
@@ -405,11 +405,11 @@ export default function FlowPilotAnalyticsPage() {
</div>
</div>
) : gaps && (
<div className="glass-card-static p-4 flex items-center gap-3">
<div className="card-flat p-4 flex items-center gap-3">
<CheckCircle2 size={20} className="text-emerald-400 shrink-0" />
<div>
<p className="text-sm text-foreground">No knowledge gaps detected</p>
<p className="text-xs text-muted-foreground">Your flow coverage looks healthy for this period.</p>
<p className="text-sm text-[#e2e5eb]">No knowledge gaps detected</p>
<p className="text-xs text-[#848b9b]">Your flow coverage looks healthy for this period.</p>
</div>
</div>
)}
@@ -422,7 +422,7 @@ export default function FlowPilotAnalyticsPage() {
<ErrorRetry label="coverage data" onRetry={() => { setCoverageError(false); coveragePeriodRef.current = null; setRetryKey((k) => k + 1) }} />
) : coverageLoading ? (
<div className="flex items-center justify-center min-h-[200px]">
<Loader2 size={20} className="animate-spin text-muted-foreground" />
<Loader2 size={20} className="animate-spin text-[#848b9b]" />
</div>
) : coverageData ? (
<CoverageHeatmap data={coverageData} />
@@ -436,7 +436,7 @@ export default function FlowPilotAnalyticsPage() {
<ErrorRetry label="flow quality data" onRetry={() => { setQualityError(false); qualityPeriodRef.current = null; setRetryKey((k) => k + 1) }} />
) : qualityLoading ? (
<div className="flex items-center justify-center min-h-[200px]">
<Loader2 size={20} className="animate-spin text-muted-foreground" />
<Loader2 size={20} className="animate-spin text-[#848b9b]" />
</div>
) : qualityData ? (
<FlowQualityTable data={qualityData} />
@@ -450,7 +450,7 @@ export default function FlowPilotAnalyticsPage() {
<ErrorRetry label="PSA metrics" onRetry={() => { setPsaError(false); psaPeriodRef.current = null; setRetryKey((k) => k + 1) }} />
) : psaLoading ? (
<div className="flex items-center justify-center min-h-[200px]">
<Loader2 size={20} className="animate-spin text-muted-foreground" />
<Loader2 size={20} className="animate-spin text-[#848b9b]" />
</div>
) : psaData ? (
<PsaMetricsPanel data={psaData} />
@@ -475,7 +475,7 @@ function MetricCard({
iconColor: string
}) {
return (
<div className="glass-card-static p-3 sm:p-4">
<div className="card-flat p-3 sm:p-4">
<div className="flex items-center gap-3">
<span
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg"
@@ -484,8 +484,8 @@ function MetricCard({
<Icon size={16} style={{ color: iconColor }} />
</span>
<div>
<p className="font-label text-[0.5625rem] uppercase tracking-wider text-[#5a6170]">{label}</p>
<p className="text-lg font-semibold text-foreground">{value}</p>
<p className="font-sans text-xs text-[0.5625rem] uppercase tracking-wider text-[#5a6170]">{label}</p>
<p className="text-lg font-semibold text-[#e2e5eb]">{value}</p>
</div>
</div>
</div>
@@ -509,12 +509,12 @@ function ConfidenceTierRow({
return (
<div className="space-y-1">
<div className="flex items-center justify-between text-xs">
<span className="text-foreground font-medium">{label}</span>
<span className="text-muted-foreground">
<span className="text-[#e2e5eb] font-medium">{label}</span>
<span className="text-[#848b9b]">
{count} sessions · {rate.toFixed(1)}% resolved
</span>
</div>
<div className="h-2 rounded-full bg-card/80 overflow-hidden">
<div className="h-2 rounded-full bg-[#14161d]/80 overflow-hidden">
<div
className="h-full rounded-full transition-all"
style={{ width: `${pct}%`, background: color }}
@@ -526,12 +526,12 @@ function ConfidenceTierRow({
function ErrorRetry({ label, onRetry }: { label: string; onRetry: () => void }) {
return (
<div className="flex flex-col items-center justify-center py-12 text-muted-foreground">
<div className="flex flex-col items-center justify-center py-12 text-[#848b9b]">
<AlertTriangle size={24} className="mb-2 text-amber-400" />
<p className="text-sm mb-3">Failed to load {label}</p>
<button
onClick={onRetry}
className="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-[10px] bg-[rgba(255,255,255,0.04)] border border-[rgba(255,255,255,0.06)] text-foreground hover:border-[rgba(255,255,255,0.12)] transition-colors"
className="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg bg-[rgba(255,255,255,0.04)] border border-[rgba(255,255,255,0.06)] text-[#e2e5eb] hover:border-[rgba(255,255,255,0.12)] transition-colors"
>
<RotateCcw size={12} />
Retry
@@ -543,17 +543,17 @@ function ErrorRetry({ label, onRetry }: { label: string; onRetry: () => void })
function GapCard({ gap }: { gap: KnowledgeGap }) {
const severityStyle = SEVERITY_STYLES[gap.severity as keyof typeof SEVERITY_STYLES] ?? SEVERITY_STYLES.low
return (
<div className="glass-card-static p-4 space-y-2">
<div className="card-flat p-4 space-y-2">
<div className="flex items-start justify-between gap-2">
<p className="text-sm font-semibold text-foreground">{gap.title}</p>
<span className={`shrink-0 rounded-md border px-1.5 py-0.5 font-label text-[0.5625rem] uppercase tracking-wider ${severityStyle}`}>
<p className="text-sm font-semibold text-[#e2e5eb]">{gap.title}</p>
<span className={`shrink-0 rounded-md border px-1.5 py-0.5 font-sans text-xs text-[0.5625rem] uppercase tracking-wider ${severityStyle}`}>
{gap.severity}
</span>
</div>
<p className="text-xs text-muted-foreground">{gap.description}</p>
<p className="text-xs text-[#848b9b]">{gap.description}</p>
<div className="flex items-start gap-1.5 pt-1">
<Lightbulb size={12} className="text-primary shrink-0 mt-0.5" />
<p className="text-xs text-primary">{gap.suggested_action}</p>
<Lightbulb size={12} className="text-[#22d3ee] shrink-0 mt-0.5" />
<p className="text-xs text-[#22d3ee]">{gap.suggested_action}</p>
</div>
</div>
)