67 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // src/components/TickerWidget.tsx
 | |
| import { useState, useEffect } from 'react';
 | |
| import { getResumenProvincial } from '../apiService';
 | |
| import type { ResumenProvincial } from '../types';
 | |
| import './TickerWidget.css';
 | |
| 
 | |
| const formatPercent = (num: number) => `${num.toFixed(2).replace('.', ',')}%`;
 | |
| const NIVO_COLORS = [
 | |
|     "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
 | |
|     "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
 | |
| ];
 | |
| 
 | |
| export const TickerWidget = () => {
 | |
|   const [data, setData] = useState<ResumenProvincial | null>(null);
 | |
|   const [loading, setLoading] = useState(true);
 | |
| 
 | |
|   useEffect(() => {
 | |
|     const fetchData = async () => {
 | |
|       try {
 | |
|         const result = await getResumenProvincial();
 | |
|         setData(result);
 | |
|       } catch (error) {
 | |
|         console.error("Error cargando resumen provincial:", error);
 | |
|       } finally {
 | |
|         setLoading(false);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     fetchData(); // Carga inicial
 | |
|     const intervalId = setInterval(fetchData, 30000); // Actualiza cada 30 segundos
 | |
| 
 | |
|     return () => clearInterval(intervalId); // Limpia el intervalo al desmontar el componente
 | |
|   }, []);
 | |
| 
 | |
|   if (loading) {
 | |
|     return <div className="ticker-container loading">Cargando resultados provinciales...</div>;
 | |
|   }
 | |
| 
 | |
|   if (!data) {
 | |
|     return <div className="ticker-container error">No se pudieron cargar los datos.</div>;
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <div className="ticker-container">
 | |
|       <div className="ticker-header">
 | |
|         <h3>{data.provinciaNombre}</h3>
 | |
|         <div className="ticker-stats">
 | |
|           <span>Mesas Escrutadas: <strong>{formatPercent(data.porcentajeEscrutado)}</strong></span>
 | |
|           <span>Participación: <strong>{formatPercent(data.porcentajeParticipacion)}</strong></span>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div className="ticker-results">
 | |
|         {data.resultados.slice(0, 3).map((partido, index) => (
 | |
|           <div key={`${partido.nombre}-${index}`} className="ticker-party"> {/* <-- CAMBIO AQUÍ */}
 | |
|             <div className="party-info">
 | |
|               <span className="party-name">{partido.nombre}</span>
 | |
|               <span className="party-percent">{formatPercent(partido.porcentaje)}</span>
 | |
|             </div>
 | |
|             <div className="party-bar-background">
 | |
|               <div className="party-bar-foreground" style={{ width: `${partido.porcentaje}%`, backgroundColor: NIVO_COLORS[index % NIVO_COLORS.length] }}></div>
 | |
|             </div>
 | |
|           </div>
 | |
|         ))}
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| }; |