import React, { useState, useEffect, useMemo } from 'react'; import { supabaseData } from '../services/supabaseClient'; import { BarChart, Bar, Cell, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer, CartesianGrid } from 'recharts'; import NavBar from '../components/NavBar'; const CHART_PALETTE = ['#6CC24A', '#4F758B', '#A4D65E', '#5B7F95', '#C4D600', '#6B8FA3', '#3E6B8A', '#8FBF5A']; export default function DashboardCarnet() { const [rawData, setRawData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filtroDepartamento, setFiltroDepartamento] = useState(''); const [filtroPosicion, setFiltroPosicion] = useState(''); const [filtroPais, setFiltroPais] = useState(''); const [filtroDivision, setFiltroDivision] = useState(''); useEffect(() => { fetchData(); }, []); // Helper para obtener valores únicos ordenados de una columna (obtiene todos los valores para la lista del filtro) const opcionesUnicas = (campo) => [ ...new Set( rawData .map(item => (item?.[campo] ?? '').toString().trim()) .filter(v => v !== '') ), ].sort((a, b) => a.localeCompare(b, 'es')); const departamentos = useMemo(() => opcionesUnicas('departamento'), [rawData]); const posiciones = useMemo(() => opcionesUnicas('posicion'), [rawData]); const paises = useMemo(() => opcionesUnicas('pais'), [rawData]); const divisiones = useMemo(() => opcionesUnicas('division'), [rawData]); const fetchData = async () => { setLoading(true); setError(null); console.log('[DashboardCarnet] Iniciando fetch...'); const { data, error: fetchError } = await supabaseData .from('carnet_empleados_creados_glm') .select('*') .order('created_at', { ascending: false }); if (fetchError) { console.error('[DashboardCarnet] Error de Supabase:', { message: fetchError.message, details: fetchError.details, hint: fetchError.hint, code: fetchError.code, }); setError(fetchError.message || 'Error al cargar los datos de carnets.'); } else { console.log('[DashboardCarnet] Datos recibidos:', data?.length ?? 0, 'registros'); setRawData(data ?? []); } setLoading(false); }; const datosFiltrados = rawData.filter(item => { const matchDepartamento = !filtroDepartamento || (item?.departamento ?? '').toString().trim() === filtroDepartamento; const matchPosicion = !filtroPosicion || (item?.posicion ?? '').toString().trim() === filtroPosicion; const matchPais = !filtroPais || (item?.pais ?? '').toString().trim() === filtroPais; const matchDivision = !filtroDivision || (item?.division ?? '').toString().trim() === filtroDivision; return matchDepartamento && matchPosicion && matchPais && matchDivision; }); const totalCarnets = datosFiltrados.length; const limpiarFiltros = () => { setFiltroDepartamento(''); setFiltroPosicion(''); setFiltroPais(''); setFiltroDivision(''); }; const hayFiltrosActivos = filtroDepartamento || filtroPosicion || filtroPais || filtroDivision; const conteoPorDivision = datosFiltrados.reduce((acc, curr) => { const division = (curr.division || 'Sin división').toString().trim() || 'Sin división'; acc[division] = (acc[division] || 0) + 1; return acc; }, {}); const chartDataDivision = Object.keys(conteoPorDivision).map((division, index) => ({ name: division, value: conteoPorDivision[division], fill: CHART_PALETTE[index % CHART_PALETTE.length] })); if (loading) return (
Cargando datos...
{error}
Revisa la consola del navegador (F12) para más detalles.
Conteo de carnets creados por división
{totalCarnets}
{divisiones.length}
distintas en el histórico