Feat Widgets Cards y Optimización de Consultas
							
								
								
									
										482
									
								
								Elecciones-Web/frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -18,6 +18,8 @@ | ||||
|     "axios": "^1.11.0", | ||||
|     "d3-geo": "^3.1.1", | ||||
|     "d3-shape": "^3.2.0", | ||||
|     "highcharts": "^12.4.0", | ||||
|     "highcharts-react-official": "^3.2.2", | ||||
|     "react": "^19.1.1", | ||||
|     "react-circular-progressbar": "^2.2.0", | ||||
|     "react-dom": "^19.1.1", | ||||
| @@ -26,7 +28,8 @@ | ||||
|     "react-select": "^5.10.2", | ||||
|     "react-simple-maps": "github:ozimmortal/react-simple-maps#feat/react-19-support", | ||||
|     "react-tooltip": "^5.29.1", | ||||
|     "topojson-client": "^3.1.0" | ||||
|     "topojson-client": "^3.1.0", | ||||
|     "vite-plugin-svgr": "^4.5.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@eslint/js": "^9.33.0", | ||||
|   | ||||
| After Width: | Height: | Size: 9.8 KiB | 
| After Width: | Height: | Size: 7.7 KiB | 
							
								
								
									
										23
									
								
								Elecciones-Web/frontend/public/maps/provincias-svg/chaco.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.0 KiB | 
| After Width: | Height: | Size: 12 KiB | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="1.3493201mm" | ||||
|    height="1.6933239mm" | ||||
|    viewBox="0 0 1.3493201 1.6933238" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-103.9813,-147.63758)"> | ||||
|     <path | ||||
|        d="m 105.33062,148.53708 -0.0264,0.0794 -0.1323,0.13229 -0.1852,0.0265 -0.15875,0.15875 -0.21167,0.39687 -0.52917,-0.44979 -0.10583,-0.37042 0.13229,-0.58208 0.34396,-0.29104 0.13229,0.0794 0.10583,0.0529 0.10584,0.0794 0.18521,0.13229 0.0794,0.0794 0.10583,0.15875 0.0794,0.15875 z" | ||||
|        id="ARC" | ||||
|        name="Ciudad de Buenos Aires" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 821 B | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="22.092972mm" | ||||
|    height="36.143562mm" | ||||
|    viewBox="0 0 22.092972 36.143562" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-93.662753,-130.4396)"> | ||||
|     <path | ||||
|        d="m 95.646872,134.9375 1.190625,-0.3175 0.264583,-0.15875 0.47625,-0.50271 0.582083,-0.66146 0.05292,-0.10583 0.02646,-0.13229 -0.15875,-1.45521 0.05292,-0.21167 0.370417,-0.13229 1.5875,-0.39687 1.03188,-0.29105 0.60854,-0.13229 h 0.21167 l 1.08479,0.26459 0.0529,0.0264 v 0.0265 l 0.0265,0.0794 -0.0265,0.15875 v 0.0794 l 0.0265,0.0529 0.0794,0.0529 0.39687,0.23812 0.0265,0.0265 0.0529,0.0794 0.0529,0.0529 0.0265,0.0265 0.34396,0.0529 0.0529,0.0265 0.0265,0.0265 0.0794,0.0529 0.0529,0.0529 0.0529,0.0265 h 0.0529 l 0.3175,0.0265 h 0.10583 l 0.635,-0.10583 0.0794,0.0265 0.39687,0.10583 0.0529,0.0265 0.21167,-0.0529 h 0.0529 l 0.0265,0.0265 0.0265,0.0265 v 0.0265 0.0265 0.0265 l -0.0265,0.18521 v 0.0265 l 0.0265,0.0529 h 0.0529 l 0.1852,0.0265 0.0529,0.0264 0.0529,0.0265 v 0.0265 0.0529 0.10583 l 0.0265,0.0265 0.0264,0.0529 0.1323,0.0264 h 3.12208 l 1.85208,-0.0264 0.89959,0.0529 0.26458,0.15875 0.84667,2.2225 -0.26459,1.66688 0.0265,0.15875 0.0265,0.10583 1.21708,1.34938 0.26459,0.37041 -0.0529,0.37042 -1.40229,5.26521 -0.10584,0.21166 -0.23812,0.21167 -0.21167,0.21167 -0.0794,0.0794 v 0.0794 0.0265 l 0.0794,0.15875 0.0265,0.0265 v 0.0265 0.0529 0.0794 l -0.0265,0.29105 v 0.0794 l 0.0265,0.39688 0.0265,0.0264 v 0.0265 0.0265 l 0.0794,0.13229 0.0529,0.0529 0.0265,0.0265 v 0.0529 0.0529 l -0.0794,0.18521 -0.0529,0.10583 -0.0265,0.10584 -0.0265,0.15875 v 0.52916 l 0.13229,0.15875 0.13229,0.10584 0.15875,0.21166 0.0529,0.0265 0.15875,0.0794 0.10583,0.0794 0.0265,0.0265 0.0265,0.0529 0.15875,0.55562 0.0265,0.10583 0.13229,0.21167 0.39688,0.29104 0.0529,0.0794 0.0794,0.0794 0.0265,0.0529 0.0264,0.13229 0.0529,0.21167 v 0.21166 l 0.0265,0.0265 0.0265,0.0529 0.0265,0.0265 0.0529,0.0529 0.0265,0.0265 0.0265,0.0529 v 0.0794 l -0.0265,0.0529 v 0.0265 0.0529 l -0.0265,0.0529 -0.0265,0.0265 -0.0794,0.10583 v 0.0265 0.0529 l 0.0265,0.0265 h 0.0529 l 0.15875,0.0265 0.0265,0.0265 H 115.2 l 0.0265,0.0265 v 0.0265 l 0.15875,0.29104 0.10583,0.21167 v 0.0529 l 0.0265,0.0265 0.15875,0.10584 0.0265,0.0265 v 0.0529 l 0.0529,0.0794 v 0.0529 0.0529 0.0529 l -0.0264,0.10583 -0.0794,0.15875 -0.0265,0.13229 v 0.39688 0.15875 l -0.0265,0.13229 -0.0265,0.0265 -0.0794,0.15875 -0.18521,0.21166 -0.0794,0.0794 -0.0794,0.0265 -0.0265,0.0265 h -0.0264 l -0.0794,0.0264 h -0.0529 l -0.0794,-0.0264 -0.13229,0.21166 -1.24354,2.01084 -1.66688,2.7252 -2.2225,3.6248 -2.67229,-0.0265 -0.18521,0.23812 -0.0265,1.08479 -0.0265,2.83105 h -3.12208 -2.91041 -3.28084 v -0.0265 -6.87917 l -0.264584,-4.97417 0.02646,-0.0529 0.02646,-0.0794 0.15875,-0.29104 0.02646,-0.0265 v -0.0265 l 0.02646,-0.0264 h 0.05292 l 0.132292,-0.0265 0.02646,-0.0265 0.05292,-0.0265 0.02646,-0.0529 v -0.0264 -0.0529 l -0.05292,-0.13229 v -0.10584 l 0.02646,-0.0794 0.132292,-0.29104 0.02646,-0.0794 v -0.0529 l -0.02646,-0.10584 -0.02646,-0.0794 0.02646,-0.0529 v -0.0529 l 0.211666,-0.39687 0.02646,-0.0529 v -0.0529 -0.23813 l 0.02646,-0.0529 v -0.0529 l 0.07937,-0.13229 0.02646,-0.0529 v -0.0265 -0.10583 -0.0794 -0.0265 l 0.02646,-0.0529 0.07938,-0.0794 0.02646,-0.0265 0.02646,-0.0529 0.02646,-0.0529 0.02646,-0.26458 0.132292,-0.29104 0.02646,-0.18521 0.02646,-0.21167 v -0.0529 l -0.02646,-0.0529 -0.02646,-0.13229 -0.02646,-0.10584 -0.02646,-0.13229 -0.132292,-0.23812 -0.02646,-0.0794 v -0.0529 -0.15875 l 0.02646,-0.15875 v -0.1852 -0.18521 l -0.02646,-0.0794 v -0.0794 h -0.02646 l -0.02646,-0.0265 -0.05292,-0.0265 h -0.02646 -0.02646 l -0.105833,0.0265 -0.555625,0.15875 -0.582084,0.0794 -0.07937,-0.0265 -0.02646,-0.0265 -0.02646,-0.0265 v -0.0529 -0.0529 -0.26459 l -0.02646,-0.0794 v -0.0265 l -0.07937,-0.13229 -0.05292,-0.10584 -0.05292,-0.13229 v -0.0794 -0.0794 -0.10583 -0.0265 l -0.02646,-0.10583 -0.02646,-0.0529 -0.02646,-0.0529 -0.15875,-0.13229 -0.15875,-0.18521 -1.534583,-0.9525 -0.264584,-0.13229 -0.185208,-0.0529 h -0.47625 v -1.69334 l -0.02646,-2.24896 v -1.11125 l 0.05292,-0.39687 0.370417,-1.08479 0.07937,-0.21167 0.105833,-0.3175 0.449792,-1.34937 v -0.10584 l 0.05292,-0.18521 0.132291,-0.44979 0.07937,-0.23812 0.02646,-0.0794 0.105833,-0.18521 0.07937,-0.1852 z" | ||||
|        id="ARX" | ||||
|        name="Córdoba" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.5 KiB | 
| After Width: | Height: | Size: 6.1 KiB | 
| After Width: | Height: | Size: 5.6 KiB | 
| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										23
									
								
								Elecciones-Web/frontend/public/maps/provincias-svg/jujuy.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.5 KiB | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="26.908112mm" | ||||
|    height="29.739168mm" | ||||
|    viewBox="0 0 26.908112 29.739168" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-91.281242,-133.61455)"> | ||||
|     <path | ||||
|        d="m 91.545834,150.99771 v -5.00063 l -0.05292,-3.78354 -0.15875,-0.82021 -0.02646,-0.0794 -0.02646,-0.10584 0.02646,-0.29104 0.05292,-0.44979 0.07937,-0.0794 0.105834,-0.0529 h 6.085416 0.423334 2.434162 3.01625 0.21167 4.89479 0.21167 0.0264 v -1.05833 l 0.0265,-5.66209 h 3.28084 2.91041 3.12208 v 1.82563 1.50812 l -0.0264,3.04271 v 0.23813 2.83104 1.53458 1.53458 2.9898 l 0.0264,3.09562 -0.0264,0.3175 0.0264,3.41313 v 3.88937 l -0.0264,3.51896 -0.47625,-0.0529 -0.21167,-0.0794 -0.15875,-0.15875 -0.71437,-0.50271 -0.18521,-0.0794 -0.10584,-0.13229 -0.13229,-0.23812 -0.0794,-0.0794 -0.0794,-0.0529 -0.21166,-0.1323 -0.37042,-0.0794 -0.10583,-0.0529 -0.47625,-0.58208 -0.0794,-0.0794 -0.26458,-0.0265 -0.10584,-0.0529 -0.39687,-0.26458 -1.77271,-0.68792 h -0.39687 l -1.50813,-0.29104 -0.10583,0.0529 -0.18521,-0.0529 -0.39688,0.0529 -0.13229,-0.10583 h -0.0529 -0.74084 l -0.82021,0.15875 -0.26458,-0.0265 -0.23812,0.10584 h -0.0794 l -0.0794,-0.0265 -0.21167,-0.15875 -0.47625,-0.18521 -0.29104,-0.0529 h -0.15875 l -0.10584,0.0794 -0.0794,0.0794 -0.13229,0.0794 -0.10584,0.0529 h -0.10583 l -0.0529,-0.0265 -0.0529,-0.0529 -0.0529,-0.0529 -0.0794,-0.0265 h -0.23813 -0.0529 l -0.10583,-0.10583 -0.0529,-0.0265 -0.0794,-0.0265 -0.21167,-0.0265 -0.18521,-0.0794 -0.15875,-0.0265 -0.10583,-0.0794 h -0.0529 l -1.40229,-0.18521 -0.74083,0.13229 h -0.23813 l -0.635,-0.18521 h -0.15875 l -0.13229,-0.0529 -0.0529,-0.10584 -0.0529,-0.34396 -0.0529,-0.21166 -0.13229,-0.18521 -0.18521,-0.15875 -0.18521,-0.10583 -0.238117,-0.0529 -0.05292,-0.0265 -0.105833,-0.0794 -0.02646,-0.0265 -0.05292,-0.0265 -0.211667,-0.13229 -0.264583,-0.0265 -0.105834,-0.0529 -0.185208,-0.13229 -0.238125,-0.0529 -0.555625,-0.29104 h -0.05292 l -0.02646,-0.0529 -0.07937,-0.10584 -0.07937,-0.0794 -0.211667,-0.29104 -0.132291,-0.37042 v -0.0794 -0.15875 l -0.02646,-0.10583 -0.05292,-0.10583 -0.132292,-0.0529 h -0.105833 l -0.47625,0.0794 -0.238125,0.15875 -0.15875,0.0529 -0.396875,-0.0529 -0.15875,0.0794 -0.396875,0.0265 -0.211667,-0.10583 -0.185208,-0.18521 -0.15875,-0.21167 -0.291042,-0.635 -0.15875,-0.15875 -0.211667,-0.10583 h -0.05292 l -0.15875,0.0529 h -0.05292 l -0.07937,-0.0794 h -0.05292 l -0.05292,-0.0529 -0.05292,-0.15875 -0.02646,-0.13229 -0.02646,-0.13229 0.02646,-0.34396 0.132291,-0.23812 0.15875,-0.15875 0.370417,-0.26459 0.132292,-0.18521 0.07937,-0.26458 v -0.3175 l -0.07937,-0.21167 -0.132292,-0.23812 -0.15875,-0.21167 -0.15875,-0.13229 -0.238125,-0.13229 z" | ||||
|        id="ARL" | ||||
|        name="La Pampa" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.9 KiB | 
| After Width: | Height: | Size: 7.2 KiB | 
| After Width: | Height: | Size: 8.4 KiB | 
| After Width: | Height: | Size: 7.4 KiB | 
| After Width: | Height: | Size: 9.1 KiB | 
| After Width: | Height: | Size: 7.6 KiB | 
							
								
								
									
										23
									
								
								Elecciones-Web/frontend/public/maps/provincias-svg/salta.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 11 KiB | 
