Files
Elecciones-2025/Elecciones-Web/frontend/src/components/ParliamentLayout.tsx

186 lines
14 KiB
TypeScript
Raw Normal View History

// src/components/ParliamentLayout.tsx
import React from 'react';
// Interfaces (no cambian)
interface SeatFillData {
color: string;
// Añadimos la propiedad opcional 'ocupante'
ocupante?: {
nombreOcupante: string;
fotoUrl: string | null;
} | null;
}
interface ParliamentLayoutProps {
seatData: SeatFillData[];
size?: number;
presidenteBancada: { color: string | null } | null;
}
const PRESIDENTE_SEAT_INDEX = 91;
export const ParliamentLayout: React.FC<ParliamentLayoutProps> = ({
seatData,
size = 400,
presidenteBancada,
}) => {
const uniqueColors = [...new Set(seatData.map(d => d.color))];
// --- NUEVO ARRAY DE ELEMENTOS ORDENADO ---
const seatElements = [
<circle key="seat-0" id="seat-0" r="12" cy="268.306" cx="202.26" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-1" id="seat-1" r="12" cy="214.247" cx="223.62" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-2" id="seat-2" r="12" cy="253.417" cx="184.047" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-3" id="seat-3" r="12" cy="290.475" cx="148.465" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-4" id="seat-4" r="12" cy="199.221" cx="204.812" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-5" id="seat-5" r="12" cy="238.165" cx="165.39" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-6" id="seat-6" r="12" cy="274.606" cx="129.053" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-7" id="seat-7" r="12" cy="307.801" cx="95.891" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-8" id="seat-8" r="12" cy="184.139" cx="184.653" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-9" id="seat-9" r="12" cy="223.156" cx="147.029" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-10" id="seat-10" r="12" cy="259.444" cx="110.504" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-11" id="seat-11" r="12" cy="291.519" cx="75.175" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-12" id="seat-12" r="12" cy="169.647" cx="164.36" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-13" id="seat-13" r="12" cy="209.251" cx="125.789" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-14" id="seat-14" r="12" cy="246.564" cx="88.133" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-15" id="seat-15" r="12" cy="280.15" cx="51.596" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-16" id="seat-16" r="12" cy="157.248" cx="142.356" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-17" id="seat-17" r="12" cy="197.635" cx="103.42" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-18" id="seat-18" r="12" cy="238.303" cx="63.378" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-19" id="seat-19" r="12" cy="145.84" cx="118.145" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-20" id="seat-20" r="12" cy="187.919" cx="77.562" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-21" id="seat-21" r="12" cy="137.535" cx="91.746" transform="matrix(-0.632908, 0.774227, 0.774227, 0.632908, 0, 0)" />,
<circle key="seat-22" id="seat-22" r="12" cy="123.093" cx="-70.302" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-23" id="seat-23" r="12" cy="143.999" cx="-118.288" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-24" id="seat-24" r="12" cy="163.733" cx="-163.582" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-25" id="seat-25" r="12" cy="183.347" cx="-208.602" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-26" id="seat-26" r="12" cy="102.267" cx="-85.471" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-27" id="seat-27" r="12" cy="125.122" cx="-134.967" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-28" id="seat-28" r="12" cy="145.407" cx="-182.84" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-29" id="seat-29" r="12" cy="167.585" cx="-230.037" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-30" id="seat-30" r="12" cy="82.48" cx="-104.338" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-31" id="seat-31" r="12" cy="108.082" cx="-153.63" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-32" id="seat-32" r="12" cy="132.154" cx="-203.666" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-33" id="seat-33" r="12" cy="160.283" cx="-255.056" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-34" id="seat-34" r="12" cy="66.206" cx="-124.894" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-35" id="seat-35" r="12" cy="93.477" cx="-175.808" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-36" id="seat-36" r="12" cy="121.335" cx="-226.656" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-37" id="seat-37" r="12" cy="51.554" cx="-147.409" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-38" id="seat-38" r="12" cy="82.117" cx="-199.609" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-39" id="seat-39" r="12" cy="114.844" cx="-252.766" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-40" id="seat-40" r="12" cy="39.969" cx="-171.147" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-41" id="seat-41" r="12" cy="74.003" cx="-224.493" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-42" id="seat-42" r="12" cy="30.215" cx="-197.157" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-43" id="seat-43" r="12" cy="68.323" cx="-249.04" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-44" id="seat-44" r="12" cy="22.948" cx="-223.55" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
<circle key="seat-45" id="seat-45" r="12" cy="22.948" cx="328.246" />,
<circle key="seat-46" id="seat-46" r="12" cy="68.323" cx="302.756" />,
<circle key="seat-47" id="seat-47" r="12" cy="114.844" cx="299.029" />,
<circle key="seat-48" id="seat-48" r="12" cy="160.283" cx="296.74" />,
<circle key="seat-49" id="seat-49" r="12" cy="30.215" cx="354.639" />,
<circle key="seat-50" id="seat-50" r="12" cy="74.003" cx="327.303" />,
<circle key="seat-51" id="seat-51" r="12" cy="121.335" cx="325.14" />,
<circle key="seat-52" id="seat-52" r="12" cy="167.585" cx="321.759" />,
<circle key="seat-53" id="seat-53" r="12" cy="39.969" cx="380.649" />,
<circle key="seat-54" id="seat-54" r="12" cy="82.117" cx="352.187" />,
<circle key="seat-55" id="seat-55" r="12" cy="132.154" cx="348.129" />,
<circle key="seat-56" id="seat-56" r="12" cy="183.347" cx="343.194" />,
<circle key="seat-57" id="seat-57" r="12" cy="51.554" cx="404.387" />,
<circle key="seat-58" id="seat-58" r="12" cy="93.477" cx="375.988" />,
<circle key="seat-59" id="seat-59" r="12" cy="145.407" cx="368.956" />,
<circle key="seat-60" id="seat-60" r="12" cy="66.206" cx="426.902" />,
<circle key="seat-61" id="seat-61" r="12" cy="108.082" cx="398.166" />,
<circle key="seat-62" id="seat-62" r="12" cy="163.733" cx="388.214" />,
<circle key="seat-63" id="seat-63" r="12" cy="82.48" cx="447.457" />,
<circle key="seat-64" id="seat-64" r="12" cy="125.122" cx="416.829" />,
<circle key="seat-65" id="seat-65" r="12" cy="102.267" cx="466.325" />,
<circle key="seat-66" id="seat-66" r="12" cy="143.999" cx="433.508" />,
<circle key="seat-67" id="seat-67" r="12" cy="123.093" cx="481.494" />,
<circle key="seat-68" id="seat-68" r="12" cy="-289.68" cx="440.983" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-69" id="seat-69" r="12" cy="-239.296" cx="426.798" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-70" id="seat-70" r="12" cy="-188.912" cx="412.614" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-71" id="seat-71" r="12" cy="-147.065" cx="400.833" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-72" id="seat-72" r="12" cy="-281.375" cx="467.381" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-73" id="seat-73" r="12" cy="-229.58" cx="452.656" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-74" id="seat-74" r="12" cy="-180.651" cx="437.369" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-75" id="seat-75" r="12" cy="-135.696" cx="424.411" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-76" id="seat-76" r="12" cy="-269.967" cx="491.592" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-77" id="seat-77" r="12" cy="-217.964" cx="475.026" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-78" id="seat-78" r="12" cy="-167.771" cx="459.741" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-79" id="seat-79" r="12" cy="-119.414" cx="445.127" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-80" id="seat-80" r="12" cy="-257.568" cx="513.597" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-81" id="seat-81" r="12" cy="-204.059" cx="496.265" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-82" id="seat-82" r="12" cy="-152.609" cx="478.289" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-83" id="seat-83" r="12" cy="-243.076" cx="533.889" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-84" id="seat-84" r="12" cy="-189.049" cx="514.627" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-85" id="seat-85" r="12" cy="-136.74" cx="497.701" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-86" id="seat-86" r="12" cy="-227.994" cx="554.048" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-87" id="seat-87" r="12" cy="-173.798" cx="533.284" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-88" id="seat-88" r="12" cy="-212.968" cx="572.857" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-89" id="seat-89" r="12" cy="-158.909" cx="551.496" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-90" id="seat-90" r="12" cy="-197.942" cx="591.665" transform="matrix(0.632908, 0.774227, -0.774227, 0.632908, 0, 0)" />,
<circle key="seat-91" id="seat-91" r="12" cy="308.5" cx="-275.898" transform="matrix(-1, 0, 0, 1, 0, 0)" />,
];
// Creamos una copia mutable de los datos de asientos para poder modificarla.
const finalSeatData = [...seatData];
// Si hay un presidente y su partido tiene bancas, le quitamos una para asignarla.
if (presidenteBancada && presidenteBancada.color) {
// Encontramos el índice del último asiento que pertenece al partido del presidente.
const lastSeatIndex = finalSeatData.map(s => s.color).lastIndexOf(presidenteBancada.color);
if (lastSeatIndex !== -1) {
// Eliminamos ese asiento de la lista de asientos electorales.
finalSeatData.splice(lastSeatIndex, 1);
}
}
const renderedElements = seatElements.map((child, index) => {
// El asiento presidencial sigue siendo un caso especial
if (index === PRESIDENTE_SEAT_INDEX) {
return React.cloneElement(child, {
fill: presidenteBancada?.color || '#A9A9A9',
stroke: '#000000',
strokeWidth: 2,
});
}
// La lógica ahora es simple: el asiento en el índice X del SVG
// corresponde al asiento en el índice X de los datos.
const seat = seatData[index];
if (!seat) {
return React.cloneElement(child, { fill: '#E0E0E0', stroke: '#ffffff', strokeWidth: 1.5 });
}
return React.cloneElement(child, {
fill: seat.color,
stroke: '#ffffff',
strokeWidth: 1.5,
'data-tooltip-id': seat.ocupante ? 'seat-tooltip' : undefined,
'data-tooltip-html': seat.ocupante
? `<div class="seat-tooltip"><img src="${seat.ocupante.fotoUrl || '/default-avatar.png'}" alt="${seat.ocupante.nombreOcupante}" /><p>${seat.ocupante.nombreOcupante}</p></div>`
: undefined,
});
});
return (
<svg viewBox="0 0 550 375" width={size} height={size * (375 / 550)} style={{ display: 'block', margin: 'auto' }}>
<defs>
{uniqueColors.map(color => {
const patternId = `stripes-${color.replace('#', '')}`;
return (
<pattern key={patternId} id={patternId} patternUnits="userSpaceOnUse" width="4" height="4" patternTransform="rotate(45)">
<rect width="4" height="4" fill={color}></rect>
<path d="M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2" stroke="rgba(255,255,255,0.7)" strokeWidth="3"></path>
</pattern>
);
})}
</defs>
<g transform="matrix(1, 0, 0, 1, 1.166021, 0.583011)">
{renderedElements}
</g>
</svg>
);
};