Files
bakery-ia/frontend/src/components/ui/Stats/StatsPresets.ts

237 lines
6.6 KiB
TypeScript
Raw Normal View History

2025-08-30 19:11:15 +02:00
import {
Calendar,
CheckCircle,
Clock,
AlertTriangle,
Zap,
Shield,
TrendingUp,
Package,
Users,
DollarSign,
BarChart3,
Target,
Activity,
Award
} from 'lucide-react';
import { StatsCardProps, StatsCardVariant } from './StatsCard';
// Common formatting functions
export const formatters = {
percentage: (value: string | number): string => `${value}%`,
currency: (value: string | number): string => `${parseFloat(String(value)).toFixed(2)}`,
number: (value: string | number): string => parseFloat(String(value)).toLocaleString('es-ES'),
compact: (value: string | number): string => {
const num = parseFloat(String(value));
if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M`;
if (num >= 1000) return `${(num / 1000).toFixed(1)}K`;
return num.toString();
},
};
// Icon mappings for common stat types
export const statIcons = {
target: Calendar,
completed: CheckCircle,
inProgress: Clock,
pending: AlertTriangle,
efficiency: Zap,
quality: Shield,
growth: TrendingUp,
inventory: Package,
users: Users,
revenue: DollarSign,
analytics: BarChart3,
goals: Target,
activity: Activity,
achievement: Award,
};
// Variant mappings for common stat types
export const statVariants: Record<string, StatsCardVariant> = {
target: 'default',
completed: 'success',
inProgress: 'info',
pending: 'warning',
efficiency: 'purple',
quality: 'success',
error: 'error',
revenue: 'success',
growth: 'success',
decline: 'error',
};
// Predefined stat configurations for common business metrics
export const businessMetrics = {
production: {
dailyTarget: (value: number): StatsCardProps => ({
title: 'Meta Diaria',
value,
icon: statIcons.target,
variant: statVariants.target,
formatValue: formatters.number,
}),
completed: (value: number): StatsCardProps => ({
title: 'Completado',
value,
icon: statIcons.completed,
variant: statVariants.completed,
formatValue: formatters.number,
}),
inProgress: (value: number): StatsCardProps => ({
title: 'En Proceso',
value,
icon: statIcons.inProgress,
variant: statVariants.inProgress,
formatValue: formatters.number,
}),
pending: (value: number): StatsCardProps => ({
title: 'Pendiente',
value,
icon: statIcons.pending,
variant: statVariants.pending,
formatValue: formatters.number,
}),
efficiency: (value: number): StatsCardProps => ({
title: 'Eficiencia',
value,
icon: statIcons.efficiency,
variant: statVariants.efficiency,
formatValue: formatters.percentage,
}),
quality: (value: number): StatsCardProps => ({
title: 'Calidad',
value,
icon: statIcons.quality,
variant: statVariants.quality,
formatValue: formatters.percentage,
}),
},
sales: {
revenue: (value: number, trend?: { value: number; direction: 'up' | 'down' | 'neutral'; label?: string }): StatsCardProps => ({
title: 'Ingresos',
value,
icon: statIcons.revenue,
variant: statVariants.revenue,
formatValue: formatters.currency,
trend,
}),
orders: (value: number, trend?: { value: number; direction: 'up' | 'down' | 'neutral'; label?: string }): StatsCardProps => ({
title: 'Pedidos',
value,
icon: statIcons.analytics,
variant: statVariants.target,
formatValue: formatters.number,
trend,
}),
customers: (value: number): StatsCardProps => ({
title: 'Clientes',
value,
icon: statIcons.users,
variant: statVariants.target,
formatValue: formatters.number,
}),
},
inventory: {
totalItems: (value: number): StatsCardProps => ({
title: 'Total Items',
value,
icon: statIcons.inventory,
variant: statVariants.target,
formatValue: formatters.number,
}),
lowStock: (value: number): StatsCardProps => ({
title: 'Stock Bajo',
value,
icon: statIcons.pending,
variant: value > 0 ? statVariants.pending : statVariants.completed,
formatValue: formatters.number,
}),
outOfStock: (value: number): StatsCardProps => ({
title: 'Sin Stock',
value,
icon: statIcons.pending,
variant: value > 0 ? statVariants.error : statVariants.completed,
formatValue: formatters.number,
}),
},
performance: {
growth: (value: number): StatsCardProps => ({
title: 'Crecimiento',
value,
icon: statIcons.growth,
variant: value >= 0 ? statVariants.growth : statVariants.decline,
formatValue: formatters.percentage,
trend: {
value: Math.abs(value),
direction: value >= 0 ? 'up' : 'down',
label: 'vs mes anterior',
},
}),
satisfaction: (value: number): StatsCardProps => ({
title: 'Satisfacción',
value,
icon: statIcons.achievement,
variant: value >= 80 ? statVariants.quality : value >= 60 ? statVariants.pending : statVariants.error,
formatValue: formatters.percentage,
}),
},
};
// Quick preset configurations for common page layouts
export const pagePresets = {
production: (data: {
dailyTarget: number;
completed: number;
inProgress: number;
pending: number;
efficiency: number;
quality: number;
}): StatsCardProps[] => [
businessMetrics.production.dailyTarget(data.dailyTarget),
businessMetrics.production.completed(data.completed),
businessMetrics.production.inProgress(data.inProgress),
businessMetrics.production.pending(data.pending),
businessMetrics.production.efficiency(data.efficiency),
businessMetrics.production.quality(data.quality),
],
sales: (data: {
revenue: number;
revenueGrowth?: number;
orders: number;
ordersGrowth?: number;
customers: number;
}): StatsCardProps[] => [
businessMetrics.sales.revenue(
data.revenue,
data.revenueGrowth ? {
value: data.revenueGrowth,
direction: data.revenueGrowth >= 0 ? 'up' : 'down',
label: '%',
} : undefined
),
businessMetrics.sales.orders(
data.orders,
data.ordersGrowth ? {
value: data.ordersGrowth,
direction: data.ordersGrowth >= 0 ? 'up' : 'down',
label: '%',
} : undefined
),
businessMetrics.sales.customers(data.customers),
],
inventory: (data: {
totalItems: number;
lowStock: number;
outOfStock: number;
}): StatsCardProps[] => [
businessMetrics.inventory.totalItems(data.totalItems),
businessMetrics.inventory.lowStock(data.lowStock),
businessMetrics.inventory.outOfStock(data.outOfStock),
],
};