Agent-completed splits committed after agents hit rate limits before committing their work. All 4 pages now under 500 LOC: - consent-management: 1303 -> 193 LOC (+ 7 _components, _hooks, _data, _types) - control-library: 1210 -> 298 LOC (+ _components, _types) - incidents: 1150 -> 373 LOC (+ _components) - training: 1127 -> 366 LOC (+ _components) Verification: next build clean (142 pages generated). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
'use client'
|
|
|
|
import React from 'react'
|
|
|
|
export function StatCard({
|
|
label,
|
|
value,
|
|
color = 'gray',
|
|
icon,
|
|
trend
|
|
}: {
|
|
label: string
|
|
value: number | string
|
|
color?: 'gray' | 'blue' | 'yellow' | 'red' | 'green' | 'purple' | 'orange'
|
|
icon?: React.ReactNode
|
|
trend?: { value: number; label: string }
|
|
}) {
|
|
const colorClasses: Record<string, string> = {
|
|
gray: 'border-gray-200 text-gray-900',
|
|
blue: 'border-blue-200 text-blue-600',
|
|
yellow: 'border-yellow-200 text-yellow-600',
|
|
red: 'border-red-200 text-red-600',
|
|
green: 'border-green-200 text-green-600',
|
|
purple: 'border-purple-200 text-purple-600',
|
|
orange: 'border-orange-200 text-orange-600'
|
|
}
|
|
|
|
return (
|
|
<div className={`bg-white rounded-xl border ${colorClasses[color]} p-6`}>
|
|
<div className="flex items-start justify-between">
|
|
<div>
|
|
<div className={`text-sm ${color === 'gray' ? 'text-gray-500' : ''}`}>
|
|
{label}
|
|
</div>
|
|
<div className={`text-3xl font-bold mt-1 ${colorClasses[color].split(' ')[1]}`}>
|
|
{value}
|
|
</div>
|
|
{trend && (
|
|
<div className={`text-xs mt-1 ${trend.value >= 0 ? 'text-green-600' : 'text-red-600'}`}>
|
|
{trend.value >= 0 ? '+' : ''}{trend.value} {trend.label}
|
|
</div>
|
|
)}
|
|
</div>
|
|
{icon && (
|
|
<div className="w-10 h-10 rounded-lg flex items-center justify-center bg-gray-50">
|
|
{icon}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|