fixed error loading data

This commit is contained in:
2026-03-15 11:48:33 +01:00
parent 05cb6fee88
commit 8bf6cc427a

View File

@@ -233,14 +233,12 @@
<!-- Main Content --> <!-- Main Content -->
<main class="w-full max-w-[1600px] mx-auto px-4 sm:px-6 lg:px-8 flex flex-col gap-6 lg:gap-8"> <main class="w-full max-w-[1600px] mx-auto px-4 sm:px-6 lg:px-8 flex flex-col gap-6 lg:gap-8">
<!-- TOP ROW -->
<!-- TOP ROW: CAST & MATRIX -->
<div class="grid grid-cols-1 xl:grid-cols-12 gap-6 lg:gap-8 items-start"> <div class="grid grid-cols-1 xl:grid-cols-12 gap-6 lg:gap-8 items-start">
<!-- LEFT COLUMN: INPUTS --> <!-- LEFT COLUMN: THE CAST (Setup) -->
<div class="xl:col-span-3 flex flex-col gap-6"> <div class="xl:col-span-3 flex flex-col gap-6">
<!-- 1. The Cast -->
<section class="theme-panel rounded-3xl p-6 shadow-xl animate-slide-in"> <section class="theme-panel rounded-3xl p-6 shadow-xl animate-slide-in">
<div class="flex items-center gap-3 mb-6 border-b pb-4" style="border-color: var(--panel-border);"> <div class="flex items-center gap-3 mb-6 border-b pb-4" style="border-color: var(--panel-border);">
<i data-lucide="users" class="w-6 h-6 theme-primary-text"></i> <i data-lucide="users" class="w-6 h-6 theme-primary-text"></i>
@@ -275,9 +273,59 @@
</section> </section>
</div> </div>
<!-- RIGHT COLUMN: RESULTS --> <!-- RIGHT COLUMN: RESULTS DASHBOARD & MATRIX -->
<div class="xl:col-span-9 flex flex-col gap-6"> <div class="xl:col-span-9 flex flex-col gap-6">
<!-- Status Dashboard -->
<section id="status-dashboard" class="hidden animate-slide-in">
<div class="theme-panel rounded-3xl p-8 relative overflow-hidden flex flex-col md:flex-row items-center justify-between gap-6 shadow-2xl">
<div class="absolute -right-16 -top-16 w-64 h-64 rounded-full blur-3xl opacity-20" style="background: var(--primary); z-index: 0;"></div>
<div style="z-index: 1;">
<h3 class="text-xs font-black uppercase tracking-[0.2em] mb-2 theme-text-muted">Verbleibende Möglichkeiten</h3>
<p id="total-possibilities" class="text-5xl sm:text-7xl font-black tracking-tighter neon-glow" style="color: var(--primary);">--</p>
</div>
<div class="w-full md:w-auto flex flex-col gap-3" style="z-index: 1;">
<button id="calculate-button" class="w-full theme-btn py-4 px-8 rounded-xl flex items-center justify-center gap-3">
<i data-lucide="refresh-cw" class="w-5 h-5"></i> NEU BERECHNEN
</button>
<div class="flex items-center justify-center gap-2">
<span class="w-2 h-2 rounded-full animate-pulse" style="background: var(--success);"></span>
<span class="text-[10px] font-bold uppercase tracking-widest theme-text-muted">Live Engine Active</span>
</div>
</div>
</div>
</section>
<!-- Probability Matrix -->
<section id="grid-section" class="hidden theme-panel rounded-3xl p-6 shadow-2xl animate-slide-in">
<div class="flex flex-col xl:flex-row xl:items-end justify-between gap-4 mb-6">
<div>
<h2 class="text-2xl font-black tracking-tight mb-1 theme-text">Match-Matrix</h2>
<p class="text-xs font-bold uppercase tracking-widest theme-text-muted">Wahrscheinlichkeit pro Paar</p>
</div>
<div class="flex flex-wrap gap-2 text-[10px] font-bold tracking-widest">
<div class="px-3 py-1.5 rounded-lg flex items-center gap-2 border" style="background: rgba(0,255,136,0.1); color: var(--success); border-color: rgba(0,255,136,0.3);">
<i data-lucide="check-circle" class="w-3 h-3"></i> 100% MATCH
</div>
<div class="px-3 py-1.5 rounded-lg flex items-center gap-2 border" style="background: rgba(255,51,51,0.1); color: var(--error); border-color: rgba(255,51,51,0.3);">
<i data-lucide="x-circle" class="w-3 h-3"></i> UNMÖGLICH
</div>
</div>
</div>
<div class="overflow-x-auto border rounded-xl" style="border-color: var(--panel-border);">
<table id="probability-table" class="w-full text-left border-collapse">
<thead id="probability-table-head" style="background: var(--input-bg);" class="text-[10px] font-black uppercase tracking-widest theme-text-muted"></thead>
<tbody id="probability-table-body" class="divide-y" style="border-color: var(--panel-border);"></tbody>
</table>
</div>
</section>
</div>
</div>
<!-- BOTTOM ROW: TRUTH BOOTH & MATCHING NIGHT -->
<div id="input-sections" class="hidden grid grid-cols-1 xl:grid-cols-2 gap-6 lg:gap-8 items-start">
<!-- 2. Truth Booth --> <!-- 2. Truth Booth -->
<section class="theme-panel rounded-3xl p-6 shadow-xl animate-slide-in"> <section class="theme-panel rounded-3xl p-6 shadow-xl animate-slide-in">
<div class="flex items-center gap-3 mb-6 border-b pb-4" style="border-color: var(--panel-border);"> <div class="flex items-center gap-3 mb-6 border-b pb-4" style="border-color: var(--panel-border);">
@@ -312,11 +360,11 @@
<div class="theme-input rounded-xl p-4 mb-4 flex items-center justify-between border-2" style="border-color: var(--panel-border);"> <div class="theme-input rounded-xl p-4 mb-4 flex items-center justify-between border-2" style="border-color: var(--panel-border);">
<span class="text-xs font-black uppercase tracking-widest theme-text-muted">Lichter (Beams)</span> <span class="text-xs font-black uppercase tracking-widest theme-text-muted">Lichter (Beams)</span>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<button type="button" onclick="ceremony_beams.stepDown()" class="w-8 h-8 flex items-center justify-center hover:bg-black/20 rounded-lg theme-text"> <button type="button" onclick="document.getElementById('ceremony-beams').stepDown()" class="w-8 h-8 flex items-center justify-center hover:bg-black/20 rounded-lg theme-text">
<i data-lucide="minus" class="w-4 h-4"></i> <i data-lucide="minus" class="w-4 h-4"></i>
</button> </button>
<input type="number" id="ceremony-beams" min="0" value="0" class="w-12 bg-transparent text-center font-black text-2xl focus:outline-none theme-text"> <input type="number" id="ceremony-beams" min="0" value="0" class="w-12 bg-transparent text-center font-black text-2xl focus:outline-none theme-text">
<button type="button" onclick="ceremony_beams.stepUp()" class="w-8 h-8 flex items-center justify-center hover:bg-black/20 rounded-lg theme-text"> <button type="button" onclick="document.getElementById('ceremony-beams').stepUp()" class="w-8 h-8 flex items-center justify-center hover:bg-black/20 rounded-lg theme-text">
<i data-lucide="plus" class="w-4 h-4"></i> <i data-lucide="plus" class="w-4 h-4"></i>
</button> </button>
</div> </div>
@@ -329,59 +377,6 @@
<div id="ceremony-list" class="mt-6 flex flex-col gap-4"></div> <div id="ceremony-list" class="mt-6 flex flex-col gap-4"></div>
</section> </section>
</div> </div>
</div>
<!-- RIGHT COLUMN: RESULTS -->
<div class="xl:col-span-9 flex flex-col gap-6">
<section id="status-dashboard" class="hidden animate-slide-in">
<div class="theme-panel rounded-3xl p-8 relative overflow-hidden flex flex-col md:flex-row items-center justify-between gap-6 shadow-2xl">
<!-- Decorative Glow -->
<div class="absolute -right-16 -top-16 w-64 h-64 rounded-full blur-3xl opacity-20" style="background: var(--primary); z-index: 0;"></div>
<div style="z-index: 1;">
<h3 class="text-xs font-black uppercase tracking-[0.2em] mb-2 theme-text-muted">Verbleibende Möglichkeiten</h3>
<p id="total-possibilities" class="text-5xl sm:text-7xl font-black tracking-tighter neon-glow" style="color: var(--primary);">--</p>
</div>
<div class="w-full md:w-auto flex flex-col gap-3" style="z-index: 1;">
<button id="calculate-button" class="w-full theme-btn py-4 px-8 rounded-xl flex items-center justify-center gap-3">
<i data-lucide="refresh-cw" class="w-5 h-5"></i> NEU BERECHNEN
</button>
<div class="flex items-center justify-center gap-2">
<span class="w-2 h-2 rounded-full animate-pulse" style="background: var(--success);"></span>
<span class="text-[10px] font-bold uppercase tracking-widest theme-text-muted">Live Engine Active</span>
</div>
</div>
</div>
</section>
<section id="grid-section" class="hidden theme-panel rounded-3xl p-6 overflow-hidden shadow-2xl animate-slide-in">
<div class="flex flex-col xl:flex-row xl:items-end justify-between gap-4 mb-6">
<div>
<h2 class="text-2xl font-black tracking-tight mb-1 theme-text">Match-Matrix</h2>
<p class="text-xs font-bold uppercase tracking-widest theme-text-muted">Wahrscheinlichkeit pro Paar</p>
</div>
<div class="flex flex-wrap gap-2 text-[10px] font-bold tracking-widest">
<div class="px-3 py-1.5 rounded-lg flex items-center gap-2 border" style="background: rgba(0,255,136,0.1); color: var(--success); border-color: rgba(0,255,136,0.3);">
<i data-lucide="check-circle" class="w-3 h-3"></i> 100% MATCH
</div>
<div class="px-3 py-1.5 rounded-lg flex items-center gap-2 border" style="background: rgba(255,51,51,0.1); color: var(--error); border-color: rgba(255,51,51,0.3);">
<i data-lucide="x-circle" class="w-3 h-3"></i> UNMÖGLICH
</div>
</div>
</div>
<div class="overflow-x-auto border rounded-xl" style="border-color: var(--panel-border);">
<table id="probability-table" class="w-full text-left border-collapse min-w-max">
<thead id="probability-table-head" style="background: var(--input-bg);" class="text-[10px] font-black uppercase tracking-widest theme-text-muted"></thead>
<tbody id="probability-table-body" class="divide-y" style="border-color: var(--panel-border);"></tbody>
</table>
</div>
</section>
</div>
</div>
</main> </main>
<!-- Global Modals/Overlays --> <!-- Global Modals/Overlays -->
@@ -516,7 +511,6 @@
initialPossibilitiesText.textContent = `${group1Names.length} in Gruppe A • ${group2Names.length} in Gruppe B`; initialPossibilitiesText.textContent = `${group1Names.length} in Gruppe A • ${group2Names.length} in Gruppe B`;
inputSections.classList.remove("hidden"); inputSections.classList.remove("hidden");
inputSections.classList.add("grid");
statusDashboard.classList.remove("hidden"); statusDashboard.classList.remove("hidden");
gridSection.classList.remove("hidden"); gridSection.classList.remove("hidden");
@@ -644,7 +638,6 @@
ceremonies: ceremonies.map(c => ({ pairs: c.pairs, beams: c.beams })) ceremonies: ceremonies.map(c => ({ pairs: c.pairs, beams: c.beams }))
}; };
// The browser proxy resolves /api/solve to the backend automatically
const res = await fetch('/api/solve', { const res = await fetch('/api/solve', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
@@ -694,7 +687,7 @@
badgeStyle = 'background: rgba(255,51,51,0.05); color: var(--error); opacity: 0.4;'; badgeStyle = 'background: rgba(255,51,51,0.05); color: var(--error); opacity: 0.4;';
textContent = '0%'; textContent = '0%';
} else { } else {
// Dynamic heatmap using CSS color-mix // Unified heatmap using CSS color-mix
const mixColor = `color-mix(in srgb, var(--success) ${prob}%, var(--error))`; const mixColor = `color-mix(in srgb, var(--success) ${prob}%, var(--error))`;
badgeStyle = `background: color-mix(in srgb, ${mixColor} 15%, transparent); color: ${mixColor}; font-weight: 800; border: 1px solid color-mix(in srgb, ${mixColor} 30%, transparent);`; badgeStyle = `background: color-mix(in srgb, ${mixColor} 15%, transparent); color: ${mixColor}; font-weight: 800; border: 1px solid color-mix(in srgb, ${mixColor} 30%, transparent);`;
} }
@@ -727,13 +720,22 @@
const s = JSON.parse(ev.target.result); const s = JSON.parse(ev.target.result);
g1NamesText.value = s.group1Names.join('\n'); g1NamesText.value = s.group1Names.join('\n');
g2NamesText.value = s.group2Names.join('\n'); g2NamesText.value = s.group2Names.join('\n');
handleSetupContestants(true); // skip initial calc
// First, setup the contestants but skip auto-calc
handleSetupContestants(true);
// Second, load truth booths and ceremonies into state
truthBooths = s.truthBooths || []; truthBooths = s.truthBooths || [];
ceremonies = s.ceremonies || []; ceremonies = s.ceremonies || [];
// Third, render the UI for both
truthBooths.forEach(renderTruthBoothUI); truthBooths.forEach(renderTruthBoothUI);
ceremonies.forEach((c, i) => renderCeremonyUI(c, i + 1)); ceremonies.forEach((c, i) => renderCeremonyUI(c, i + 1));
handleCalculate(); // Calc once all data is loaded
// Fourth, trigger ONE final calculation
handleCalculate();
} catch(err) { } catch(err) {
console.error(err);
showError("Fehler beim Laden der Datei. Ist sie beschädigt?"); showError("Fehler beim Laden der Datei. Ist sie beschädigt?");
} }
}; };
@@ -742,7 +744,7 @@
}); });
// Event Listeners // Event Listeners
setupButton.addEventListener("click", handleSetupContestants); setupButton.addEventListener("click", () => handleSetupContestants());
tbForm.addEventListener("submit", handleAddTruthBooth); tbForm.addEventListener("submit", handleAddTruthBooth);
ceremonyForm.addEventListener("submit", handleAddCeremony); ceremonyForm.addEventListener("submit", handleAddCeremony);
calculateButton.addEventListener("click", handleCalculate); calculateButton.addEventListener("click", handleCalculate);