111 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // src/features/legislativas/nacionales/components/ProvinciaCard.tsx
 | |
| import type { ResumenProvincia, CategoriaResumen } from '../../../../types/types';
 | |
| import { MiniMapaSvg } from './MiniMapaSvg';
 | |
| import { ImageWithFallback } from '../../../../components/common/ImageWithFallback';
 | |
| import { assetBaseUrl } from '../../../../apiService';
 | |
| 
 | |
| interface CategoriaDisplayProps {
 | |
|     categoria: CategoriaResumen;
 | |
|     mostrarBancas?: boolean;
 | |
| }
 | |
| 
 | |
| interface ProvinciaCardProps {
 | |
|     data: ResumenProvincia;
 | |
|     mostrarBancas?: boolean;
 | |
| }
 | |
| 
 | |
| const formatNumber = (num: number) => num.toLocaleString('es-AR');
 | |
| const formatPercent = (num: number) => `${num.toFixed(2).replace('.', ',')}%`;
 | |
| 
 | |
| const CategoriaDisplay = ({ categoria, mostrarBancas }: CategoriaDisplayProps) => {
 | |
|     return (
 | |
|         <div className="categoria-bloque">
 | |
|             <h4 className="categoria-titulo">{categoria.categoriaNombre}</h4>
 | |
| 
 | |
|             {categoria.resultados.map(res => (
 | |
|                 <div 
 | |
|                     key={res.agrupacionId} 
 | |
|                     className="candidato-row"
 | |
|                     style={{ borderLeftColor: res.color || '#ccc' }}
 | |
|                 >
 | |
|                     {/* --- INICIO DE LA MODIFICACIÓN --- */}
 | |
|                     <div className="candidato-foto-wrapper" style={{ backgroundColor: res.color || '#e9ecef' }}>
 | |
|                         <ImageWithFallback
 | |
|                             src={res.fotoUrl ?? undefined}
 | |
|                             fallbackSrc={`${assetBaseUrl}/default-avatar.png`}
 | |
|                             alt={res.nombreCandidato ?? res.nombreAgrupacion}
 | |
|                             className="candidato-foto"
 | |
|                         />
 | |
|                     </div>
 | |
|                     {/* --- FIN DE LA MODIFICACIÓN --- */}
 | |
| 
 | |
|                     <div className="candidato-data">
 | |
|                         {res.nombreCandidato ? (
 | |
|                             <>
 | |
|                                 <span className="candidato-nombre">{res.nombreCandidato}</span>
 | |
|                                 <span className="candidato-partido">{res.nombreCortoAgrupacion || res.nombreAgrupacion}</span>
 | |
|                             </>
 | |
|                         ) : (
 | |
|                             <span className="candidato-nombre">{res.nombreCortoAgrupacion || res.nombreAgrupacion}</span>
 | |
|                         )}
 | |
|                         <div className="progress-bar-container">
 | |
|                             <div className="progress-bar" style={{ width: `${res.porcentaje}%`, backgroundColor: res.color || '#ccc' }} />
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div className="candidato-stats">
 | |
|                         <span className="stats-percent">{formatPercent(res.porcentaje)}</span>
 | |
|                         <span className="stats-votos">{formatNumber(res.votos)} votos</span>
 | |
|                     </div>
 | |
| 
 | |
|                     {mostrarBancas && (
 | |
|                         <div className="stats-bancas">
 | |
|                             +{res.bancasObtenidas}
 | |
|                             <span>Bancas</span>
 | |
|                         </div>
 | |
|                     )}
 | |
|                 </div>
 | |
|             ))}
 | |
| 
 | |
|             <footer className="card-footer">
 | |
|                 <div>
 | |
|                     <span>Participación</span>
 | |
|                     <strong>{formatPercent(categoria.estadoRecuento?.participacionPorcentaje ?? 0)}</strong>
 | |
|                 </div>
 | |
|                 <div>
 | |
|                     <span>Mesas escrutadas</span>
 | |
|                     <strong>{formatPercent(categoria.estadoRecuento?.mesasTotalizadasPorcentaje ?? 0)}</strong>
 | |
|                 </div>
 | |
|                 <div>
 | |
|                     <span>Votos totales</span>
 | |
|                     <strong>{formatNumber(categoria.estadoRecuento?.cantidadVotantes ?? 0)}</strong>
 | |
|                 </div>
 | |
|             </footer>
 | |
|         </div>
 | |
|     );
 | |
| };
 | |
| 
 | |
| export const ProvinciaCard = ({ data, mostrarBancas }: ProvinciaCardProps) => {
 | |
|     const colorGanador = data.categorias[0]?.resultados[0]?.color || '#d1d1d1';
 | |
| 
 | |
|     return (
 | |
|         <div className="provincia-card">
 | |
|             <header className="card-header">
 | |
|                 <div className="header-info">
 | |
|                     <h3 style={{ whiteSpace: 'normal' }}>{data.provinciaNombre}</h3>
 | |
|                 </div>
 | |
|                 <div className="header-map">
 | |
|                     <MiniMapaSvg provinciaNombre={data.provinciaNombre} fillColor={colorGanador} />
 | |
|                 </div>
 | |
|             </header>
 | |
|             <div className="card-body">
 | |
|                 {data.categorias.map(categoria => (
 | |
|                     <CategoriaDisplay
 | |
|                         key={categoria.categoriaId}
 | |
|                         categoria={categoria}
 | |
|                         mostrarBancas={mostrarBancas}
 | |
|                     />
 | |
|                 ))}
 | |
|             </div>
 | |
|         </div>
 | |
|     );
 | |
| }; |