a11oy / web /src /components /command /ops-center-grid.tsx
betterwithage's picture
sync(space): complete build context — fix BUILD_ERROR (CTO)
518343a verified
Raw
History Blame Contribute Delete
5.9 kB
import {
AlertTriangle,
BarChart2,
Bell,
DollarSign,
GitCommit,
Rocket,
Shield,
Target,
Users,
Zap,
} from 'lucide-react';
import { useLocation } from 'wouter';
import { useOpsBadgeCounts } from '../../hooks/use-ops-badge-counts';
type BadgeKey = 'alerts' | 'slaBreaches' | 'governancePending' | 'costOverBudget';
interface OpsItem {
path: string;
label: string;
description: string;
icon: typeof Bell;
color: string;
badge?: number;
badgeKey?: BadgeKey;
badgeLabel?: string;
badgeColor?: string;
}
const OPS_ITEMS: OpsItem[] = [
{
path: '/alerts',
label: 'Alert Inbox',
description: 'Unified alert inbox with priority ranking, snooze, acknowledge & escalate',
icon: Bell,
color: '#ef4444',
badgeKey: 'alerts',
badgeLabel: 'active',
},
{
path: '/team',
label: 'Team & Users',
description: 'User directory, role-based access, team grouping, SSO configuration',
icon: Users,
color: '#8b7ac8',
},
{
path: '/costs',
label: 'Cost Analytics',
description: 'Resource consumption, API volumes, budget allocation, overage alerts',
icon: DollarSign,
color: '#22c55e',
badgeKey: 'costOverBudget',
badgeLabel: 'over budget',
badgeColor: 'var(--color-high)',
},
{
path: '/changelog',
label: 'Release Feed',
description: 'Auto-generated change log for all apps — deployments, features, fixes',
icon: GitCommit,
color: 'var(--gi-accent-blue)',
},
{
path: '/operations/deployments',
label: 'Deployments',
description: 'Active versions per app, full deployment history, guarded rollback controls',
icon: Rocket,
color: '#8b7ac8',
},
{
path: '/sla',
label: 'SLA Dashboard',
description: 'Cross-domain SLA compliance tracking with breach alerting',
icon: Target,
color: '#f97316',
badgeKey: 'slaBreaches',
badgeLabel: 'breaching',
badgeColor: 'var(--color-critical)',
},
{
path: '/governance',
label: 'Governance',
description: 'Policy creation, approval chains, enforcement tracking, audit trail',
icon: Shield,
color: '#a855f7',
badgeKey: 'governancePending',
badgeLabel: 'needs approval',
badgeColor: 'var(--color-medium)',
},
{
path: '/health',
label: 'Health Score',
description: 'Composite ecosystem health score with dimension breakdown',
icon: BarChart2,
color: '#8b7ac8',
},
{
path: '/digest',
label: 'Daily Digest',
description: 'AI-personalized briefing with role-aware prioritization and quick actions',
icon: Zap,
color: '#f59e0b',
},
];
export function OpsCenterGrid() {
const [, navigate] = useLocation();
const counts = useOpsBadgeCounts();
return (
<div className="flex flex-col gap-4">
<div className="flex items-center justify-between">
<h2
className="text-xs font-bold tracking-widest uppercase"
style={{ color: 'var(--color-fg-muted)' }}
>
Ops Center
</h2>
<span className="text-[10px] font-mono" style={{ color: 'var(--color-fg-muted)' }}>
8 workspaces
</span>
</div>
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
{OPS_ITEMS.map((item) => {
const Icon = item.icon;
const liveBadge = item.badgeKey ? counts[item.badgeKey] : null;
const badgeValue = typeof liveBadge === 'number' ? liveBadge : item.badge;
const showBadge = typeof badgeValue === 'number' && badgeValue > 0;
return (
<button
key={item.path}
onClick={() => navigate(item.path)}
className="relative flex flex-col gap-3 p-4 rounded-xl text-left transition-all hover:scale-[1.02]"
style={{
backgroundColor: 'var(--color-surface-base)',
border: '1px solid var(--color-surface-border)',
}}
>
{showBadge && (
<div
className="absolute top-3 right-3 flex items-center gap-1 px-1.5 py-0.5 rounded-full"
style={{
backgroundColor: `color-mix(in srgb, ${item.badgeColor ?? 'var(--color-critical)'} 15%, transparent)`,
border: `1px solid color-mix(in srgb, ${item.badgeColor ?? 'var(--color-critical)'} 30%, transparent)`,
}}
>
<AlertTriangle
className="w-2.5 h-2.5"
style={{ color: item.badgeColor ?? 'var(--color-critical)' }}
/>
<span
className="text-[9px] font-bold"
style={{ color: item.badgeColor ?? 'var(--color-critical)' }}
>
{badgeValue} {item.badgeLabel}
</span>
</div>
)}
<div
className="w-9 h-9 rounded-lg flex items-center justify-center"
style={{
backgroundColor: `color-mix(in srgb, ${item.color} 12%, transparent)`,
border: `1px solid color-mix(in srgb, ${item.color} 25%, transparent)`,
}}
>
<Icon className="w-4 h-4" style={{ color: item.color }} />
</div>
<div>
<div
className="text-sm font-bold mb-0.5"
style={{ color: 'var(--color-fg-primary)' }}
>
{item.label}
</div>
<div
className="text-[10px] leading-relaxed"
style={{ color: 'var(--color-fg-muted)' }}
>
{item.description}
</div>
</div>
</button>
);
})}
</div>
</div>
);
}