| After Width: | Height: | Size: 8.7 KiB | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="13.838294mm" | ||||
|    height="27.438555mm" | ||||
|    viewBox="0 0 13.838294 27.438555" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-97.895573,-134.6725)"> | ||||
|     <path | ||||
|        d="m 101.54708,134.85812 0.37042,0.0794 0.13229,0.0529 0.15875,0.0794 0.0529,0.0265 h 0.0265 0.0529 0.10584 l 0.10583,-0.0529 0.0529,-0.0265 0.0265,0.0265 0.0529,0.0265 0.13229,0.0794 h 0.0265 l 0.29104,-0.0529 h 0.0529 l 0.0529,0.0265 0.0794,0.0265 0.13229,0.0794 h 0.0529 0.0529 l 0.1852,-0.0529 h 0.0794 l 0.26458,0.0265 0.26459,-0.0265 0.29104,-0.10583 0.21166,-0.13229 0.1323,-0.0529 0.26458,-0.0529 h 0.21167 l 0.26458,0.0529 h 0.0529 l 0.0264,0.0265 0.0794,0.0529 0.0529,0.0265 h 0.0264 l 0.10584,0.0265 h 0.26458 l 0.52917,-0.10583 h 0.47625 l 0.18521,0.0529 0.26458,0.13229 1.53458,0.9525 0.15875,0.18521 0.15875,0.13229 0.0265,0.0529 0.0265,0.0529 0.0265,0.10584 v 0.0264 0.10584 0.0794 0.0794 l 0.0529,0.13229 0.0529,0.10583 0.0794,0.13229 v 0.0265 l 0.0264,0.0794 v 0.26458 0.0529 0.0529 l 0.0265,0.0265 0.0265,0.0265 0.0794,0.0265 0.58208,-0.0794 0.55562,-0.15875 0.10584,-0.0265 h 0.0265 0.0264 l 0.0529,0.0265 0.0265,0.0265 h 0.0265 v 0.0794 l 0.0265,0.0794 v 0.18521 0.18521 l -0.0265,0.15875 v 0.15875 0.0529 l 0.0265,0.0794 0.13229,0.23813 0.0265,0.13229 0.0265,0.10583 0.0265,0.13229 0.0265,0.0529 v 0.0529 l -0.0265,0.21166 -0.0265,0.18521 -0.13229,0.29104 -0.0265,0.26459 -0.0265,0.0529 -0.0265,0.0529 -0.0265,0.0265 -0.0794,0.0794 -0.0264,0.0529 v 0.0265 0.0794 0.10584 0.0264 l -0.0265,0.0529 -0.0794,0.13229 v 0.0529 l -0.0265,0.0529 v 0.23812 0.0529 l -0.0264,0.0529 -0.21167,0.39688 v 0.0529 l -0.0265,0.0529 0.0265,0.0794 0.0265,0.10583 v 0.0529 l -0.0265,0.0794 -0.13229,0.29104 -0.0265,0.0794 v 0.10583 l 0.0529,0.13229 v 0.0529 0.0265 l -0.0265,0.0529 -0.0529,0.0265 -0.0265,0.0265 -0.13229,0.0265 h -0.0529 l -0.0265,0.0265 v 0.0265 l -0.0265,0.0265 -0.15875,0.29104 -0.0265,0.0794 -0.0265,0.0529 0.26458,4.97417 v 6.87916 0.0265 l -0.0265,5.66208 v 1.05834 h -0.0265 -0.21167 -4.89479 -0.21167 -3.01625 l -0.0529,-0.0265 -0.0265,-0.21167 v -0.10583 l 0.0794,-0.3175 0.0265,-0.50271 0.23813,-1.05833 0.0529,-0.68792 0.18521,-0.37042 0.0265,-0.13229 v -0.60854 l 0.0794,-0.42333 v -0.10584 l -0.0794,-0.42333 0.0265,-0.0265 0.0265,-0.0529 0.0265,-0.0794 v -0.0794 l -0.0265,-0.0529 -0.0265,-0.0529 -0.0529,-0.0794 0.10583,-0.39688 V 156.21 l -0.0265,-0.10583 -0.10584,-0.21167 -0.0265,-0.0794 -0.0265,-0.10583 -0.0794,-0.26458 v -0.0794 l 0.0529,-0.34396 -0.0265,-0.13229 -0.13229,-0.50271 -0.66146,-1.29645 -0.23813,-0.29105 -0.0529,-0.10583 -0.0265,-0.13229 -0.13229,-0.42333 -0.0265,-0.58209 -0.0529,-0.13229 -0.0794,-0.0529 -0.0529,-0.10583 0.0794,-0.13229 -0.0794,-0.13229 V 150.495 l -0.0529,-0.15875 v -0.0794 l 0.0794,-0.13229 0.0265,-0.10583 0.0265,-0.0265 h 0.0264 l 0.0794,0.0529 h 0.0265 l 0.0794,-0.10584 0.0265,-0.13229 0.0265,-0.34396 0.0265,-0.21166 v -0.10584 l -0.10584,-0.15875 -0.0264,-0.21166 -0.0529,-0.10584 -0.0794,-0.0529 -0.0794,-0.0529 -0.0794,-0.10583 -0.0529,-0.29104 -0.0529,-0.1323 -0.10583,-0.0794 -0.0794,-0.0794 -0.18521,-0.13229 -0.10583,-0.0794 -0.0529,-0.0794 v -0.13229 l -0.13229,-0.44979 -0.13229,-0.21167 -0.0794,-0.29104 -0.0265,-0.0794 -0.07938,-0.21167 -0.02646,-0.0794 -0.105833,-0.10583 -0.529167,-0.89958 -0.05292,-0.15875 v -0.13229 -0.29105 -0.10583 l -0.132291,-0.3175 v -0.23812 l -0.05292,-0.0529 -0.02646,-0.18521 0.02646,-0.50271 -0.02646,-0.60854 -0.05292,-0.13229 -0.02646,-0.0529 v -0.0794 l 0.02646,-0.13229 v -0.0794 l -0.105833,-0.26458 -0.05292,-0.18521 0.02646,-0.0794 0.105834,-0.0794 v -0.13229 l -0.07937,-0.29104 0.02646,-0.0529 0.02646,-0.18521 0.105834,-0.18521 -0.02646,-0.0794 -0.05292,-0.0794 -0.02646,-0.10583 -0.02646,-0.10583 -0.05292,-0.0529 -0.05292,-0.0529 -0.05292,-0.0794 -0.05292,-0.0529 -0.02646,-0.10583 -0.105833,-0.52917 -0.02646,-0.0794 v -0.10584 l -0.07937,-0.18521 -0.02646,-0.1852 -0.02646,-0.0529 -0.02646,-0.0529 -0.02646,-0.0529 -0.02646,-0.0265 v -0.10584 -0.0529 l -0.05292,-0.0794 -0.05292,-0.0529 -0.132291,-0.10584 -0.132292,-0.58208 -0.02646,-0.29104 v -0.42334 -0.21166 -0.39688 -0.10583 l -0.02646,-0.13229 0.02646,-0.0529 v -0.0794 l 0.07937,-0.29105 0.02646,-0.0265 v -0.0529 l -0.02646,-0.0794 v -0.0529 l -0.02646,-0.0265 v -0.0265 l 0.02646,-0.10583 -0.02646,-0.0529 -0.02646,-0.15875 v -0.0794 -0.0265 -0.0529 l 0.02646,-0.0529 0.02646,-0.0529 0.05292,-0.0529 0.132292,-0.0794 0.238125,0.0529 0.15875,0.0529 h 0.07937 l 0.132292,0.0265 0.449791,-0.0529 0.185209,-0.0529 h 0.05292 0.07937 l 0.105834,0.0265 0.07937,0.0265 0.05292,0.0265 0.05292,0.0794 h 0.02646 l 0.02646,0.0265 h 0.05292 l 0.185209,0.0529 z" | ||||
|        id="ARD" | ||||
|        name="San Luis" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.9 KiB | 
| After Width: | Height: | Size: 12 KiB | 
| After Width: | Height: | Size: 5.8 KiB | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="19.023661mm" | ||||
|    height="28.363354mm" | ||||
|    viewBox="0 0 19.023661 28.363354" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-95.24991,-134.40833)"> | ||||
|     <path | ||||
|        d="m 99.059995,138.29771 0.02646,-0.21167 0.02646,-0.0265 0.185208,-0.39687 0.05292,-0.10584 v -0.0529 -0.21167 l 0.02646,-0.0529 0.02646,-0.10583 1.164167,-2.59292 0.10583,-0.13229 0.21167,0.0265 1.05833,0.34396 0.18521,0.0529 2.88396,0.0529 h 9.02229 l 0.15875,0.50271 0.0794,2.46063 v 0.68791 3.28084 6.27062 1.16417 l -0.3175,2.2225 -0.52917,3.4925 -0.47625,3.04271 -0.26458,1.66687 -0.47625,3.09563 -0.84667,-2.2225 -0.26458,-0.15875 -0.89959,-0.0529 -1.85208,0.0265 h -3.12208 l -0.1323,-0.0265 -0.0264,-0.0529 -0.0265,-0.0265 v -0.10583 -0.0529 -0.0264 l -0.0529,-0.0265 -0.0529,-0.0265 -0.1852,-0.0265 h -0.0529 l -0.0265,-0.0529 v -0.0264 l 0.0265,-0.18521 v -0.0265 -0.0265 -0.0265 l -0.0265,-0.0265 -0.0265,-0.0265 h -0.0529 l -0.21167,0.0529 -0.0529,-0.0265 -0.39687,-0.10583 -0.0794,-0.0265 -0.635,0.10584 h -0.10583 l -0.3175,-0.0265 h -0.0529 l -0.0529,-0.0265 -0.0529,-0.0529 -0.0794,-0.0529 -0.0265,-0.0265 -0.0529,-0.0265 -0.34396,-0.0529 -0.0265,-0.0265 -0.0529,-0.0529 -0.0529,-0.0794 -0.0265,-0.0265 -0.39687,-0.23812 -0.0794,-0.0529 -0.0265,-0.0529 v -0.0794 l 0.0265,-0.15875 -0.0265,-0.0794 v -0.0265 l -0.0529,-0.0265 -1.08479,-0.26458 h -0.21167 l -0.608543,0.13229 -1.031875,0.29104 -1.5875,0.39687 -0.132292,-0.15875 -0.05292,-0.13229 V 158.67 l -0.05292,-0.13229 -0.370417,-0.635 -0.238125,-0.58208 -0.238125,-1.82563 0.02646,-0.52916 -0.105833,-1.21709 v -0.10583 l -0.02646,-0.0265 -0.02646,-0.0265 -0.105833,-0.10583 -0.211667,-0.13229 h -0.05292 l -0.02646,-0.0265 v -0.0265 l -0.02646,-0.0265 v -0.21166 -0.0529 l 0.02646,-0.0265 0.105834,-0.0529 0.02646,-0.0265 0.05292,-0.13229 0.07937,-0.1323 0.132291,-0.13229 0.07937,-0.10583 0.05292,-0.15875 0.05292,-0.34396 -0.05292,-0.92604 -0.47625,-2.27542 0.05292,-0.0529 0.07937,-0.0265 h 0.02646 0.05292 l 0.07937,0.0265 h 0.05292 0.07937 l 0.05292,-0.0265 0.05292,-0.0529 0.05292,-0.10583 0.15875,-0.50271 0.05292,-0.0529 0.02646,-0.0265 h 0.07937 0.02646 l -0.02646,-0.0794 -0.132291,-0.3175 -0.238125,-0.55563 v -0.13229 l 0.05292,-0.18521 h 0.05292 l 0.02646,-0.0264 h 0.105834 0.05292 0.02646 0.02646 l 0.02646,-0.0265 0.05292,-0.0265 0.02646,-0.0265 0.02646,-0.0529 0.05292,-0.10583 0.02646,-0.0529 v -0.0529 h -0.02646 l -0.105833,-0.0794 -0.105833,-0.0529 h -0.07937 l -0.105834,-0.0265 -0.07937,-0.0529 -0.02646,-0.0265 0.343958,-0.39687 0.07937,-0.0794 0.264584,-0.3175 0.07937,-0.0794 0.05292,-0.0265 0.132292,-0.0265 0.02646,-0.0265 0.02646,-0.0529 0.132291,-0.37042 0.02646,-0.0265 0.105833,-0.13229 0.15875,-0.44979 0.05292,-0.26459 0.07937,-0.34395 0.02646,-0.0529 0.02646,-0.0529 0.05292,-0.0529 0.02646,-0.0529 h 0.05292 l 0.02646,-0.0265 0.07937,-0.15875 0.185209,-0.76729 0.07937,-0.26458 0.02646,-0.10584 H 98.081 l 0.02646,-0.0265 h 0.07937 0.07937 0.02646 l 0.02646,-0.0529 0.02646,-0.0529 0.15875,-0.58208 0.02646,-0.0529 0.07937,-0.0265 0.343959,0.0529 0.02646,-0.0265 v -0.10583 -0.23813 l -0.02646,-0.44979 -0.105834,-0.635 v -0.0529 l 0.02646,-0.0529 0.185208,-0.66146 0.02646,-0.18521 z" | ||||
|        id="ARG" | ||||
|        name="Santiago del Estero" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.4 KiB | 
| After Width: | Height: | Size: 5.7 KiB | 
| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    width="9.3935156mm" | ||||
|    height="12.197932mm" | ||||
|    viewBox="0 0 9.3935156 12.197932" | ||||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"> | ||||
|   <defs | ||||
|      id="defs1" /> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="translate(-100.01234,-142.34548)"> | ||||
|     <path | ||||
|        d="m 100.77979,143.45708 1.61396,0.26459 0.1852,0.0265 0.0529,-0.0265 0.0265,-0.0265 0.0265,-0.0265 0.0265,-0.0265 0.0264,-0.0529 v -0.0265 -0.0265 -0.0529 -0.21167 -0.0794 l 0.0265,-0.13229 0.0529,-0.10584 v -0.13229 -0.23812 -0.0794 l 0.0265,-0.0794 v -0.0265 l 0.0265,-0.0265 0.0529,-0.0265 h 0.0265 l 0.0265,0.0265 0.13229,0.0529 0.0265,0.0265 0.26458,0.0794 0.13229,-0.0265 h 0.0794 l 0.52917,0.13229 h 0.0794 0.0265 l 0.0265,-0.0264 0.29104,-0.15875 0.15875,-0.0529 0.0529,-0.0265 h 0.0529 l 0.0265,0.0265 h 0.0265 l 0.0265,0.0265 0.0794,0.15875 0.0265,0.15875 0.0529,0.0794 0.0265,0.0794 0.0794,0.0529 1.05833,0.42334 0.0794,-0.0265 h 0.0529 l 0.10583,0.0265 0.10583,0.0794 0.18521,0.0794 0.10583,0.0265 0.0794,0.0265 0.0265,-0.0265 h 0.0794 l 0.0529,-0.0265 h 0.0265 l 0.10583,-0.0794 0.10583,-0.10583 0.0529,-0.0265 0.26458,-0.10583 0.18521,-0.0265 0.29104,0.0794 h 0.0794 l 1.16417,-0.0265 0.0264,0.42333 -0.0264,0.18521 -0.18521,0.66146 -0.0265,0.0529 v 0.0529 l 0.10583,0.635 0.0265,0.44979 v 0.23813 0.10583 l -0.0265,0.0265 -0.34396,-0.0529 -0.0794,0.0265 -0.0265,0.0529 -0.15875,0.58208 -0.0265,0.0529 -0.0265,0.0529 h -0.0265 -0.0794 -0.0794 l -0.0265,0.0265 h -0.0529 l -0.0265,0.10583 -0.0794,0.26459 -0.18521,0.76729 -0.0794,0.15875 -0.0264,0.0265 h -0.0529 l -0.0265,0.0529 -0.0529,0.0529 -0.0264,0.0529 -0.0265,0.0529 -0.0794,0.34396 -0.0529,0.26459 -0.15875,0.44979 -0.10584,0.13229 -0.0265,0.0265 -0.13229,0.37041 -0.0265,0.0529 -0.0264,0.0265 -0.1323,0.0265 -0.0529,0.0265 -0.0794,0.0794 -0.26458,0.3175 -0.0794,0.0794 -0.34395,0.39687 0.0264,0.0265 0.0794,0.0529 0.10583,0.0265 h 0.0794 l 0.10583,0.0529 0.10583,0.0794 h 0.0265 v 0.0529 l -0.0265,0.0529 -0.0529,0.10583 -0.0265,0.0529 -0.0265,0.0265 -0.0529,0.0265 -0.0265,0.0265 h -0.0265 -0.0265 -0.0529 -0.10583 l -0.0265,0.0265 h -0.0529 l -0.0529,0.18521 v 0.13229 l 0.23812,0.55563 0.13229,0.3175 0.0265,0.0794 h -0.0265 -0.0794 l -0.0265,0.0265 -0.0529,0.0529 -0.15875,0.50271 -0.0529,0.10583 -0.0529,0.0529 -0.0529,0.0265 h -0.0794 -0.0529 l -0.0794,-0.0265 h -0.0529 -0.0265 l -0.0794,0.0265 -0.0529,0.0529 -0.15875,0.0794 h -0.10583 -0.0794 l -0.0794,-0.0265 -0.10584,-0.0529 -0.10583,-0.0794 -0.10583,-0.10584 -0.0794,-0.0529 -0.0794,-0.0529 h -0.0529 -0.0529 l -0.44979,0.29104 -0.15875,0.18521 -0.18521,0.13229 -0.0529,0.0265 -0.13229,0.21167 -0.1323,0.29104 -0.0265,0.0529 -0.0794,-0.0264 -0.44979,-0.58209 -0.0529,-0.0794 -0.0794,-0.23813 -0.0529,-0.3175 -0.0529,-0.18521 -0.0264,-0.0265 -0.0529,-0.0529 -0.23813,-0.13229 h -0.10583 l -0.0529,0.0265 -0.0529,0.0265 -0.13229,0.0529 -0.10584,-0.0794 -0.0265,-0.0265 -0.0529,-0.0529 -0.0265,-0.0794 v -0.1323 l -0.0794,-0.23812 -0.0264,-0.0794 -0.0265,-0.0264 -0.0794,-0.0529 -0.0529,-0.0265 -0.0794,-0.0794 -0.0265,-0.0265 -0.0265,-0.0529 -0.0264,-0.0529 -0.0265,-0.26458 -0.0794,-0.15875 -0.18521,-0.89958 0.0529,-0.15875 v -0.0265 l -0.0265,-0.0529 h -0.0265 -0.0264 l -0.15875,-0.0265 -0.39688,-0.23812 -0.0794,-0.0265 -0.18521,-0.0265 -0.10584,-0.0265 -0.10583,-0.0264 -0.0529,-0.0529 -0.0264,-0.0265 v -0.0265 l 0.0264,-0.0265 0.1323,-0.21166 0.10583,-0.23813 0.15875,-0.18521 0.13229,-0.10583 0.10583,-0.13229 0.0265,-0.0529 0.0265,-0.0265 0.0265,-0.0529 0.0265,-0.0794 0.10583,-0.18521 0.13229,-0.1852 0.18521,-0.18521 0.37042,-0.39688 0.15875,-0.23812 0.0529,-0.15875 0.0265,-0.0794 v -0.0794 -0.34396 -0.0794 l 0.0794,-0.37041 v -0.0529 -0.0794 -0.0529 -0.0529 l -0.0265,-0.0265 v -0.0264 l -0.0265,-0.0529 h -0.0265 l -0.0265,-0.0265 -0.23812,-0.13229 -0.37042,-0.29104 -0.18521,-0.18521 -0.0794,-0.0529 -0.13229,-0.0529 -0.13229,-0.0529 h -0.10584 l -0.13229,-0.0529 -0.0794,-0.0529 -0.0794,-0.1323 -0.0265,-0.0794 v -0.0529 -0.10583 l 0.10584,-0.29104 0.13229,-0.26459 0.0265,-0.15875 0.0264,-0.13229 v -0.10583 l 0.0265,-0.13229 0.0265,-0.0794 0.0794,-0.0794 0.0529,-0.0794 0.0529,-0.0265 z" | ||||
|        id="ART" | ||||
|        name="Tucumán" | ||||
|        style="stroke-width:0.264583" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.3 KiB | 
| @@ -1,6 +1,9 @@ | ||||
| // src/apiService.ts | ||||
| import axios from 'axios'; | ||||
| import type { ApiResponseRankingMunicipio, ApiResponseRankingSeccion, ApiResponseTablaDetallada, ProyeccionBancas, MunicipioSimple, TelegramaData, CatalogoItem, CategoriaResumen, ResultadoTicker, ApiResponseResultadosPorSeccion, PanelElectoralDto } from './types/types'; | ||||
| import type { ApiResponseRankingMunicipio, ApiResponseRankingSeccion,  | ||||
|   ApiResponseTablaDetallada, ProyeccionBancas, MunicipioSimple,  | ||||
|   TelegramaData, CatalogoItem, CategoriaResumen, ResultadoTicker,  | ||||
|   ApiResponseResultadosPorSeccion, PanelElectoralDto, ResumenProvincia } from './types/types'; | ||||
|  | ||||
| /** | ||||
|  * URL base para las llamadas a la API. | ||||
| @@ -84,6 +87,32 @@ export interface ResultadoDetalleSeccion { | ||||
|   color: string | null; | ||||
| } | ||||
|  | ||||
| export interface PartidoComposicionNacional { | ||||
|     id: string; | ||||
|     nombre: string; | ||||
|     nombreCorto: string | null; | ||||
|     color: string | null; | ||||
|     bancasFijos: number; | ||||
|     bancasGanadas: number; | ||||
|     bancasTotales: number; | ||||
|     ordenDiputadosNacionales: number | null; | ||||
|     ordenSenadoresNacionales: number | null; | ||||
| } | ||||
|  | ||||
| export interface CamaraComposicionNacional { | ||||
|     camaraNombre: string; | ||||
|     totalBancas: number; | ||||
|     bancasEnJuego: number; | ||||
|     partidos: PartidoComposicionNacional[]; | ||||
|     presidenteBancada: { color: string | null; tipoBanca: 'ganada' | 'previa' | null } | null; | ||||
|     ultimaActualizacion: string; | ||||
| } | ||||
|  | ||||
| export interface ComposicionNacionalData { | ||||
|     diputados: CamaraComposicionNacional; | ||||
|     senadores: CamaraComposicionNacional; | ||||
| } | ||||
|  | ||||
| export const getResumenProvincial = async (eleccionId: number): Promise<CategoriaResumen[]> => { | ||||
|   const response = await apiClient.get(`/elecciones/${eleccionId}/provincia/02`); | ||||
|   return response.data; | ||||
| @@ -221,4 +250,16 @@ export const getPanelElectoral = async (eleccionId: number, ambitoId: string | n | ||||
|          | ||||
|     const { data } = await apiClient.get(url); | ||||
|     return data; | ||||
| }; | ||||
|  | ||||
| export const getComposicionNacional = async (eleccionId: number): Promise<ComposicionNacionalData> => { | ||||
|     const { data } = await apiClient.get(`/elecciones/${eleccionId}/composicion-nacional`); | ||||
|     return data; | ||||
| }; | ||||
|  | ||||
| // 11. Endpoint para el widget de tarjetas nacionales | ||||
| export const getResumenPorProvincia = async (eleccionId: number): Promise<ResumenProvincia[]> => { | ||||
|     // Usamos el cliente público ya que son datos de resultados | ||||
|     const { data } = await apiClient.get(`/elecciones/${eleccionId}/resumen-por-provincia`); | ||||
|     return data; | ||||
| }; | ||||
| @@ -0,0 +1,339 @@ | ||||
| // src/components/common/DiputadosNacionalesLayout.tsx | ||||
| import React from 'react'; | ||||
| import type { PartidoComposicionNacional } from '../../apiService'; | ||||
|  | ||||
| // --- Interfaces Actualizadas --- | ||||
| interface DiputadosNacionalesLayoutProps { | ||||
|   partyData: PartidoComposicionNacional[]; | ||||
|   size?: number; | ||||
|   presidenteBancada?: { color: string | null } | null; // <-- Nueva Prop | ||||
| } | ||||
|  | ||||
| const PRESIDENTE_SEAT_INDEX = 0; // El escaño 'seat-0' es el del presidente | ||||
|  | ||||
| export const DiputadosNacionalesLayout: React.FC<DiputadosNacionalesLayoutProps> = ({ | ||||
|   partyData, | ||||
|   size = 800, | ||||
|   presidenteBancada, // <-- Recibimos la nueva prop | ||||
| }) => { | ||||
|   // --- ARRAY DE 257 ELEMENTOS <circle> ORDENADOS POR ID DE "seat-X" --- | ||||
|   const seatElements = [ | ||||
|     <circle key="seat-0" id="seat-0" r="15.7" cy="639.5" cx="595.3" />, | ||||
|     <circle key="seat-1" id="seat-1" r="15.7" cy="673.1" cx="109.3" />, | ||||
|     <circle key="seat-2" id="seat-2" r="15.7" cy="673.1" cx="161.7" />, | ||||
|     <circle key="seat-3" id="seat-3" r="15.7" cy="673.5" cx="214.3" />, | ||||
|     <circle key="seat-4" id="seat-4" r="15.7" cy="673.2" cx="266.5" />, | ||||
|     <circle key="seat-5" id="seat-5" r="15.7" cy="669.5" cx="319.4" />, | ||||
|     <circle key="seat-6" id="seat-6" r="15.7" cy="660" cx="370.8" />, | ||||
|     <circle key="seat-7" id="seat-7" transform="rotate(-88.1)" r="15.7" cy="77.69" cx="-634.1" />, | ||||
|     <circle key="seat-8" id="seat-8" r="15.7" cy="639" cx="109.3" />, | ||||
|     <circle key="seat-9" id="seat-9" r="15.7" cy="639" cx="161.7" />, | ||||
|     <circle key="seat-10" id="seat-10" r="15.7" cy="639.2" cx="214.3" />, | ||||
|     <circle key="seat-11" id="seat-11" r="15.7" cy="638.8" cx="266.7" />, | ||||
|     <circle key="seat-12" id="seat-12" r="15.7" cy="635.1" cx="319.4" />, | ||||
|     <circle key="seat-13" id="seat-13" r="15.7" cy="625.7" cx="371.7" />, | ||||
|     <circle key="seat-14" id="seat-14" r="15.7" cy="639" cx="424.2" />, | ||||
|     <circle key="seat-15" id="seat-15" transform="rotate(-88.1)" r="15.7" cy="77" cx="-600.18" />, | ||||
|     <circle key="seat-16" id="seat-16" r="15.7" cy="600.9" cx="109.5" />, | ||||
|     <circle key="seat-17" id="seat-17" r="15.7" cy="603.7" cx="162.1" />, | ||||
|     <circle key="seat-18" id="seat-18" r="15.7" cy="598.6" cx="215" />, | ||||
|     <circle key="seat-19" id="seat-19" r="15.7" cy="602.6" cx="267.1" />, | ||||
|     <circle key="seat-20" id="seat-20" transform="rotate(-88.1)" r="15.7" cy="76.57" cx="-562.57" />, | ||||
|     <circle key="seat-21" id="seat-21" r="15.7" cy="566.7" cx="112.2" />, | ||||
|     <circle key="seat-22" id="seat-22" r="15.7" cy="570" cx="164.7" />, | ||||
|     <circle key="seat-23" id="seat-23" r="15.7" cy="564.5" cx="218.2" />, | ||||
|     <circle key="seat-24" id="seat-24" r="15.7" cy="568.6" cx="270.9" />, | ||||
|     <circle key="seat-25" id="seat-25" r="15.7" cy="588" cx="321.1" />, | ||||
|     <circle key="seat-26" id="seat-26" transform="rotate(-88.1)" r="15.7" cy="79.88" cx="-524.51" />, | ||||
|     <circle key="seat-27" id="seat-27" transform="rotate(-5.7)" r="15.7" cy="539.19" cx="65.05" />, | ||||
|     <circle key="seat-28" id="seat-28" r="15.7" cy="535.9" cx="170" />, | ||||
|     <circle key="seat-29" id="seat-29" transform="rotate(-88.1)" r="15.7" cy="86.87" cx="-488.2" />, | ||||
|     <circle key="seat-30" id="seat-30" r="15.7" cy="497.2" cx="125.2" />, | ||||
|     <circle key="seat-31" id="seat-31" r="15.7" cy="502.8" cx="178.2" />, | ||||
|     <circle key="seat-32" id="seat-32" r="15.7" cy="525.1" cx="226.3" />, | ||||
|     <circle key="seat-33" id="seat-33" r="15.7" cy="533.1" cx="278.4" />, | ||||
|     <circle key="seat-34" id="seat-34" r="15.7" cy="554.6" cx="327.1" />, | ||||
|     <circle key="seat-35" id="seat-35" r="15.7" cy="567.9" cx="377.9" />, | ||||
|     <circle key="seat-36" id="seat-36" r="15.7" cy="596.7" cx="426" />, | ||||
|     <circle key="seat-37" id="seat-37" r="15.7" cy="453.8" cx="79.7" />, | ||||
|     <circle key="seat-38" id="seat-38" r="15.7" cy="462" cx="135.7" />, | ||||
|     <circle key="seat-39" id="seat-39" r="15.7" cy="469.3" cx="188.9" />, | ||||
|     <circle key="seat-40" id="seat-40" r="15.7" cy="492.6" cx="236.4" />, | ||||
|     <circle key="seat-41" id="seat-41" r="15.7" cy="500.6" cx="289.8" />, | ||||
|     <circle key="seat-42" id="seat-42" r="15.7" cy="511.6" cx="341.5" />, | ||||
|     <circle key="seat-43" id="seat-43" r="15.7" cy="535" cx="388.9" />, | ||||
|     <circle key="seat-44" id="seat-44" r="15.7" cy="555" cx="437.3" />, | ||||
|     <circle key="seat-45" id="seat-45" r="15.7" cy="419.3" cx="92.8" />, | ||||
|     <circle key="seat-46" id="seat-46" r="15.7" cy="429.8" cx="148.1" />, | ||||
|     <circle key="seat-47" id="seat-47" r="15.7" cy="387.4" cx="106.8" />, | ||||
|     <circle key="seat-48" id="seat-48" transform="rotate(-5.7)" r="15.7" cy="364.72" cx="89.86" />, | ||||
|     <circle key="seat-49" id="seat-49" r="15.7" cy="395.5" cx="164.4" />, | ||||
|     <circle key="seat-50" id="seat-50" r="15.7" cy="437.3" cx="202.4" />, | ||||
|     <circle key="seat-51" id="seat-51" r="15.7" cy="455.4" cx="252.1" />, | ||||
|     <circle key="seat-52" id="seat-52" r="15.7" cy="325.1" cx="144.9" />, | ||||
|     <circle key="seat-53" id="seat-53" r="15.7" cy="365.7" cx="181.3" />, | ||||
|     <circle key="seat-54" id="seat-54" r="15.7" cy="405.1" cx="218.8" />, | ||||
|     <circle key="seat-55" id="seat-55" r="15.7" cy="425.6" cx="267.7" />, | ||||
|     <circle key="seat-56" id="seat-56" r="15.7" cy="464.9" cx="306.5" />, | ||||
|     <circle key="seat-57" id="seat-57" r="15.7" cy="292.1" cx="168.7" />, | ||||
|     <circle key="seat-58" id="seat-58" r="15.7" cy="334.6" cx="202.3" />, | ||||
|     <circle key="seat-59" id="seat-59" r="15.7" cy="376.9" cx="236.7" />, | ||||
|     <circle key="seat-60" id="seat-60" r="15.7" cy="265.1" cx="190.8" />, | ||||
|     <circle key="seat-61" id="seat-61" r="15.7" cy="307.2" cx="224" />, | ||||
|     <circle key="seat-62" id="seat-62" r="15.7" cy="346.9" cx="259.3" />, | ||||
|     <circle key="seat-63" id="seat-63" r="15.7" cy="393" cx="289.6" />, | ||||
|     <circle key="seat-64" id="seat-64" r="15.7" cy="435.9" cx="323.7" />, | ||||
|     <circle key="seat-65" id="seat-65" r="15.7" cy="480.8" cx="357.3" />, | ||||
|     <circle key="seat-66" id="seat-66" r="15.7" cy="236.2" cx="218.1" />, | ||||
|     <circle key="seat-67" id="seat-67" r="15.7" cy="278.6" cx="250" />, | ||||
|     <circle key="seat-68" id="seat-68" r="15.7" cy="320.2" cx="283" />, | ||||
|     <circle key="seat-69" id="seat-69" r="15.7" cy="362" cx="315.5" />, | ||||
|     <circle key="seat-70" id="seat-70" r="15.7" cy="403.8" cx="348.7" />, | ||||
|     <circle key="seat-71" id="seat-71" r="15.7" cy="445.9" cx="381.6" />, | ||||
|     <circle key="seat-72" id="seat-72" r="15.7" cy="489" cx="415.1" />, | ||||
|     <circle key="seat-73" id="seat-73" r="15.7" cy="515.6" cx="460.7" />, | ||||
|     <circle key="seat-74" id="seat-74" r="15.7" cy="485.2" cx="491" />, | ||||
|     <circle key="seat-75" id="seat-75" r="15.7" cy="213.6" cx="243.2" />, | ||||
|     <circle key="seat-76" id="seat-76" r="15.7" cy="254.9" cx="275.3" />, | ||||
|     <circle key="seat-77" id="seat-77" r="15.7" cy="296.4" cx="307.8" />, | ||||
|     <circle key="seat-78" id="seat-78" r="15.7" cy="337.6" cx="339.9" />, | ||||
|     <circle key="seat-79" id="seat-79" r="15.7" cy="379" cx="372.5" />, | ||||
|     <circle key="seat-80" id="seat-80" r="15.7" cy="420.8" cx="405.1" />, | ||||
|     <circle key="seat-81" id="seat-81" r="15.7" cy="462.7" cx="437.2" />, | ||||
|     <circle key="seat-82" id="seat-82" r="15.5" cy="181.8" cx="283.1" />, | ||||
|     <circle key="seat-83" id="seat-83" r="15.5" cy="223.6" cx="315.4" />, | ||||
|     <circle key="seat-84" id="seat-84" r="15.7" cy="262.6" cx="351" />, | ||||
|     <circle key="seat-85" id="seat-85" r="15.5" cy="304.5" cx="382.7" />, | ||||
|     <circle key="seat-86" id="seat-86" r="15.7" cy="339.1" cx="425.3" />, | ||||
|     <circle key="seat-87" id="seat-87" r="15.7" cy="379" cx="461" />, | ||||
|     <circle key="seat-88" id="seat-88" r="15.7" cy="420.4" cx="495.9" />, | ||||
|     <circle key="seat-89" id="seat-89" r="15.7" cy="463.5" cx="528.1" />, | ||||
|     <circle key="seat-90" id="seat-90" r="15.5" cy="160.4" cx="315.7" />, | ||||
|     <circle key="seat-91" id="seat-91" r="15.5" cy="206.2" cx="342.9" />, | ||||
|     <circle key="seat-92" id="seat-92" r="15.7" cy="245.1" cx="379" />, | ||||
|     <circle key="seat-93" id="seat-93" r="15.5" cy="287.4" cx="410.5" />, | ||||
|     <circle key="seat-94" id="seat-94" r="15.7" cy="323.4" cx="455.9" />, | ||||
|     <circle key="seat-95" id="seat-95" transform="rotate(-80.8)" r="15.7" cy="555.93" cx="-274.27" />, | ||||
|     <circle key="seat-96" id="seat-96" r="15.7" cy="407.6" cx="527.7" />, | ||||
|     <circle key="seat-97" id="seat-97" r="15.5" cy="142.7" cx="345.9" />, | ||||
|     <circle key="seat-98" id="seat-98" r="15.5" cy="186.8" cx="375.8" />, | ||||
|     <circle key="seat-99" id="seat-99" r="15.5" cy="125.9" cx="377.8" />, | ||||
|     <circle key="seat-100" id="seat-100" r="15.5" cy="173.7" cx="405.1" />, | ||||
|     <circle key="seat-101" id="seat-101" r="15.7" cy="223" cx="422.9" />, | ||||
|     <circle key="seat-102" id="seat-102" r="15.5" cy="270.9" cx="444.3" />, | ||||
|     <circle key="seat-103" id="seat-103" r="15.5" cy="112" cx="409.4" />, | ||||
|     <circle key="seat-104" id="seat-104" r="15.5" cy="157.7" cx="438.1" />, | ||||
|     <circle key="seat-105" id="seat-105" r="15.7" cy="209" cx="453.9" />, | ||||
|     <circle key="seat-106" id="seat-106" r="15.5" cy="259.6" cx="474.2" />, | ||||
|     <circle key="seat-107" id="seat-107" r="15.7" cy="306.3" cx="499.3" />, | ||||
|     <circle key="seat-108" id="seat-108" r="15.5" cy="100.1" cx="443.4" />, | ||||
|     <circle key="seat-109" id="seat-109" r="15.5" cy="146.7" cx="472.7" />, | ||||
|     <circle key="seat-110" id="seat-110" r="15.7" cy="197.9" cx="497" />, | ||||
|     <circle key="seat-111" id="seat-111" r="15.5" cy="249" cx="508.8" />, | ||||
|     <circle key="seat-112" id="seat-112" r="15.7" cy="298.4" cx="532.7" />, | ||||
|     <circle key="seat-113" id="seat-113" r="15.7" cy="350.8" cx="538.1" />, | ||||
|     <circle key="seat-114" id="seat-114" r="15.5" cy="92.2" cx="477" />, | ||||
|     <circle key="seat-115" id="seat-115" r="15.5" cy="84.4" cx="510" />, | ||||
|     <circle key="seat-116" id="seat-116" transform="rotate(-80.8)" r="15.5" cy="523.04" cx="-55.62" />, | ||||
|     <circle key="seat-117" id="seat-117" r="15.7" cy="190.1" cx="531.6" />, | ||||
|     <circle key="seat-118" id="seat-118" r="15.5" cy="243.4" cx="542.3" />, | ||||
|     <circle key="seat-119" id="seat-119" r="15.5" cy="80.7" cx="544.3" />, | ||||
|     <circle key="seat-120" id="seat-120" r="15.5" cy="136.1" cx="541.9" />, | ||||
|     <circle key="seat-121" id="seat-121" r="15.5" cy="78.5" cx="579" />, | ||||
|     <circle key="seat-122" id="seat-122" r="15.5" cy="135" cx="578.2" />, | ||||
|     <circle key="seat-123" id="seat-123" r="15.7" cy="187.6" cx="577.9" />, | ||||
|     <circle key="seat-124" id="seat-124" r="15.5" cy="240" cx="579" />, | ||||
|     <circle key="seat-125" id="seat-125" r="15.7" cy="292.6" cx="578" />, | ||||
|     <circle key="seat-126" id="seat-126" r="15.7" cy="345.3" cx="578" />, | ||||
|     <circle key="seat-127" id="seat-127" r="15.7" cy="398" cx="577.8" />, | ||||
|     <circle key="seat-128" id="seat-128" r="15.7" cy="451.2" cx="572.2" />, | ||||
|     <circle key="seat-129" id="seat-129" r="15.5" cy="78.5" cx="613.5" />, | ||||
|     <circle key="seat-130" id="seat-130" r="15.5" cy="135" cx="612.3" />, | ||||
|     <circle key="seat-131" id="seat-131" r="15.7" cy="187.6" cx="612.6" />, | ||||
|     <circle key="seat-132" id="seat-132" r="15.5" cy="240" cx="611.5" />, | ||||
|     <circle key="seat-133" id="seat-133" r="15.7" cy="292.6" cx="612.5" />, | ||||
|     <circle key="seat-134" id="seat-134" r="15.7" cy="345.3" cx="612.5" />, | ||||
|     <circle key="seat-135" id="seat-135" r="15.7" cy="398" cx="612.7" />, | ||||
|     <circle key="seat-136" id="seat-136" r="15.7" cy="451.2" cx="618.3" />, | ||||
|     <circle key="seat-137" id="seat-137" r="15.5" cy="82.6" cx="646.3" />, | ||||
|     <circle key="seat-138" id="seat-138" r="15.5" cy="86.4" cx="680.5" />, | ||||
|     <circle key="seat-139" id="seat-139" r="15.5" cy="138.4" cx="650.6" />, | ||||
|     <circle key="seat-140" id="seat-140" r="15.5" cy="94.2" cx="715.6" />, | ||||
|     <circle key="seat-141" id="seat-141" r="15.5" cy="142.6" cx="685.4" />, | ||||
|     <circle key="seat-142" id="seat-142" r="15.7" cy="190.1" cx="657" />, | ||||
|     <circle key="seat-143" id="seat-143" r="15.5" cy="243.4" cx="648.3" />, | ||||
|     <circle key="seat-144" id="seat-144" r="15.5" cy="104.1" cx="747.1" />, | ||||
|     <circle key="seat-145" id="seat-145" r="15.5" cy="150.7" cx="719.9" />, | ||||
|     <circle key="seat-146" id="seat-146" r="15.7" cy="197.9" cx="691.5" />, | ||||
|     <circle key="seat-147" id="seat-147" r="15.5" cy="248.5" cx="679.8" />, | ||||
|     <circle key="seat-148" id="seat-148" r="15.7" cy="298.4" cx="657.8" />, | ||||
|     <circle key="seat-149" id="seat-149" r="15.7" cy="350.8" cx="652.4" />, | ||||
|     <circle key="seat-150" id="seat-150" r="15.5" cy="116" cx="783.1" />, | ||||
|     <circle key="seat-151" id="seat-151" r="15.5" cy="159.7" cx="750.4" />, | ||||
|     <circle key="seat-152" id="seat-152" r="15.7" cy="211" cx="736.6" />, | ||||
|     <circle key="seat-153" id="seat-153" r="15.5" cy="259.6" cx="716.4" />, | ||||
|     <circle key="seat-154" id="seat-154" r="15.7" cy="306.3" cx="691.2" />, | ||||
|     <circle key="seat-155" id="seat-155" r="15.5" cy="127.9" cx="812.8" />, | ||||
|     <circle key="seat-156" id="seat-156" r="15.5" cy="173.7" cx="785.5" />, | ||||
|     <circle key="seat-157" id="seat-157" r="15.7" cy="223" cx="767.7" />, | ||||
|     <circle key="seat-158" id="seat-158" r="15.5" cy="270.9" cx="746.3" />, | ||||
|     <circle key="seat-159" id="seat-159" r="15.5" cy="144.7" cx="846.6" />, | ||||
|     <circle key="seat-160" id="seat-160" r="15.5" cy="186.8" cx="814.8" />, | ||||
|     <circle key="seat-161" id="seat-161" r="15.5" cy="160.4" cx="874.8" />, | ||||
|     <circle key="seat-162" id="seat-162" r="15.5" cy="206.2" cx="847.6" />, | ||||
|     <circle key="seat-163" id="seat-163" r="15.7" cy="245.1" cx="811.5" />, | ||||
|     <circle key="seat-164" id="seat-164" r="15.5" cy="287.4" cx="780.1" />, | ||||
|     <circle key="seat-165" id="seat-165" r="15.7" cy="323.4" cx="734.6" />, | ||||
|     <circle key="seat-166" id="seat-166" r="15.7" cy="357.8" cx="687.4" />, | ||||
|     <circle key="seat-167" id="seat-167" r="15.7" cy="407.6" cx="662.8" />, | ||||
|     <circle key="seat-168" id="seat-168" r="15.5" cy="181.8" cx="907.5" />, | ||||
|     <circle key="seat-169" id="seat-169" r="15.5" cy="223.6" cx="875.2" />, | ||||
|     <circle key="seat-170" id="seat-170" r="15.7" cy="262.6" cx="839.5" />, | ||||
|     <circle key="seat-171" id="seat-171" r="15.5" cy="304.3" cx="807.8" />, | ||||
|     <circle key="seat-172" id="seat-172" r="15.7" cy="339.1" cx="765.3" />, | ||||
|     <circle key="seat-173" id="seat-173" r="15.7" cy="379" cx="729.6" />, | ||||
|     <circle key="seat-174" id="seat-174" r="15.7" cy="420.4" cx="694.6" />, | ||||
|     <circle key="seat-175" id="seat-175" r="15.7" cy="463.5" cx="662.5" />, | ||||
|     <circle key="seat-176" id="seat-176" r="15.7" cy="485.4" cx="699.5" />, | ||||
|     <circle key="seat-177" id="seat-177" r="15.7" cy="213.6" cx="947.4" />, | ||||
|     <circle key="seat-178" id="seat-178" r="15.7" cy="254.9" cx="915.2" />, | ||||
|     <circle key="seat-179" id="seat-179" r="15.7" cy="296.4" cx="882.7" />, | ||||
|     <circle key="seat-180" id="seat-180" r="15.7" cy="337.6" cx="850.7" />, | ||||
|     <circle key="seat-181" id="seat-181" r="15.7" cy="379" cx="818.1" />, | ||||
|     <circle key="seat-182" id="seat-182" r="15.7" cy="420.8" cx="785.4" />, | ||||
|     <circle key="seat-183" id="seat-183" r="15.7" cy="462.7" cx="753.4" />, | ||||
|     <circle key="seat-184" id="seat-184" r="15.7" cy="515.4" cx="730.1" />, | ||||
|     <circle key="seat-185" id="seat-185" r="15.7" cy="236.2" cx="972.4" />, | ||||
|     <circle key="seat-186" id="seat-186" r="15.7" cy="278.6" cx="940.5" />, | ||||
|     <circle key="seat-187" id="seat-187" r="15.7" cy="320.2" cx="907.5" />, | ||||
|     <circle key="seat-188" id="seat-188" r="15.7" cy="362" cx="875.1" />, | ||||
|     <circle key="seat-189" id="seat-189" r="15.7" cy="403.8" cx="841.8" />, | ||||
|     <circle key="seat-190" id="seat-190" r="15.7" cy="445.9" cx="808.9" />, | ||||
|     <circle key="seat-191" id="seat-191" r="15.7" cy="489" cx="775.5" />, | ||||
|     <circle key="seat-192" id="seat-192" r="15.7" cy="265.1" cx="999.7" />, | ||||
|     <circle key="seat-193" id="seat-193" r="15.7" cy="307.2" cx="966.6" />, | ||||
|     <circle key="seat-194" id="seat-194" r="15.7" cy="346.9" cx="931.2" />, | ||||
|     <circle key="seat-195" id="seat-195" r="15.7" cy="393" cx="901" />, | ||||
|     <circle key="seat-196" id="seat-196" r="15.7" cy="435.9" cx="866.9" />, | ||||
|     <circle key="seat-197" id="seat-197" r="15.7" cy="480.8" cx="833.2" />, | ||||
|     <circle key="seat-198" id="seat-198" transform="rotate(-80.8)" r="15.7" cy="1055.16" cx="-124.85" />, | ||||
|     <circle key="seat-199" id="seat-199" r="15.7" cy="334.6" cx="988.2" />, | ||||
|     <circle key="seat-200" id="seat-200" r="15.7" cy="376.9" cx="953.8" />, | ||||
|     <circle key="seat-201" id="seat-201" r="15.7" cy="425.6" cx="922.8" />, | ||||
|     <circle key="seat-202" id="seat-202" r="15.7" cy="464.9" cx="884" />, | ||||
|     <circle key="seat-203" id="seat-203" r="15.7" cy="325.1" cx="1045.7" />, | ||||
|     <circle key="seat-204" id="seat-204" r="15.7" cy="365.7" cx="1009.2" />, | ||||
|     <circle key="seat-205" id="seat-205" r="15.7" cy="405.1" cx="971.7" />, | ||||
|     <circle key="seat-206" id="seat-206" r="15.7" cy="354.1" cx="1063.2" />, | ||||
|     <circle key="seat-207" id="seat-207" transform="rotate(-80.8)" r="15.7" cy="1075.78" cx="-226.25" />, | ||||
|     <circle key="seat-208" id="seat-208" r="15.7" cy="387.4" cx="1081.8" />, | ||||
|     <circle key="seat-209" id="seat-209" r="15.7" cy="421.3" cx="1095.7" />, | ||||
|     <circle key="seat-210" id="seat-210" r="15.7" cy="429.8" cx="1042.5" />, | ||||
|     <circle key="seat-211" id="seat-211" r="15.7" cy="437.3" cx="988.2" />, | ||||
|     <circle key="seat-212" id="seat-212" r="15.7" cy="455.4" cx="938.5" />, | ||||
|     <circle key="seat-213" id="seat-213" r="15.7" cy="455.8" cx="1108.8" />, | ||||
|     <circle key="seat-214" id="seat-214" r="15.7" cy="462" cx="1054.9" />, | ||||
|     <circle key="seat-215" id="seat-215" r="15.7" cy="469.3" cx="1001.6" />, | ||||
|     <circle key="seat-216" id="seat-216" r="15.7" cy="492.6" cx="954.1" />, | ||||
|     <circle key="seat-217" id="seat-217" r="15.7" cy="500.6" cx="900.8" />, | ||||
|     <circle key="seat-218" id="seat-218" r="15.7" cy="511.6" cx="849" />, | ||||
|     <circle key="seat-219" id="seat-219" r="15.7" cy="535" cx="801.6" />, | ||||
|     <circle key="seat-220" id="seat-220" r="15.7" cy="554.8" cx="753.3" />, | ||||
|     <circle key="seat-221" id="seat-221" r="15.7" cy="490.9" cx="1118" />, | ||||
|     <circle key="seat-222" id="seat-222" r="15.7" cy="497.2" cx="1065.3" />, | ||||
|     <circle key="seat-223" id="seat-223" r="15.7" cy="502.8" cx="1012.3" />, | ||||
|     <circle key="seat-224" id="seat-224" r="15.7" cy="525.1" cx="964.2" />, | ||||
|     <circle key="seat-225" id="seat-225" r="15.7" cy="533.1" cx="912.2" />, | ||||
|     <circle key="seat-226" id="seat-226" r="15.7" cy="554.6" cx="863.4" />, | ||||
|     <circle key="seat-227" id="seat-227" r="15.7" cy="567.9" cx="812.7" />, | ||||
|     <circle key="seat-228" id="seat-228" r="15.7" cy="596.7" cx="764.8" />, | ||||
|     <circle key="seat-229" id="seat-229" r="15.7" cy="528.9" cx="1126.1" />, | ||||
|     <circle key="seat-230" id="seat-230" r="15.7" cy="530.2" cx="1072.7" />, | ||||
|     <circle key="seat-231" id="seat-231" transform="rotate(-80.8)" r="15.7" cy="1092.81" cx="-365.69" />, | ||||
|     <circle key="seat-232" id="seat-232" r="15.7" cy="562.9" cx="1130.6" />, | ||||
|     <circle key="seat-233" id="seat-233" r="15.7" cy="566.7" cx="1078.3" />, | ||||
|     <circle key="seat-234" id="seat-234" transform="rotate(-80.8)" r="15.7" cy="1103.39" cx="-398.54" />, | ||||
|     <circle key="seat-235" id="seat-235" r="15.7" cy="564.5" cx="972.4" />, | ||||
|     <circle key="seat-236" id="seat-236" r="15.7" cy="568.6" cx="919.7" />, | ||||
|     <circle key="seat-237" id="seat-237" r="15.7" cy="588" cx="869.4" />, | ||||
|     <circle key="seat-238" id="seat-238" r="15.7" cy="602.5" cx="1133.5" />, | ||||
|     <circle key="seat-239" id="seat-239" r="15.7" cy="600.9" cx="1081" />, | ||||
|     <circle key="seat-240" id="seat-240" transform="rotate(-80.8)" r="15.7" cy="1111.41" cx="-431.3" />, | ||||
|     <circle key="seat-241" id="seat-241" r="15.7" cy="598.6" cx="975.6" />, | ||||
|     <circle key="seat-242" id="seat-242" r="15.7" cy="602.6" cx="923.4" />, | ||||
|     <circle key="seat-243" id="seat-243" r="15.7" cy="636.4" cx="1133.9" />, | ||||
|     <circle key="seat-244" id="seat-244" r="15.7" cy="639" cx="1081.3" />, | ||||
|     <circle key="seat-245" id="seat-245" transform="rotate(-80.8)" r="15.7" cy="1117.48" cx="-466.13" />, | ||||
|     <circle key="seat-246" id="seat-246" r="15.7" cy="639.2" cx="976.3" />, | ||||
|     <circle key="seat-247" id="seat-247" r="15.7" cy="638.8" cx="923.9" />, | ||||
|     <circle key="seat-248" id="seat-248" r="15.7" cy="635.1" cx="871.2" />, | ||||
|     <circle key="seat-249" id="seat-249" r="15.7" cy="625.7" cx="818.8" />, | ||||
|     <circle key="seat-250" id="seat-250" r="15.7" cy="639" cx="766.3" />, | ||||
|     <circle key="seat-251" id="seat-251" r="15.7" cy="673.1" cx="1081.3" />, | ||||
|     <circle key="seat-252" id="seat-252" transform="rotate(-80.8)" r="15.7" cy="1122.99" cx="-499.74" />, | ||||
|     <circle key="seat-253" id="seat-253" r="15.7" cy="673.5" cx="976.3" />, | ||||
|     <circle key="seat-254" id="seat-254" r="15.7" cy="673.2" cx="924" />, | ||||
|     <circle key="seat-255" id="seat-255" r="15.7" cy="669.5" cx="871.2" />, | ||||
|     <circle key="seat-256" id="seat-256" r="15.7" cy="660" cx="819.7" />, | ||||
|   ]; | ||||
|  | ||||
|   let seatIndex = 1; // Empezamos a contar desde 1, ya que el 0 es presidencial | ||||
|  | ||||
|   return ( | ||||
|     <svg viewBox="0 0 1190.6 772.2" width={size} height={size * (772.2 / 1190.6)} style={{ display: 'block', margin: 'auto' }}> | ||||
|       <g> | ||||
|         {/* Renderizamos el escaño presidencial primero y por separado */} | ||||
|         {presidenteBancada && React.cloneElement(seatElements[PRESIDENTE_SEAT_INDEX], { | ||||
|           fill: presidenteBancada.color || '#A9A9A9', | ||||
|           strokeWidth: 0.5, | ||||
|         })} | ||||
|         {partyData.map(partido => { | ||||
|           // Por cada partido, creamos un array combinado de sus escaños | ||||
|           const partySeats = [ | ||||
|             ...Array(partido.bancasFijos).fill({ isNew: false }), | ||||
|             ...Array(partido.bancasGanadas).fill({ isNew: true }) | ||||
|           ]; | ||||
|  | ||||
|           return ( | ||||
|             // Envolvemos todos los escaños de un partido en un <g> | ||||
|             <g | ||||
|               key={partido.id} | ||||
|               className="party-block" | ||||
|               data-tooltip-id="party-tooltip" | ||||
|               data-tooltip-content={`${partido.nombreCorto || partido.nombre}: ${partido.bancasTotales} bancas`} | ||||
|             > | ||||
|               {partySeats.map((seatInfo, i) => { | ||||
|                 // Si ya no hay más plantillas de escaños, no renderizamos nada | ||||
|                 if (seatIndex >= seatElements.length) return null; | ||||
|  | ||||
|                 const template = seatElements[seatIndex]; | ||||
|                 seatIndex++; // Incrementamos el contador para el siguiente escaño | ||||
|  | ||||
|                 // Clonamos la plantilla con el estilo apropiado | ||||
|                 return React.cloneElement(template, { | ||||
|                   key: `${partido.id}-${i}`, | ||||
|                   className: 'seat-circle', | ||||
|                   fill: partido.color || '#808080', | ||||
|                   fillOpacity: seatInfo.isNew ? 1 : 0.3, // Opacidad para bancas previas | ||||
|                   stroke: partido.color || '#808080', | ||||
|                   strokeWidth: 0.5, | ||||
|                 }); | ||||
|               })} | ||||
|             </g> | ||||
|           ); | ||||
|         })} | ||||
|         {/* Renderizamos los escaños vacíos sobrantes */} | ||||
|         {seatIndex < seatElements.length && | ||||
|           seatElements.slice(seatIndex).map((template, i) => | ||||
|             React.cloneElement(template, { | ||||
|               key: `empty-${i}`, | ||||
|               fill: '#E0E0E0', | ||||
|               stroke: '#ffffff', | ||||
|               strokeWidth: 0.5 | ||||
|             }) | ||||
|           ) | ||||
|         } | ||||
|       </g> | ||||
|     </svg> | ||||
|   ); | ||||
| }; | ||||
| @@ -0,0 +1,154 @@ | ||||
| // src/components/common/SenadoresNacionalesLayout.tsx | ||||
| import React from 'react'; | ||||
| import type { PartidoComposicionNacional } from '../../apiService'; | ||||
|  | ||||
| // Interfaces | ||||
| interface SenadoresNacionalesLayoutProps { | ||||
|   partyData: PartidoComposicionNacional[]; | ||||
|   size?: number; | ||||
|   presidenteBancada?: { color: string | null } | null; | ||||
| } | ||||
|  | ||||
| const PRESIDENTE_SEAT_INDEX = 0; | ||||
|  | ||||
| export const SenadoresNacionalesLayout: React.FC<SenadoresNacionalesLayoutProps> = ({ | ||||
|   partyData, | ||||
|   size = 800, | ||||
|   presidenteBancada, | ||||
| }) => { | ||||
|   // --- ARRAY DE 73 ELEMENTOS <circle> ORDENADOS POR ID DE "seat-X" --- | ||||
|   // El asiento 0 es el presidencial, los 72 restantes son los senadores. | ||||
|   const seatElements = [ | ||||
|     <circle key="seat-0" id="seat-0" r="7.1" cy="187" cx="168.6" />, | ||||
|     <circle key="seat-1" id="seat-1" r="7.1" cy="166" cx="21.8" />, | ||||
|     <circle key="seat-2" id="seat-2" r="7.1" cy="172" cx="51.5" />, | ||||
|     <circle key="seat-3" id="seat-3" r="7.1" cy="174.5" cx="82.7" />, | ||||
|     <circle key="seat-4" id="seat-4" r="7.1" cy="147.4" cx="21.5" />, | ||||
|     <circle key="seat-5" id="seat-5" r="7.1" cy="155.2" cx="51.8" />, | ||||
|     <circle key="seat-6" id="seat-6" r="7.1" cy="156.3" cx="83.4" />, | ||||
|     <circle key="seat-7" id="seat-7" r="7.1" cy="169.9" cx="120.9" />, | ||||
|     <circle key="seat-8" id="seat-8" r="7.1" cy="128.4" cx="22.8" />, | ||||
|     <circle key="seat-9" id="seat-9" r="7.1" cy="137.9" cx="53.2" />, | ||||
|     <circle key="seat-10" id="seat-10" r="7.1" cy="138.8" cx="85.5" />, | ||||
|     <circle key="seat-11" id="seat-11" r="7.1" cy="151.9" cx="120.9" />, | ||||
|     <circle key="seat-12" id="seat-12" r="7.1" cy="109" cx="25.6" />, | ||||
|     <circle key="seat-13" id="seat-13" r="7.1" cy="121.3" cx="57.2" />, | ||||
|     <circle key="seat-14" id="seat-14" r="7.1" cy="91.5" cx="34.2" />, | ||||
|     <circle key="seat-15" id="seat-15" r="7.1" cy="105.7" cx="64.8" />, | ||||
|     <circle key="seat-16" id="seat-16" r="7.1" cy="122.5" cx="92.9" />, | ||||
|     <circle key="seat-17" id="seat-17" r="7.1" cy="136.2" cx="128.2" />, | ||||
|     <circle key="seat-18" id="seat-18" r="7.1" cy="75.5" cx="45.3" />, | ||||
|     <circle key="seat-19" id="seat-19" r="7.1" cy="91.3" cx="75.7" />, | ||||
|     <circle key="seat-20" id="seat-20" r="7.1" cy="106.5" cx="106.3" />, | ||||
|     <circle key="seat-21" id="seat-21" r="7.1" cy="59.8" cx="57.9" />, | ||||
|     <circle key="seat-22" id="seat-22" r="7.1" cy="78.6" cx="89.5" />, | ||||
|     <circle key="seat-23" id="seat-23" r="7.1" cy="45.3" cx="73.2" />, | ||||
|     <circle key="seat-24" id="seat-24" r="7.1" cy="67.2" cx="104.6" />, | ||||
|     <circle key="seat-25" id="seat-25" r="7.1" cy="94.3" cx="121.6" />, | ||||
|     <circle key="seat-26" id="seat-26" r="7.1" cy="124.3" cx="141.1" />, | ||||
|     <circle key="seat-27" id="seat-27" r="7.1" cy="32.7" cx="90.8" />, | ||||
|     <circle key="seat-28" id="seat-28" r="7.1" cy="58.3" cx="120.9" />, | ||||
|     <circle key="seat-29" id="seat-29" r="7.1" cy="84.9" cx="139.1" />, | ||||
|     <circle key="seat-30" id="seat-30" r="7.1" cy="116.4" cx="157.2" />, | ||||
|     <circle key="seat-31" id="seat-31" r="7.1" cy="24.6" cx="109.5" />, | ||||
|     <circle key="seat-32" id="seat-32" r="7.1" cy="52.2" cx="138.6" />, | ||||
|     <circle key="seat-33" id="seat-33" r="7.1" cy="79.5" cx="157.8" />, | ||||
|     <circle key="seat-34" id="seat-34" r="7.1" cy="17.9" cx="128.8" />, | ||||
|     <circle key="seat-35" id="seat-35" r="7.1" cy="15.2" cx="147.7" />, | ||||
|     <circle key="seat-36" id="seat-36" r="7.1" cy="48.3" cx="156.9" />, | ||||
|     <circle key="seat-37" id="seat-37" r="7.1" cy="15.2" cx="192.5" />, | ||||
|     <circle key="seat-38" id="seat-38" r="7.1" cy="48.3" cx="183.3" />, | ||||
|     <circle key="seat-39" id="seat-39" r="7.1" cy="79.5" cx="182.4" />, | ||||
|     <circle key="seat-40" id="seat-40" r="7.1" cy="115.8" cx="182.2" />, | ||||
|     <circle key="seat-41" id="seat-41" r="7.1" cy="17.9" cx="211.4" />, | ||||
|     <circle key="seat-42" id="seat-42" r="7.1" cy="52.2" cx="201.6" />, | ||||
|     <circle key="seat-43" id="seat-43" r="7.1" cy="24.6" cx="230.7" />, | ||||
|     <circle key="seat-44" id="seat-44" r="7.1" cy="58.3" cx="219.3" />, | ||||
|     <circle key="seat-45" id="seat-45" r="7.1" cy="84.9" cx="201.1" />, | ||||
|     <circle key="seat-46" id="seat-46" r="7.1" cy="32.7" cx="249.4" />, | ||||
|     <circle key="seat-47" id="seat-47" r="7.1" cy="67.2" cx="235.6" />, | ||||
|     <circle key="seat-48" id="seat-48" r="7.1" cy="94.3" cx="218.6" />, | ||||
|     <circle key="seat-49" id="seat-49" r="7.1" cy="124.3" cx="199.1" />, | ||||
|     <circle key="seat-50" id="seat-50" r="7.1" cy="45.3" cx="267" />, | ||||
|     <circle key="seat-51" id="seat-51" r="7.1" cy="59.8" cx="282.3" />, | ||||
|     <circle key="seat-52" id="seat-52" r="7.1" cy="78.6" cx="250.7" />, | ||||
|     <circle key="seat-53" id="seat-53" r="7.1" cy="106.5" cx="234" />, | ||||
|     <circle key="seat-54" id="seat-54" r="7.1" cy="136.2" cx="212" />, | ||||
|     <circle key="seat-55" id="seat-55" r="7.1" cy="75.5" cx="294.9" />, | ||||
|     <circle key="seat-56" id="seat-56" r="7.1" cy="91.3" cx="264.5" />, | ||||
|     <circle key="seat-57" id="seat-57" r="7.1" cy="91.5" cx="306" />, | ||||
|     <circle key="seat-58" id="seat-58" r="7.1" cy="105.7" cx="275.4" />, | ||||
|     <circle key="seat-59" id="seat-59" r="7.1" cy="122.5" cx="247.3" />, | ||||
|     <circle key="seat-60" id="seat-60" r="7.1" cy="109" cx="313.5" />, | ||||
|     <circle key="seat-61" id="seat-61" r="7.1" cy="121.3" cx="283" />, | ||||
|     <circle key="seat-62" id="seat-62" r="7.1" cy="138.8" cx="254.7" />, | ||||
|     <circle key="seat-63" id="seat-63" r="7.1" cy="151.9" cx="219.3" />, | ||||
|     <circle key="seat-64" id="seat-64" r="7.1" cy="128.4" cx="317.4" />, | ||||
|     <circle key="seat-65" id="seat-65" r="7.1" cy="137.9" cx="287" />, | ||||
|     <circle key="seat-66" id="seat-66" r="7.1" cy="156.3" cx="256.8" />, | ||||
|     <circle key="seat-67" id="seat-67" r="7.1" cy="169.9" cx="219.3" />, | ||||
|     <circle key="seat-68" id="seat-68" r="7.1" cy="147.4" cx="318.7" />, | ||||
|     <circle key="seat-69" id="seat-69" r="7.1" cy="155.2" cx="288.4" />, | ||||
|     <circle key="seat-70" id="seat-70" r="7.1" cy="166" cx="318.4" />, | ||||
|     <circle key="seat-71" id="seat-71" r="7.1" cy="172" cx="288.7" />, | ||||
|     <circle key="seat-72" id="seat-72" r="7.1" cy="174.5" cx="257.5" />, | ||||
|   ]; | ||||
|  | ||||
|   let seatIndex = 1; // Empezamos desde 1 porque el 0 es para el presidente | ||||
|  | ||||
|   return ( | ||||
|     <svg viewBox="0 0 340.2 220.5" width={size} height={size * (220.5 / 340.2)} style={{ display: 'block', margin: 'auto' }}> | ||||
|       <g> | ||||
|         {/* Renderizamos primero el escaño del presidente por separado */} | ||||
|         {presidenteBancada && React.cloneElement(seatElements[PRESIDENTE_SEAT_INDEX], { | ||||
|           fill: presidenteBancada.color || '#A9A9A9', | ||||
|           strokeWidth: 0.5, | ||||
|         })} | ||||
|  | ||||
|         {/* Mapeamos los partidos para crear los bloques */} | ||||
|         {partyData.map(partido => { | ||||
|           const partySeats = [ | ||||
|             ...Array(partido.bancasFijos).fill({ isNew: false }), | ||||
|             ...Array(partido.bancasGanadas).fill({ isNew: true }) | ||||
|           ]; | ||||
|            | ||||
|           return ( | ||||
|             <g | ||||
|               key={partido.id} | ||||
|               className="party-block" | ||||
|               data-tooltip-id="party-tooltip" | ||||
|               data-tooltip-content={`${partido.nombreCorto || partido.nombre}: ${partido.bancasTotales} bancas`} | ||||
|             > | ||||
|               {partySeats.map((seatInfo, i) => { | ||||
|                 if (seatIndex >= seatElements.length) return null; | ||||
|  | ||||
|                 const template = seatElements[seatIndex]; | ||||
|                 seatIndex++; | ||||
|  | ||||
|                 return React.cloneElement(template, { | ||||
|                   key: `${partido.id}-${i}`, | ||||
|                   className: 'seat-circle', | ||||
|                   fill: partido.color || '#808080', | ||||
|                   fillOpacity: seatInfo.isNew ? 1 : 0.3, | ||||
|                   stroke: partido.color || '#808080', | ||||
|                   strokeWidth: 0.5, | ||||
|                 }); | ||||
|               })} | ||||
|             </g> | ||||
|           ); | ||||
|         })} | ||||
|         {/* Renderizamos escaños vacíos si sobran */} | ||||
|         {seatIndex < seatElements.length && | ||||
|           seatElements.slice(seatIndex).map((template, i) =>  | ||||
|             React.cloneElement(template, { | ||||
|               key: `empty-${i}`, | ||||
|               fill: '#E0E0E0', | ||||
|               stroke: '#ffffff', | ||||
|               strokeWidth: 0.5 | ||||
|             }) | ||||
|           ) | ||||
|         } | ||||
|       </g> | ||||
|     </svg> | ||||
|   ); | ||||
| }; | ||||
| @@ -1,4 +1,6 @@ | ||||
| // src/features/legislativas/rovinciales/DevAppLegislativas.tsx | ||||
| import { ResultadosNacionalesCardsWidget } from './nacionales/ResultadosNacionalesCardsWidget'; | ||||
| import { CongresoNacionalWidget } from './nacionales/CongresoNacionalWidget'; | ||||
| import { PanelNacionalWidget } from './nacionales/PanelNacionalWidget'; | ||||
| import './DevAppStyle.css' | ||||
|  | ||||
| @@ -6,9 +8,8 @@ export const DevAppLegislativas = () => { | ||||
|     return ( | ||||
|         <div className="container"> | ||||
|             <h1>Visor de Widgets</h1> | ||||
|              | ||||
|             {/* Le pasamos el ID de la elección que queremos visualizar. | ||||
|                 Para tus datos de prueba provinciales, este ID es 1. */} | ||||
|             <ResultadosNacionalesCardsWidget eleccionId={2} /> | ||||
|             <CongresoNacionalWidget eleccionId={2} /> | ||||
|             <PanelNacionalWidget eleccionId={2} /> | ||||
|         </div> | ||||
|     ); | ||||
|   | ||||
| @@ -0,0 +1,162 @@ | ||||
| // src/features/legislativas/nacionales/CongresoNacionalWidget.tsx | ||||
| import { useState, Suspense, useMemo } from 'react'; | ||||
| import { useSuspenseQuery } from '@tanstack/react-query'; | ||||
| import { Tooltip } from 'react-tooltip'; | ||||
| import { DiputadosNacionalesLayout } from '../../../components/common/DiputadosNacionalesLayout'; | ||||
| import { SenadoresNacionalesLayout } from '../../../components/common/SenadoresNacionalesLayout'; | ||||
| import { getComposicionNacional, type ComposicionNacionalData, type PartidoComposicionNacional } from '../../../apiService'; | ||||
| import '../provinciales/CongresoWidget.css'; | ||||
|  | ||||
| interface CongresoNacionalWidgetProps { | ||||
|   eleccionId: number; | ||||
| } | ||||
|  | ||||
| const formatTimestamp = (dateString: string) => { | ||||
|   if (!dateString) return '...'; | ||||
|   const date = new Date(dateString); | ||||
|   const day = String(date.getDate()).padStart(2, '0'); | ||||
|   const month = String(date.getMonth() + 1).padStart(2, '0'); | ||||
|   const year = date.getFullYear(); | ||||
|   const hours = String(date.getHours()).padStart(2, '0'); | ||||
|   const minutes = String(date.getMinutes()).padStart(2, '0'); | ||||
|   return `${day}/${month}/${year} ${hours}:${minutes}`; | ||||
| }; | ||||
|  | ||||
| const WidgetContent = ({ eleccionId }: CongresoNacionalWidgetProps) => { | ||||
|   const [camaraActiva, setCamaraActiva] = useState<'diputados' | 'senadores'>('diputados'); | ||||
|   const [isHovering, setIsHovering] = useState(false); | ||||
|  | ||||
|   const { data } = useSuspenseQuery<ComposicionNacionalData>({ | ||||
|     queryKey: ['composicionNacional', eleccionId], | ||||
|     queryFn: () => getComposicionNacional(eleccionId), | ||||
|     refetchInterval: 30000, | ||||
|   }); | ||||
|  | ||||
|   const datosCamaraActual = data[camaraActiva]; | ||||
|  | ||||
|   const partidosOrdenados = useMemo(() => { | ||||
|     if (!datosCamaraActual?.partidos) return []; | ||||
|     const partidosACopiar = [...datosCamaraActual.partidos]; | ||||
|     partidosACopiar.sort((a, b) => { | ||||
|       const ordenA = camaraActiva === 'diputados' ? a.ordenDiputadosNacionales : a.ordenSenadoresNacionales; | ||||
|       const ordenB = camaraActiva === 'diputados' ? b.ordenDiputadosNacionales : b.ordenSenadoresNacionales; | ||||
|       return (ordenA ?? 999) - (ordenB ?? 999); | ||||
|     }); | ||||
|     return partidosACopiar; | ||||
|   }, [datosCamaraActual, camaraActiva]); | ||||
|  | ||||
|   const partyDataParaLayout = useMemo(() => { | ||||
|     if (camaraActiva === 'senadores') return partidosOrdenados; | ||||
|     if (!partidosOrdenados || !datosCamaraActual.presidenteBancada?.color) return partidosOrdenados; | ||||
|     const partidoPresidente = partidosOrdenados.find(p => p.color === datosCamaraActual.presidenteBancada!.color); | ||||
|     if (!partidoPresidente) return partidosOrdenados; | ||||
|  | ||||
|     const adjustedPartyData = JSON.parse(JSON.stringify(partidosOrdenados)); | ||||
|     const partidoAjustar = adjustedPartyData.find((p: PartidoComposicionNacional) => p.id === partidoPresidente.id); | ||||
|  | ||||
|     if (partidoAjustar) { | ||||
|       const tipoBanca = datosCamaraActual.presidenteBancada.tipoBanca; | ||||
|       if (tipoBanca === 'ganada' && partidoAjustar.bancasGanadas > 0) { | ||||
|         partidoAjustar.bancasGanadas -= 1; | ||||
|       } else if (tipoBanca === 'previa' && partidoAjustar.bancasFijos > 0) { | ||||
|         partidoAjustar.bancasFijos -= 1; | ||||
|       } else { | ||||
|         if (partidoAjustar.bancasGanadas > 0) { | ||||
|           partidoAjustar.bancasGanadas -= 1; | ||||
|         } else if (partidoAjustar.bancasFijos > 0) { | ||||
|           partidoAjustar.bancasFijos -= 1; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return adjustedPartyData; | ||||
|   }, [partidosOrdenados, datosCamaraActual.presidenteBancada, camaraActiva]); | ||||
|  | ||||
|   return ( | ||||
|     <div className="congreso-container"> | ||||
|       <div className="congreso-grafico"> | ||||
|         <div | ||||
|           className={`congreso-hemiciclo-wrapper ${isHovering ? 'is-hovering' : ''}`} | ||||
|           onMouseEnter={() => setIsHovering(true)} | ||||
|           onMouseLeave={() => setIsHovering(false)} | ||||
|         > | ||||
|           {camaraActiva === 'diputados' ? | ||||
|             <DiputadosNacionalesLayout | ||||
|               partyData={partyDataParaLayout} | ||||
|               presidenteBancada={datosCamaraActual.presidenteBancada || null} | ||||
|               size={700} | ||||
|             /> : | ||||
|             <SenadoresNacionalesLayout | ||||
|               partyData={partyDataParaLayout} | ||||
|               presidenteBancada={datosCamaraActual.presidenteBancada || null} | ||||
|               size={700} | ||||
|             /> | ||||
|           } | ||||
|         </div> | ||||
|         <div className="congreso-footer"> | ||||
|           <div className="footer-legend"> | ||||
|             <div className="footer-legend-item"> | ||||
|               {/* Usamos la nueva clase CSS para el círculo sólido */} | ||||
|               <span className="legend-icon legend-icon--solid"></span> | ||||
|               <span>Bancas en juego</span> | ||||
|             </div> | ||||
|             <div className="footer-legend-item"> | ||||
|               {/* Reemplazamos el SVG por un span con la nueva clase para el anillo */} | ||||
|               <span className="legend-icon legend-icon--ring"></span> | ||||
|               <span>Bancas previas</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="footer-timestamp"> | ||||
|             Última Actualización: {formatTimestamp(datosCamaraActual.ultimaActualizacion)} | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div className="congreso-summary"> | ||||
|         <div className="chamber-tabs"> | ||||
|           <button className={camaraActiva === 'diputados' ? 'active' : ''} onClick={() => setCamaraActiva('diputados')}> | ||||
|             Diputados | ||||
|           </button> | ||||
|           <button className={camaraActiva === 'senadores' ? 'active' : ''} onClick={() => setCamaraActiva('senadores')}> | ||||
|             Senadores | ||||
|           </button> | ||||
|         </div> | ||||
|         <h3>{datosCamaraActual.camaraNombre}</h3> | ||||
|         <div className="summary-metric"> | ||||
|           <span>Total de Bancas</span> | ||||
|           <strong>{datosCamaraActual.totalBancas}</strong> | ||||
|         </div> | ||||
|         <div className="summary-metric"> | ||||
|           <span>Bancas en Juego</span> | ||||
|           <strong>{datosCamaraActual.bancasEnJuego}</strong> | ||||
|         </div> | ||||
|         <hr /> | ||||
|         <div className="partido-lista-container"> | ||||
|           <ul className="partido-lista"> | ||||
|             {partidosOrdenados | ||||
|               .filter(p => p.bancasTotales > 0) | ||||
|               .map((partido: PartidoComposicionNacional) => ( | ||||
|                 <li key={partido.id}> | ||||
|                   <span className="partido-color-box" style={{ backgroundColor: partido.color || '#808080' }}></span> | ||||
|                   <span className="partido-nombre">{partido.nombreCorto || partido.nombre}</span> | ||||
|                   <strong | ||||
|                     className="partido-bancas" | ||||
|                     title={`${partido.bancasFijos} bancas previas + ${partido.bancasGanadas} ganadas`} | ||||
|                   > | ||||
|                     {partido.bancasTotales} | ||||
|                   </strong> | ||||
|                 </li> | ||||
|               ))} | ||||
|           </ul> | ||||
|         </div> | ||||
|       </div> | ||||
|       <Tooltip id="party-tooltip" /> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export const CongresoNacionalWidget = ({ eleccionId }: CongresoNacionalWidgetProps) => { | ||||
|   return ( | ||||
|     <Suspense fallback={<div className="congreso-container loading" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '400px' }}>Cargando composición del congreso...</div>}> | ||||
|       <WidgetContent eleccionId={eleccionId} /> | ||||
|     </Suspense> | ||||
|   ); | ||||
| }; | ||||
| @@ -1,10 +1,11 @@ | ||||
| /* src/features/legislativas/nacionales/PanelNaciona.css */ | ||||
| /* src/features/legislativas/nacionales/PanelNacional.css */ | ||||
| .panel-nacional-container { | ||||
|   font-family: 'Roboto', sans-serif; | ||||
|   max-width: 1200px; | ||||
|   margin: auto; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   border-radius: 8px; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .panel-header { | ||||
| @@ -491,13 +492,11 @@ | ||||
| /* --- NUEVOS ESTILOS PARA EL TOGGLE MÓVIL --- */ | ||||
| .mobile-view-toggle { | ||||
|   display: none; | ||||
|   /* Oculto por defecto */ | ||||
|   position: fixed; | ||||
|   bottom: 20px; | ||||
|   position: absolute; /* <-- CAMBIO: De 'fixed' a 'absolute' */ | ||||
|   bottom: 10px; /* <-- AJUSTE: Menos espacio desde abajo */ | ||||
|   left: 50%; | ||||
|   transform: translateX(-50%); | ||||
|   z-index: 100; | ||||
|  | ||||
|   background-color: rgba(255, 255, 255, 0.9); | ||||
|   border-radius: 30px; | ||||
|   padding: 5px; | ||||
|   | ||||
| @@ -0,0 +1,259 @@ | ||||
| /* src/features/legislativas/nacionales/ResultadosNacionalesCardsWidget.css */ | ||||
|  | ||||
| /* --- Variables de Diseño --- */ | ||||
| :root { | ||||
|     --card-border-color: #e0e0e0; | ||||
|     --card-bg-color: #ffffff; | ||||
|     --card-header-bg-color: #f8f9fa; | ||||
|     --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); | ||||
|     --text-primary: #212529; | ||||
|     --text-secondary: #6c757d; | ||||
|     --font-family: "Public Sans", system-ui, sans-serif; | ||||
|     --primary-accent-color: #007bff; | ||||
| } | ||||
|  | ||||
| /* --- Contenedor Principal del Widget --- */ | ||||
| .cards-widget-container { | ||||
|     font-family: var(--font-family); | ||||
|     width: 100%; | ||||
|     max-width: 1200px; | ||||
|     margin: 2rem auto; | ||||
| } | ||||
|  | ||||
| .cards-widget-container h2 { | ||||
|     font-size: 1.75rem; | ||||
|     color: var(--text-primary); | ||||
|     margin-bottom: 1.5rem; | ||||
|     padding-bottom: 0.5rem; | ||||
|     border-bottom: 1px solid var(--card-border-color); | ||||
| } | ||||
|  | ||||
| /* --- Grilla de Tarjetas --- */ | ||||
| .cards-grid { | ||||
|     display: grid; | ||||
|     /* Crea columnas flexibles que se ajustan al espacio disponible */ | ||||
|     grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); | ||||
|     gap: 1.5rem; | ||||
| } | ||||
|  | ||||
| /* --- Tarjeta Individual --- */ | ||||
| .provincia-card { | ||||
|     background-color: var(--card-bg-color); | ||||
|     border: 1px solid var(--card-border-color); | ||||
|     border-radius: 8px; | ||||
|     box-shadow: var(--card-shadow); | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     overflow: hidden; /* Asegura que los bordes redondeados se apliquen al contenido */ | ||||
| } | ||||
|  | ||||
| /* --- Cabecera de la Tarjeta --- */ | ||||
| .card-header { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     background-color: var(--card-header-bg-color); | ||||
|     padding: 0.75rem 1rem; | ||||
|     border-bottom: 1px solid var(--card-border-color); | ||||
| } | ||||
|  | ||||
| .header-info h3 { | ||||
|     margin: 0; | ||||
|     font-size: 1.2rem; | ||||
|     font-weight: 700; | ||||
|     color: var(--text-primary); | ||||
| } | ||||
|  | ||||
| .header-info span { | ||||
|     font-size: 0.8rem; | ||||
|     color: var(--text-secondary); | ||||
|     text-transform: uppercase; | ||||
| } | ||||
|  | ||||
| .header-map { | ||||
|     width: 90px; | ||||
|     height: 90px; | ||||
|     flex-shrink: 0; | ||||
|     border-radius: 4px; | ||||
|     overflow: hidden; | ||||
|     background-color: #e9ecef; | ||||
|     padding: 0.25rem; | ||||
|     box-sizing: border-box; /* Para que el padding no aumente el tamaño total */ | ||||
| } | ||||
|  | ||||
| /* Contenedor del SVG para asegurar que se ajuste al espacio */ | ||||
| .map-svg-container, .map-placeholder { | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
| } | ||||
|  | ||||
| /* Estilo para el SVG renderizado */ | ||||
| .map-svg-container svg { | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
|     object-fit: contain; /* Asegura que el mapa no se deforme */ | ||||
| } | ||||
|  | ||||
| /* Placeholder para cuando el mapa no carga */ | ||||
| .map-placeholder.error { | ||||
|     background-color: #f8d7da; /* Un color de fondo rojizo para indicar un error */ | ||||
| } | ||||
|  | ||||
| /* --- Cuerpo de la Tarjeta --- */ | ||||
| .card-body { | ||||
|     padding: 0.5rem 1rem; | ||||
| } | ||||
|  | ||||
| .candidato-row { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     gap: 0.75rem; | ||||
|     padding: 0.75rem 0; | ||||
|     border-bottom: 1px solid #f0f0f0; | ||||
| } | ||||
|  | ||||
| .candidato-row:last-child { | ||||
|     border-bottom: none; | ||||
| } | ||||
|  | ||||
| .candidato-foto { | ||||
|     width: 45px; | ||||
|     height: 45px; | ||||
|     border-radius: 50%; | ||||
|     object-fit: cover; | ||||
|     flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .candidato-data { | ||||
|     flex-grow: 1; | ||||
|     min-width: 0; /* Permite que el texto se trunque si es necesario */ | ||||
|     margin-right: 0.5rem; | ||||
| } | ||||
|  | ||||
| .candidato-nombre { | ||||
|     font-weight: 700; | ||||
|     font-size: 0.95rem; | ||||
|     color: var(--text-primary); | ||||
|     display: block; | ||||
| } | ||||
|  | ||||
| .candidato-partido { | ||||
|     font-size: 0.75rem; | ||||
|     color: var(--text-secondary); | ||||
|     text-transform: uppercase; | ||||
|     display: block; | ||||
|     margin-bottom: 0.3rem; | ||||
| } | ||||
|  | ||||
| .progress-bar-container { | ||||
|     height: 6px; | ||||
|     background-color: #e9ecef; | ||||
|     border-radius: 3px; | ||||
|     overflow: hidden; | ||||
| } | ||||
|  | ||||
| .progress-bar { | ||||
|     height: 100%; | ||||
|     border-radius: 3px; | ||||
|     transition: width 0.5s ease-out; | ||||
| } | ||||
|  | ||||
| .candidato-stats { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: flex-end; | ||||
|     text-align: right; | ||||
|     flex-shrink: 0; | ||||
|     padding-left: 0.5rem; | ||||
| } | ||||
|  | ||||
| .stats-percent { | ||||
|     font-weight: 700; | ||||
|     font-size: 1.1rem; | ||||
|     color: var(--text-primary); | ||||
| } | ||||
|  | ||||
| .stats-votos { | ||||
|     font-size: 0.8rem; | ||||
|     color: var(--text-secondary); | ||||
| } | ||||
|  | ||||
| .stats-bancas { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     flex-shrink: 0; | ||||
|     border: 1px solid var(--card-border-color); | ||||
|     border-radius: 6px; | ||||
|     padding: 0.25rem 0.5rem; | ||||
|     margin-left: 0.75rem; | ||||
|     font-weight: 700; | ||||
|     font-size: 1.2rem; | ||||
|     color: var(--primary-accent-color); | ||||
|     min-width: 50px; | ||||
| } | ||||
|  | ||||
| .stats-bancas span { | ||||
|     font-size: 0.65rem; | ||||
|     font-weight: 500; | ||||
|     color: var(--text-secondary); | ||||
|     text-transform: uppercase; | ||||
|     margin-top: -4px; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* --- Pie de la Tarjeta --- */ | ||||
| .card-footer { | ||||
|     display: grid; | ||||
|     grid-template-columns: repeat(3, 1fr); | ||||
|     background-color: var(--card-header-bg-color); | ||||
|     border-top: 1px solid var(--card-border-color); | ||||
|     padding: 0.75rem 0; | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .card-footer div { | ||||
|     border-right: 1px solid var(--card-border-color); | ||||
| } | ||||
|  | ||||
| .card-footer div:last-child { | ||||
|     border-right: none; | ||||
| } | ||||
|  | ||||
| .card-footer span { | ||||
|     display: block; | ||||
|     font-size: 0.75rem; | ||||
|     color: var(--text-secondary); | ||||
| } | ||||
|  | ||||
| .card-footer strong { | ||||
|     font-size: 1rem; | ||||
|     font-weight: 700; | ||||
|     color: var(--text-primary); | ||||
| } | ||||
|  | ||||
| /* --- Media Query para Móvil --- */ | ||||
| @media (max-width: 480px) { | ||||
|     .cards-grid { | ||||
|         /* En pantallas muy pequeñas, forzamos una sola columna */ | ||||
|         grid-template-columns: 1fr; | ||||
|     } | ||||
|  | ||||
|     .card-header { | ||||
|         padding: 0.5rem; | ||||
|     } | ||||
|      | ||||
|     .header-info h3 { | ||||
|         font-size: 1rem; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* --- NUEVOS ESTILOS PARA EL NOMBRE DEL PARTIDO CUANDO ES EL TÍTULO PRINCIPAL --- */ | ||||
| .candidato-partido.main-title { | ||||
|     font-size: 0.95rem;      /* Hacemos la fuente más grande */ | ||||
|     font-weight: 700;        /* La ponemos en negrita, como el nombre del candidato */ | ||||
|     color: var(--text-primary); /* Usamos el color de texto principal */ | ||||
|     text-transform: none;    /* Quitamos el 'uppercase' para que se lea mejor */ | ||||
|     margin-bottom: 0.3rem; | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| // src/features/legislativas/nacionales/ResultadosNacionalesCardsWidget.tsx | ||||
| import { useQuery } from '@tanstack/react-query'; | ||||
| import { getResumenPorProvincia } from '../../../apiService'; | ||||
| import { ProvinciaCard } from './components/ProvinciaCard'; | ||||
| import './ResultadosNacionalesCardsWidget.css'; | ||||
|  | ||||
| interface Props { | ||||
|     eleccionId: number; | ||||
| } | ||||
|  | ||||
| export const ResultadosNacionalesCardsWidget = ({ eleccionId }: Props) => { | ||||
|     const { data, isLoading, error } = useQuery({ | ||||
|         queryKey: ['resumenPorProvincia', eleccionId], | ||||
|         queryFn: () => getResumenPorProvincia(eleccionId), | ||||
|     }); | ||||
|  | ||||
|     if (isLoading) return <div>Cargando resultados por provincia...</div>; | ||||
|     if (error) return <div>Error al cargar los datos.</div>; | ||||
|  | ||||
|     return ( | ||||
|         <section className="cards-widget-container"> | ||||
|             <h2>Resultados elecciones nacionales 2025</h2> | ||||
|             <div className="cards-grid"> | ||||
|                 {data?.map(provinciaData => ( | ||||
|                     <ProvinciaCard key={provinciaData.provinciaId} data={provinciaData} /> | ||||
|                 ))} | ||||
|             </div> | ||||
|         </section> | ||||
|     ); | ||||
| }; | ||||
| @@ -0,0 +1,64 @@ | ||||
| // src/features/legislativas/nacionales/components/MiniMapaSvg.tsx | ||||
| import { useQuery } from '@tanstack/react-query'; | ||||
| import axios from 'axios'; | ||||
| import { useMemo } from 'react'; | ||||
| import { assetBaseUrl } from '../../../../apiService'; | ||||
|  | ||||
| interface MiniMapaSvgProps { | ||||
|     provinciaNombre: string; | ||||
|     fillColor: string; | ||||
| } | ||||
|  | ||||
| // Función para normalizar el nombre de la provincia y que coincida con el nombre del archivo SVG | ||||
| const normalizarNombreParaUrl = (nombre: string) =>  | ||||
|     nombre | ||||
|         .toLowerCase() | ||||
|         .replace(/ /g, '_') // Reemplaza espacios con guiones bajos | ||||
|         .normalize("NFD")    // Descompone acentos para eliminarlos en el siguiente paso | ||||
|         .replace(/[\u0300-\u036f]/g, ""); // Elimina los acentos | ||||
|  | ||||
| export const MiniMapaSvg = ({ provinciaNombre, fillColor }: MiniMapaSvgProps) => { | ||||
|     const nombreNormalizado = normalizarNombreParaUrl(provinciaNombre); | ||||
|     // Asumimos que los SVGs están en /public/maps/provincias-svg/ | ||||
|     const mapFileUrl = `${assetBaseUrl}/maps/provincias-svg/${nombreNormalizado}.svg`; | ||||
|  | ||||
|     // Usamos React Query para fetchear el contenido del SVG como texto | ||||
|     const { data: svgContent, isLoading, isError } = useQuery<string>({ | ||||
|         queryKey: ['svgMapa', nombreNormalizado], | ||||
|         queryFn: async () => { | ||||
|             const response = await axios.get(mapFileUrl, { responseType: 'text' }); | ||||
|             return response.data; | ||||
|         }, | ||||
|         staleTime: Infinity, // Estos archivos son estáticos y no cambian | ||||
|         gcTime: Infinity, | ||||
|         retry: false, // No reintentar si el archivo no existe | ||||
|     }); | ||||
|  | ||||
|     // Usamos useMemo para modificar el SVG solo cuando el contenido o el color cambian | ||||
|     const modifiedSvg = useMemo(() => { | ||||
|         if (!svgContent) return ''; | ||||
|  | ||||
|         // Usamos una expresión regular para encontrar todas las etiquetas <path> | ||||
|         // y añadirles el atributo de relleno con el color del ganador. | ||||
|         // Esto sobrescribirá cualquier 'fill' que ya exista en la etiqueta. | ||||
|         return svgContent.replace(/<path/g, `<path fill="${fillColor}"`); | ||||
|     }, [svgContent, fillColor]); | ||||
|  | ||||
|     if (isLoading) { | ||||
|         return <div className="map-placeholder" />; | ||||
|     } | ||||
|  | ||||
|     if (isError || !modifiedSvg) { | ||||
|         // Muestra un placeholder si el SVG no se encontró o está vacío | ||||
|         return <div className="map-placeholder error" />; | ||||
|     } | ||||
|  | ||||
|     // Renderizamos el SVG modificado. dangerouslySetInnerHTML es seguro aquí | ||||
|     // porque el contenido proviene de nuestros propios archivos SVG estáticos. | ||||
|     return ( | ||||
|         <div  | ||||
|             className="map-svg-container"  | ||||
|             dangerouslySetInnerHTML={{ __html: modifiedSvg }}  | ||||
|         /> | ||||
|     ); | ||||
| }; | ||||
| @@ -0,0 +1,78 @@ | ||||
| // src/features/legislativas/nacionales/components/ProvinciaCard.tsx | ||||
| import type { ResumenProvincia } from '../../../../types/types'; | ||||
| import { MiniMapaSvg } from './MiniMapaSvg'; | ||||
| import { ImageWithFallback } from '../../../../components/common/ImageWithFallback'; | ||||
| import { assetBaseUrl } from '../../../../apiService'; | ||||
|  | ||||
| interface ProvinciaCardProps { | ||||
|     data: ResumenProvincia; | ||||
| } | ||||
|  | ||||
| const formatNumber = (num: number) => num.toLocaleString('es-AR'); | ||||
| const formatPercent = (num: number) => `${num.toFixed(2).replace('.', ',')}%`; | ||||
|  | ||||
| export const ProvinciaCard = ({ data }: ProvinciaCardProps) => { | ||||
|     // Determinamos el color del ganador para pasárselo al mapa. | ||||
|     // Si no hay ganador, usamos un color gris por defecto. | ||||
|     const colorGanador = data.resultados[0]?.color || '#d1d1d1'; | ||||
|  | ||||
|     return ( | ||||
|         <div className="provincia-card"> | ||||
|             <header className="card-header"> | ||||
|                 <div className="header-info"> | ||||
|                     <h3 style={{ whiteSpace: 'normal' }}>{data.provinciaNombre}</h3> | ||||
|                     <span>DIPUTADOS NACIONALES</span> | ||||
|                 </div> | ||||
|                 <div className="header-map"> | ||||
|                     <MiniMapaSvg provinciaNombre={data.provinciaNombre} fillColor={colorGanador} /> | ||||
|                 </div> | ||||
|             </header> | ||||
|             <div className="card-body"> | ||||
|                 {data.resultados.map(res => ( | ||||
|                     <div key={res.agrupacionId} className="candidato-row"> | ||||
|                         <ImageWithFallback src={res.fotoUrl ?? undefined} fallbackSrc={`${assetBaseUrl}/default-avatar.png`} alt={res.nombreCandidato ?? res.nombreAgrupacion} className="candidato-foto" /> | ||||
|  | ||||
|                         <div className="candidato-data"> | ||||
|                             {res.nombreCandidato && ( | ||||
|                                 <span className="candidato-nombre">{res.nombreCandidato}</span> | ||||
|                             )} | ||||
|  | ||||
|                             <span className={`candidato-partido ${!res.nombreCandidato ? 'main-title' : ''}`}> | ||||
|                                 {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> | ||||
|                         <div className="stats-bancas"> | ||||
|                             +{res.bancasObtenidas} | ||||
|                             <span>Bancas</span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 ))} | ||||
|             </div> | ||||
|             <footer className="card-footer"> | ||||
|                 <div> | ||||
|                     <span>Participación</span> | ||||
|                     {/* Usamos los datos reales del estado de recuento */} | ||||
|                     <strong>{formatPercent(data.estadoRecuento?.participacionPorcentaje ?? 0)}</strong> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                     <span>Mesas escrutadas</span> | ||||
|                     <strong>{formatPercent(data.estadoRecuento?.mesasTotalizadasPorcentaje ?? 0)}</strong> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                     <span>Votos totales</span> | ||||
|                     {/* Usamos el nuevo campo cantidadVotantes */} | ||||
|                     <strong>{formatNumber(data.estadoRecuento?.cantidadVotantes ?? 0)}</strong> | ||||
|                 </div> | ||||
|             </footer> | ||||
|         </div> | ||||
|     ); | ||||
| }; | ||||
| @@ -1,27 +1,35 @@ | ||||
| /* src/features/legislativas/provinciales/CongresoWidget.css */ | ||||
| .congreso-container { | ||||
|   display: flex; | ||||
|   /* Se reduce ligeramente el espacio entre el gráfico y el panel */ | ||||
|   gap: 1rem; | ||||
|   gap: 1.5rem; | ||||
|   background-color: #ffffff; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); | ||||
|   padding: 1rem; | ||||
|   border-radius: 8px; | ||||
|   max-width: 800px; | ||||
|   max-width: 900px; | ||||
|   margin: 20px auto; | ||||
|   font-family: "Public Sans", system-ui, sans-serif; | ||||
|   color: #333333; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .congreso-grafico { | ||||
|   /* --- CAMBIO PRINCIPAL: Se aumenta la proporción del gráfico --- */ | ||||
|   flex: 1 1 65%; | ||||
|   flex: 2;  | ||||
|   min-width: 300px; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| } | ||||
|  | ||||
| .congreso-hemiciclo-wrapper { | ||||
|   flex-grow: 1; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .congreso-hemiciclo-wrapper.is-hovering .party-block:not(:hover) { | ||||
|   opacity: 0.4; | ||||
| } | ||||
|  | ||||
| .congreso-grafico svg { | ||||
| @@ -30,35 +38,139 @@ | ||||
|   animation: fadeIn 0.8s ease-in-out; | ||||
| } | ||||
|  | ||||
| @keyframes fadeIn { | ||||
|   from { | ||||
|     opacity: 0; | ||||
|     transform: scale(0.9); | ||||
|   } | ||||
| /* --- NUEVOS ESTILOS PARA EL FOOTER DEL GRÁFICO --- */ | ||||
| .congreso-footer { | ||||
|   width: 100%; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   padding: 0.5rem 1rem 0 1rem; | ||||
|   margin-top: auto; /* Empuja el footer a la parte inferior del contenedor flex */ | ||||
|   font-size: 0.8em; | ||||
|   color: #666; | ||||
|   border-top: 1px solid #eee; | ||||
| } | ||||
|  | ||||
|   to { | ||||
|     opacity: 1; | ||||
|     transform: scale(1); | ||||
|   } | ||||
| .footer-legend { | ||||
|   display: flex; | ||||
|   gap: 1.5rem; /* Espacio entre los items de la leyenda */ | ||||
| } | ||||
|  | ||||
| .footer-legend-item { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 0.5rem; /* Espacio entre el icono y el texto */ | ||||
| } | ||||
|  | ||||
| .footer-timestamp { | ||||
|   font-weight: 500; | ||||
| } | ||||
|  | ||||
| /* --- ESTILOS PARA HOVER --- */ | ||||
|  | ||||
| /* Estilo base para cada círculo de escaño */ | ||||
| .seat-circle { | ||||
|   transition: all 0.2s ease-in-out; | ||||
| } | ||||
|  | ||||
| .party-block { | ||||
|   cursor: pointer; | ||||
|   transition: opacity 0.2s ease-in-out; | ||||
| } | ||||
|  | ||||
| .party-block:hover .seat-circle { | ||||
|   stroke: #333 !important; /* Borde oscuro para resaltar */ | ||||
|   stroke-width: 1.5px !important; | ||||
|   stroke-opacity: 1; | ||||
|   filter: brightness(1.1); | ||||
| } | ||||
|  | ||||
| /* CORRECCIÓN: El selector ahora apunta al wrapper correcto */ | ||||
| .congreso-hemiciclo-wrapper.is-hovering .party-block:not(:hover) { | ||||
|   opacity: 0.3; /* Hacemos el desvanecimiento más pronunciado */ | ||||
| } | ||||
| .congreso-grafico svg { | ||||
|   width: 100%; | ||||
|   height: auto; | ||||
|   animation: fadeIn 0.8s ease-in-out; | ||||
| } | ||||
|  | ||||
| @keyframes fadeIn { | ||||
|   from { opacity: 0; transform: scale(0.9); } | ||||
|   to { opacity: 1; transform: scale(1); } | ||||
| } | ||||
|  | ||||
| /* --- INICIO DE NUEVOS ESTILOS PARA EL FOOTER DEL GRÁFICO --- */ | ||||
| .congreso-footer { | ||||
|   width: 100%; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   padding: 0.75rem 0.5rem 0 0.5rem; | ||||
|   margin-top: auto; | ||||
|   font-size: 0.8em; | ||||
|   color: #666; | ||||
|   border-top: 1px solid #eee; | ||||
| } | ||||
|  | ||||
| .footer-legend { | ||||
|   display: flex; | ||||
|   gap: 1.25rem; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .footer-legend-item { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 0.6rem; | ||||
|   font-size: 1.1em; | ||||
| } | ||||
|  | ||||
| /* Creamos una clase base para ambos iconos para compartir tamaño */ | ||||
| .legend-icon { | ||||
|   display: inline-block; | ||||
|   width: 14px;   /* Tamaño base para ambos iconos */ | ||||
|   height: 14px; | ||||
|   border-radius: 50%; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
|  | ||||
| /* Estilo para el icono de "Bancas en juego" (círculo sólido) */ | ||||
| .legend-icon--solid { | ||||
|   background-color: #888; | ||||
|   border: 1px solid #777; | ||||
| } | ||||
|  | ||||
| /* Estilo para el icono de "Bancas previas" (anillo translúcido) */ | ||||
| .legend-icon--ring { | ||||
|   background-color: rgba(136, 136, 136, 0.3); /* #888 con opacidad */ | ||||
|   border: 1px solid #888; /* Borde sólido del mismo color */ | ||||
| } | ||||
|  | ||||
| .footer-timestamp { | ||||
|   font-weight: 500; | ||||
|   font-size: 0.75em; | ||||
| } | ||||
|  | ||||
| .congreso-summary { | ||||
|   /* --- CAMBIO PRINCIPAL: Se reduce la proporción del panel de datos --- */ | ||||
|   flex: 1 1 35%; | ||||
|   flex: 1;  | ||||
|   border-left: 1px solid #e0e0e0; | ||||
|   /* Se reduce el padding para dar aún más espacio al gráfico */ | ||||
|   padding-left: 1rem; | ||||
|   padding-left: 1.25rem; /* Un poco más de padding */ | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   justify-content: flex-start;  | ||||
| } | ||||
|  | ||||
| .congreso-summary h3 { | ||||
|   margin-top: 0; | ||||
|   margin-bottom: 0.75rem; /* Margen inferior reducido */ | ||||
|   font-size: 1.4em; | ||||
|   color: #212529; | ||||
| } | ||||
|  | ||||
| .chamber-tabs { | ||||
|   display: flex; | ||||
|   margin-bottom: 1.5rem; | ||||
|   margin-bottom: 1rem; /* Margen inferior reducido */ | ||||
|   border: 1px solid #dee2e6; | ||||
|   border-radius: 6px; | ||||
|   overflow: hidden; | ||||
| @@ -66,7 +178,7 @@ | ||||
|  | ||||
| .chamber-tabs button { | ||||
|   flex: 1; | ||||
|   padding: 0.75rem 0.5rem; | ||||
|   padding: 0.5rem 0.5rem; | ||||
|   border: none; | ||||
|   background-color: #f8f9fa; | ||||
|   color: #6c757d; | ||||
| @@ -94,7 +206,7 @@ | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: baseline; | ||||
|   margin-bottom: 0.5rem; | ||||
|   margin-bottom: 0.25rem; /* Margen inferior muy reducido */ | ||||
|   font-size: 1.1em; | ||||
| } | ||||
|  | ||||
| @@ -107,7 +219,15 @@ | ||||
| .congreso-summary hr { | ||||
|   border: none; | ||||
|   border-top: 1px solid #e0e0e0; | ||||
|   margin: 1.5rem 0; | ||||
|   margin: 1rem 0; /* Margen vertical reducido */ | ||||
| } | ||||
|  | ||||
| /* Contenedor de la lista de partidos para aplicar el scroll */ | ||||
| .partido-lista-container { | ||||
|     flex-grow: 1; /* Ocupa el espacio vertical disponible */ | ||||
|     overflow-y: auto; /* Muestra el scrollbar si es necesario */ | ||||
|     min-height: 0; /* Truco de Flexbox para que el scroll funcione */ | ||||
|     padding-right: 8px; /* Espacio para el scrollbar */ | ||||
| } | ||||
|  | ||||
| .partido-lista { | ||||
| @@ -119,14 +239,14 @@ | ||||
| .partido-lista li { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   margin-bottom: 0.75rem; | ||||
|   margin-bottom: 0.85rem; /* Un poco más de espacio entre items */ | ||||
| } | ||||
|  | ||||
| .partido-color-box { | ||||
|   width: 14px; | ||||
|   height: 14px; | ||||
|   border-radius: 3px; | ||||
|   margin-right: 10px; | ||||
|   width: 16px;  /* Cuadro de color más grande */ | ||||
|   height: 16px; | ||||
|   border-radius: 4px; /* Un poco más cuadrado */ | ||||
|   margin-right: 12px; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| @@ -139,19 +259,54 @@ | ||||
|   font-size: 1.1em; | ||||
| } | ||||
|  | ||||
| /* --- Media Query para Responsividad Móvil --- */ | ||||
| /* --- Media Query para Responsividad Móvil (HASTA 768px) --- */ | ||||
| @media (max-width: 768px) { | ||||
|   .congreso-container { | ||||
|     flex-direction: column; | ||||
|     padding: 1.5rem; | ||||
|     padding: 0.5rem; | ||||
|     height: auto; | ||||
|     max-height: none; | ||||
|   } | ||||
|  | ||||
|   .congreso-summary { | ||||
|     border-left: none; | ||||
|     padding-left: 0; | ||||
|     margin-top: 2rem; | ||||
|     border-top: 1px solid #e0e0e0; | ||||
|     padding-top: 1.5rem; | ||||
|   } | ||||
|  | ||||
|   .partido-lista-container { | ||||
|     overflow-y: visible; | ||||
|     max-height: none; | ||||
|   } | ||||
|  | ||||
|   .congreso-footer { | ||||
|     flex-direction: column; /* Apila la leyenda y el timestamp verticalmente */ | ||||
|     align-items: flex-start; /* Alinea todo a la izquierda */ | ||||
|     gap: 0.5rem; /* Añade un pequeño espacio entre la leyenda y el timestamp */ | ||||
|     padding: 0.75rem 0rem; /* Ajusta el padding para móvil */ | ||||
|     align-items: center; | ||||
|   } | ||||
|  | ||||
|   .footer-legend { | ||||
|     gap: 0.75rem; /* Reduce el espacio entre los items de la leyenda */ | ||||
|   } | ||||
|  | ||||
|   .footer-legend-item{ | ||||
|     font-size: 1em; | ||||
|   } | ||||
|  | ||||
|   .footer-timestamp { | ||||
|     font-size: 0.75em; /* Reduce el tamaño de la fuente para que quepa mejor */ | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* --- Media Query para Escritorio (DESDE 769px en adelante) --- */ | ||||
| @media (min-width: 769px) { | ||||
|   .congreso-container { | ||||
|     flex-direction: row; | ||||
|     align-items: stretch; | ||||
|     height: 500px;  | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -245,4 +245,29 @@ export interface PanelElectoralDto { | ||||
|   mapaData: ResultadoMapaDto[]; | ||||
|   resultadosPanel: ResultadoTicker[]; // Reutilizamos el tipo que ya tienes | ||||
|   estadoRecuento: EstadoRecuentoTicker; // Reutilizamos el tipo que ya tienes | ||||
| } | ||||
|  | ||||
| // --- TIPOS PARA EL WIDGET DE TARJETAS --- | ||||
| export interface EstadoRecuentoDto { | ||||
|     participacionPorcentaje: number; | ||||
|     mesasTotalizadasPorcentaje: number; | ||||
|     cantidadVotantes: number; | ||||
| } | ||||
|  | ||||
| export interface ResultadoCandidato { | ||||
|     agrupacionId: string; | ||||
|     nombreCandidato: string | null; | ||||
|     nombreAgrupacion: string; | ||||
|     fotoUrl: string | null; | ||||
|     color: string | null; | ||||
|     porcentaje: number; | ||||
|     votos: number; | ||||
|     bancasObtenidas: number; | ||||
| } | ||||
|  | ||||
| export interface ResumenProvincia { | ||||
|     provinciaId: string; | ||||
|     provinciaNombre: string; | ||||
|     estadoRecuento: EstadoRecuentoDto | null; | ||||
|     resultados: ResultadoCandidato[]; | ||||
| } | ||||