- OrchestrationSummaryCard: Full dark mode support with CSS variables - InsightsGrid: Replace Tailwind classes with theme-aware CSS variables - All dashboard components now properly adapt to light/dark themes - Skeleton loaders use theme colors for seamless transitions - ProductionTimelineCard filters for today's PENDING/ON_HOLD batches All dashboard components now use CSS variables exclusively for colors, ensuring proper theme adaptation and consistent user experience across light and dark modes.
122 lines
3.8 KiB
TypeScript
122 lines
3.8 KiB
TypeScript
// ================================================================
|
|
// frontend/src/components/dashboard/InsightsGrid.tsx
|
|
// ================================================================
|
|
/**
|
|
* Insights Grid - Key metrics at a glance
|
|
*
|
|
* 2x2 grid of important metrics: savings, inventory, waste, deliveries.
|
|
* Mobile-first design with large touch targets.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Insights } from '../../api/hooks/newDashboard';
|
|
|
|
interface InsightsGridProps {
|
|
insights: Insights;
|
|
loading?: boolean;
|
|
}
|
|
|
|
const colorConfig = {
|
|
green: {
|
|
bgColor: 'var(--color-success-50)',
|
|
borderColor: 'var(--color-success-200)',
|
|
textColor: 'var(--color-success-800)',
|
|
detailColor: 'var(--color-success-600)',
|
|
},
|
|
amber: {
|
|
bgColor: 'var(--color-warning-50)',
|
|
borderColor: 'var(--color-warning-200)',
|
|
textColor: 'var(--color-warning-900)',
|
|
detailColor: 'var(--color-warning-600)',
|
|
},
|
|
red: {
|
|
bgColor: 'var(--color-error-50)',
|
|
borderColor: 'var(--color-error-200)',
|
|
textColor: 'var(--color-error-900)',
|
|
detailColor: 'var(--color-error-600)',
|
|
},
|
|
};
|
|
|
|
function InsightCard({
|
|
label,
|
|
value,
|
|
detail,
|
|
color,
|
|
}: {
|
|
label: string;
|
|
value: string;
|
|
detail: string;
|
|
color: 'green' | 'amber' | 'red';
|
|
}) {
|
|
const config = colorConfig[color];
|
|
|
|
return (
|
|
<div
|
|
className="border-2 rounded-xl p-4 md:p-6 transition-all duration-200 hover:shadow-lg cursor-pointer"
|
|
style={{
|
|
backgroundColor: config.bgColor,
|
|
borderColor: config.borderColor,
|
|
}}
|
|
>
|
|
{/* Label */}
|
|
<div className="text-sm md:text-base font-bold mb-2" style={{ color: 'var(--text-primary)' }}>{label}</div>
|
|
|
|
{/* Value */}
|
|
<div className="text-xl md:text-2xl font-bold mb-1" style={{ color: config.textColor }}>{value}</div>
|
|
|
|
{/* Detail */}
|
|
<div className="text-sm font-medium" style={{ color: config.detailColor }}>{detail}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function InsightsGrid({ insights, loading }: InsightsGridProps) {
|
|
if (loading) {
|
|
return (
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
{[1, 2, 3, 4].map((i) => (
|
|
<div key={i} className="animate-pulse rounded-xl p-6" style={{ backgroundColor: 'var(--bg-tertiary)' }}>
|
|
<div className="h-4 rounded w-1/2 mb-3" style={{ backgroundColor: 'var(--bg-quaternary)' }}></div>
|
|
<div className="h-8 rounded w-3/4 mb-2" style={{ backgroundColor: 'var(--bg-quaternary)' }}></div>
|
|
<div className="h-4 rounded w-2/3" style={{ backgroundColor: 'var(--bg-quaternary)' }}></div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Guard against undefined values
|
|
if (!insights || !insights.savings || !insights.inventory || !insights.waste || !insights.deliveries) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<InsightCard
|
|
label={insights.savings?.label || 'Savings'}
|
|
value={insights.savings?.value || '€0'}
|
|
detail={insights.savings?.detail || 'This week'}
|
|
color={insights.savings?.color || 'green'}
|
|
/>
|
|
<InsightCard
|
|
label={insights.inventory?.label || 'Inventory'}
|
|
value={insights.inventory?.value || '0%'}
|
|
detail={insights.inventory?.detail || 'Status'}
|
|
color={insights.inventory?.color || 'green'}
|
|
/>
|
|
<InsightCard
|
|
label={insights.waste?.label || 'Waste'}
|
|
value={insights.waste?.value || '0%'}
|
|
detail={insights.waste?.detail || 'Reduction'}
|
|
color={insights.waste?.color || 'green'}
|
|
/>
|
|
<InsightCard
|
|
label={insights.deliveries?.label || 'Deliveries'}
|
|
value={insights.deliveries?.value || '0%'}
|
|
detail={insights.deliveries?.detail || 'On-time'}
|
|
color={insights.deliveries?.color || 'green'}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|