Feat Tabla Resumen Nacional
This commit is contained in:
		| @@ -0,0 +1,81 @@ | ||||
| /* src/components/widgets/ResumenNacionalWidget.module.css */ | ||||
| .widgetContainer { | ||||
|   font-family: sans-serif; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 8px; | ||||
|   padding: 1.5rem; | ||||
|   max-width: 1000px; | ||||
|   margin: 2rem auto; | ||||
| } | ||||
|  | ||||
| .header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   padding-bottom: 1rem; | ||||
|   margin-bottom: 1rem; | ||||
|   border-bottom: 1px solid #eee; | ||||
| } | ||||
|  | ||||
| .header h3 { | ||||
|   margin: 0; | ||||
|   font-size: 1.5rem; | ||||
| } | ||||
|  | ||||
| .categoriaSelector { | ||||
|   min-width: 280px; | ||||
| } | ||||
|  | ||||
| .listaProvincias { | ||||
|   list-style: none; | ||||
|   padding: 0; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .provinciaItem { | ||||
|   padding: 1rem 0; | ||||
|   border-bottom: 1px solid #eee; | ||||
| } | ||||
|  | ||||
| .provinciaItem:last-child { | ||||
|   border-bottom: none; | ||||
| } | ||||
|  | ||||
| .provinciaHeader { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: baseline; | ||||
|   margin-bottom: 0.5rem; | ||||
| } | ||||
|  | ||||
| .provinciaNombre { | ||||
|   font-weight: bold; | ||||
|   font-size: 1.1rem; | ||||
|   text-transform: uppercase; | ||||
| } | ||||
|  | ||||
| .provinciaEscrutado { | ||||
|   font-size: 0.8rem; | ||||
|   color: #555; | ||||
|   font-weight: 500; | ||||
| } | ||||
|  | ||||
| .resultadosLista { | ||||
|   list-style: none; | ||||
|   padding: 0; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .resultadoItem { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   padding: 0.25rem 0; | ||||
| } | ||||
|  | ||||
| .partidoNombre { | ||||
|   color: #333; | ||||
| } | ||||
|  | ||||
| .partidoPorcentaje { | ||||
|   font-weight: bold; | ||||
| } | ||||
| @@ -0,0 +1,61 @@ | ||||
| // src/components/widgets/ResumenNacionalWidget.tsx | ||||
| import { useState } from 'react'; | ||||
| import { useQuery } from '@tanstack/react-query'; | ||||
| import Select from 'react-select'; | ||||
| import { getResumenNacionalPorProvincia } from '../../../apiService'; | ||||
| import styles from './ResumenNacionalWidget.module.css'; | ||||
|  | ||||
| const ELECCION_ID = 2; // Exclusivo para elecciones nacionales | ||||
| const CATEGORIAS_NACIONALES = [ | ||||
|   { value: 3, label: 'Diputados Nacionales' }, | ||||
|   { value: 2, label: 'Senadores Nacionales' }, | ||||
| ]; | ||||
|  | ||||
| export const ResumenNacionalWidget = () => { | ||||
|   const [categoria, setCategoria] = useState(CATEGORIAS_NACIONALES[0]); | ||||
|  | ||||
|   const { data, isLoading, error } = useQuery({ | ||||
|     queryKey: ['resumenNacional', ELECCION_ID, categoria.value], | ||||
|     queryFn: () => getResumenNacionalPorProvincia(ELECCION_ID, categoria.value), | ||||
|     refetchInterval: 60000, | ||||
|   }); | ||||
|  | ||||
|   const formatPercent = (num: number) => `${num.toFixed(2)}%`; | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.widgetContainer}> | ||||
|       <div className={styles.header}> | ||||
|         <h3>{categoria.label}</h3> | ||||
|         <Select | ||||
|           className={styles.categoriaSelector} | ||||
|           options={CATEGORIAS_NACIONALES} | ||||
|           value={categoria} | ||||
|           onChange={(opt) => setCategoria(opt!)} | ||||
|           isSearchable={false} | ||||
|         /> | ||||
|       </div> | ||||
|       {isLoading && <p>Cargando resumen nacional...</p>} | ||||
|       {error && <p style={{ color: 'red' }}>Error al cargar los datos.</p>} | ||||
|       {data && ( | ||||
|         <ul className={styles.listaProvincias}> | ||||
|           {data.map((provincia) => ( | ||||
|             <li key={provincia.provinciaId} className={styles.provinciaItem}> | ||||
|               <div className={styles.provinciaHeader}> | ||||
|                 <span className={styles.provinciaNombre}>{provincia.provinciaNombre}</span> | ||||
|                 <span className={styles.provinciaEscrutado}>ESCR. {formatPercent(provincia.porcentajeEscrutado)}</span> | ||||
|               </div> | ||||
|               <ul className={styles.resultadosLista}> | ||||
|                 {provincia.resultados.map((partido, index) => ( | ||||
|                   <li key={index} className={styles.resultadoItem}> | ||||
|                     <span className={styles.partidoNombre}>{partido.nombre}</span> | ||||
|                     <span className={styles.partidoPorcentaje}>{formatPercent(partido.porcentaje)}</span> | ||||
|                   </li> | ||||
|                 ))} | ||||
|               </ul> | ||||
|             </li> | ||||
|           ))} | ||||
|         </ul> | ||||
|       )} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user