Files
FRASA-CAS/apps/dashboards/src/components/comunes.tsx
Consult AS Technology c77b4c0628 feat(mejoras): 14 mejoras al CRM Frasa
Fase 1 - UI: dark mode, skeletons, toasts
Fase 2 - Filtros: avanzados Mi día, búsqueda global Ctrl+K
Fase 3 - Datos: export Excel, notas apartados, auditoría
Fase 4 - Dashboard: gráficas vendedor + métricas uso
Fase 5 - Responsive: tablets optimizadas
Fase 6 - PWA: IndexedDB offline, push notifications

Backend: 3 tablas nuevas, 6 services, 6 endpoints nuevos
721 API tests + fronts verdes.
2026-09-07 06:04:49 +00:00

39 lines
1.4 KiB
TypeScript

// Piezas visuales compartidas por las vistas del tablero (NovaSpark)
import type { ReactNode } from 'react'
/**
* Acciones que cada vista del tablero expone al header de DashboardPage:
* el botón "Actualizar" vive en el header sticky y dispara la recarga de la
* vista activa (sin cambiar fuentes de datos ni consultas).
*/
export type AccionesTablero = { actualizar: () => void; cargando: boolean }
export function EstadoVacio({ mensaje }: { mensaje: string }) {
return (
<div className="flex h-64 items-center justify-center rounded-xl border border-dashed border-[#E5E7EB] bg-white dark:border-[#334155] dark:bg-[#1E293B]">
<p className="text-xs font-medium uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">{mensaje}</p>
</div>
)
}
export function TituloSeccion({ children }: { children: string }) {
return <h2 className="mb-4 text-xs font-semibold uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">{children}</h2>
}
/** Tarjeta contenedora de gráficas: título interno + padding consistente. */
export function TarjetaGrafica({
titulo,
children,
}: {
titulo: string
children: ReactNode
}) {
return (
<div className="rounded-xl border border-[#E5E7EB] bg-white p-5 dark:border-[#1E293B] dark:bg-[#1E293B] shadow-sm">
<h3 className="mb-4 text-xs font-semibold uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">{titulo}</h3>
{children}
</div>
)
}