mirror of
https://github.com/marcogll/AnchorOS.git
synced 2026-03-15 13:24:27 +00:00
🚀 FASE 4 COMPLETADO: Comentarios auditables + Calendario funcional + Gestión staff/recursos
✅ COMENTARIOS AUDITABLES IMPLEMENTADOS: - 80+ archivos con JSDoc completo para auditoría manual - APIs críticas con validaciones business/security/performance - Componentes con reglas de negocio documentadas - Funciones core con edge cases y validaciones ✅ CALENDARIO MULTI-COLUMNA FUNCIONAL (95%): - Drag & drop con reprogramación automática - Filtros por sucursal/staff, tiempo real - Indicadores de conflictos y disponibilidad - APIs completas con validaciones de colisión ✅ GESTIÓN OPERATIVA COMPLETA: - CRUD staff: APIs + componente con validaciones - CRUD recursos: APIs + componente con disponibilidad - Autenticación completa con middleware seguro - Auditoría completa en todas las operaciones ✅ DOCUMENTACIÓN ACTUALIZADA: - TASKS.md: FASE 4 95% completado - README.md: Estado actual y funcionalidades - API.md: 40+ endpoints documentados ✅ SEGURIDAD Y VALIDACIONES: - RLS policies documentadas en comentarios - Business rules validadas manualmente - Performance optimizations anotadas - Error handling completo Próximos: Nómina/POS/CRM avanzado (FASE 4 final)
This commit is contained in:
83
components/ui/stats-card.tsx
Normal file
83
components/ui/stats-card.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import * as React from "react"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { ArrowUp, ArrowDown, Minus } from "lucide-react"
|
||||
|
||||
interface StatsCardProps {
|
||||
icon: React.ReactNode
|
||||
title: string
|
||||
value: string | number
|
||||
trend?: {
|
||||
value: number
|
||||
isPositive: boolean
|
||||
}
|
||||
className?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* StatsCard component for displaying key metrics in the dashboard.
|
||||
* @param {React.ReactNode} icon - Icon component to display
|
||||
* @param {string} title - Title of the metric
|
||||
* @param {string|number} value - Value to display
|
||||
* @param {Object} trend - Optional trend information with value and isPositive flag
|
||||
* @param {string} className - Optional additional CSS classes
|
||||
*/
|
||||
export function StatsCard({ icon, title, value, trend, className }: StatsCardProps) {
|
||||
return (
|
||||
<Card
|
||||
className={cn(
|
||||
"p-6 transition-all hover:shadow-lg",
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: 'var(--ivory-cream)',
|
||||
border: '1px solid var(--mocha-taupe)',
|
||||
borderRadius: 'var(--radius-lg)'
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span
|
||||
className="text-sm font-medium"
|
||||
style={{ color: 'var(--charcoal-brown)', opacity: 0.8 }}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className="text-3xl font-bold"
|
||||
style={{ color: 'var(--deep-earth)' }}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
{trend && (
|
||||
<div className="flex items-center gap-1 text-xs">
|
||||
{trend.value === 0 ? (
|
||||
<Minus className="h-3 w-3" style={{ color: 'var(--charcoal-brown)' }} />
|
||||
) : trend.isPositive ? (
|
||||
<ArrowUp className="h-3 w-3" style={{ color: 'var(--forest-green)' }} />
|
||||
) : (
|
||||
<ArrowDown className="h-3 w-3" style={{ color: 'var(--brick-red)' }} />
|
||||
)}
|
||||
<span
|
||||
className={cn(
|
||||
"font-medium",
|
||||
trend.value === 0 && "text-gray-500",
|
||||
trend.isPositive && trend.value > 0 && "text-green-600",
|
||||
!trend.isPositive && trend.value > 0 && "text-red-600"
|
||||
)}
|
||||
>
|
||||
{trend.value}%
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="flex h-12 w-12 items-center justify-center rounded-lg"
|
||||
style={{ backgroundColor: 'var(--sand-beige)' }}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user