Moved podium and fixed create button
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
// frontend/src/components/Tournament/Podium.jsx
|
||||
|
||||
import { Trophy } from 'lucide-react';
|
||||
|
||||
export default function Podium({ matches }) {
|
||||
const isDoubleElim = matches.some(m => m.bracket === 'Loser');
|
||||
|
||||
const wb = matches.filter(m => m.bracket === 'Winner').sort((a, b) => a.round - b.round);
|
||||
const lb = matches.filter(m => m.bracket === 'Loser').sort((a, b) => a.round - b.round);
|
||||
const finals = matches.filter(m => m.bracket === 'Finals').sort((a, b) => a.round - b.round);
|
||||
|
||||
let gfMatch = null;
|
||||
let resetMatch = null;
|
||||
let tpMatch = null;
|
||||
|
||||
if (isDoubleElim) {
|
||||
tpMatch = lb[lb.length - 1];
|
||||
gfMatch = finals[0];
|
||||
resetMatch = finals[1];
|
||||
} else {
|
||||
gfMatch = wb[wb.length - 1];
|
||||
tpMatch = finals[0];
|
||||
}
|
||||
|
||||
const podium = [
|
||||
{ rank: 1, label: "1st", team: "TBD", isReal: false, color: "bg-yellow-400 text-yellow-900 dark:text-yellow-950 shadow-yellow-400/50" },
|
||||
{ rank: 2, label: "2nd", team: "TBD", isReal: false, color: "bg-zinc-300 dark:bg-zinc-400 text-zinc-800 dark:text-zinc-900 shadow-zinc-400/50" },
|
||||
{ rank: 3, label: "3rd", team: "TBD", isReal: false, color: "bg-amber-600 text-amber-50 dark:text-amber-50 shadow-amber-600/50", hidden: false }
|
||||
];
|
||||
|
||||
// --- CALCULATE 3RD PLACE ---
|
||||
if (tpMatch) {
|
||||
if (tpMatch.isFinished && tpMatch.winnerName) {
|
||||
// If match is done, grab the actual team name
|
||||
podium[2].team = isDoubleElim
|
||||
? (tpMatch.winnerName === tpMatch.p1 ? tpMatch.p2 : tpMatch.p1) // DE: Loser of LB Final
|
||||
: tpMatch.winnerName; // SE: Winner of 3rd Place Match
|
||||
podium[2].isReal = true;
|
||||
} else {
|
||||
// Set the exact string expected by the print formatter
|
||||
podium[2].team = isDoubleElim ? `Loser of #${tpMatch.number}` : `Winner of #${tpMatch.number}`;
|
||||
}
|
||||
} else {
|
||||
podium[2].hidden = true;
|
||||
}
|
||||
|
||||
// --- CALCULATE 1ST & 2ND PLACE ---
|
||||
if (resetMatch && resetMatch.isFinished && resetMatch.winnerName) {
|
||||
podium[0].team = resetMatch.winnerName;
|
||||
podium[0].isReal = true;
|
||||
podium[1].team = resetMatch.winnerName === resetMatch.p1 ? resetMatch.p2 : resetMatch.p1;
|
||||
podium[1].isReal = true;
|
||||
} else if (gfMatch) {
|
||||
if (gfMatch.isFinished && gfMatch.winnerName) {
|
||||
// Has the loser bracket champ won, forcing a reset?
|
||||
const isResetForced = resetMatch && resetMatch.hasTeams;
|
||||
|
||||
if (!isResetForced) {
|
||||
// GF Winner is 1st, GF Loser is 2nd
|
||||
podium[0].team = gfMatch.winnerName;
|
||||
podium[0].isReal = true;
|
||||
podium[1].team = gfMatch.winnerName === gfMatch.p1 ? gfMatch.p2 : gfMatch.p1;
|
||||
podium[1].isReal = true;
|
||||
} else {
|
||||
// Reset forced, wait for the final match
|
||||
podium[0].team = `Winner of #${resetMatch.number}`;
|
||||
podium[1].team = `Loser of #${resetMatch.number}`;
|
||||
}
|
||||
} else {
|
||||
// GF not finished yet
|
||||
podium[0].team = `Winner of #${gfMatch.number}`;
|
||||
podium[1].team = `Loser of #${gfMatch.number}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper for rendering print strings (Takes "Winner of #7" -> "W#7: _______")
|
||||
const printName = (name) => {
|
||||
if (!name) return '';
|
||||
if (name.startsWith('Winner of #')) return name.replace('Winner of #', 'W#') + ': _______';
|
||||
if (name.startsWith('Loser of #')) return name.replace('Loser of #', 'L#') + ': _______';
|
||||
return name;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white dark:bg-zinc-900 print:!bg-white border border-zinc-200 dark:border-zinc-800 print:!border-zinc-400 rounded-xl shadow-sm w-64 overflow-hidden z-10 print:!shadow-none">
|
||||
<div className="bg-zinc-50 dark:bg-zinc-900/50 print:!bg-transparent p-3 border-b border-zinc-200 dark:border-zinc-800 print:!border-zinc-400">
|
||||
<h3 className="text-[10px] font-black uppercase tracking-[0.2em] text-zinc-500 print:!text-zinc-600 text-center flex items-center justify-center gap-2">
|
||||
<Trophy size={14} className="text-orange-500 print:!text-black" /> Final Standings
|
||||
</h3>
|
||||
</div>
|
||||
<div className="p-4 space-y-4">
|
||||
{podium.filter(p => !p.hidden).map(p => (
|
||||
<div key={p.rank} className="flex items-center gap-3">
|
||||
<div className={`w-7 h-7 rounded-full flex items-center justify-center font-black text-xs shrink-0 shadow-sm print:!shadow-none print:!bg-white print:!border print:!border-zinc-400 print:!text-black ${p.color}`}>
|
||||
{p.rank}
|
||||
</div>
|
||||
{/* Web Label */}
|
||||
<div className={`text-sm truncate print:hidden ${p.isReal ? 'font-bold text-zinc-900 dark:text-white print:!text-black' : 'font-medium italic text-zinc-400 print:!text-zinc-600'}`} title={p.team}>
|
||||
{p.team}
|
||||
</div>
|
||||
{/* Print Label */}
|
||||
<div className={`hidden print:block text-sm print:whitespace-normal print:overflow-visible ${p.isReal ? 'font-bold print:!text-black' : 'font-medium italic print:!text-zinc-600'}`}>
|
||||
{printName(p.team)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user