diff --git a/web/static/index.html b/web/static/index.html index a5d3d73..504e984 100644 --- a/web/static/index.html +++ b/web/static/index.html @@ -153,6 +153,23 @@ function status(id, text, klasse) { } /* ------------------------------------------------ 1. Tische */ +let geladenerRadius = 1.5; // zuletzt aus der Session geladener Nachbar-Radius + +async function tischeAusSessionLaden() { + // Sektion 1 aus dem serverseitigen Session-Layout fuellen (z.B. was der + // grafische Editor gespeichert hat) statt fest das Preset zu zeigen. + try { + const r = await api('/sitzung/' + sitzung + '/tische'); + if (r.tische && r.tische.length) { + tischeLeeren(); + for (const t of r.tische) tischZeile(t.plaetze, t.x, t.y, t.id); + geladenerRadius = r.nachbarRadius || 1.5; + return; + } + } catch (e) { /* frische/abgelaufene Session — Preset als Fallback */ } + presetReihe(); +} + function tischZeile(plaetze, x, y, tid) { const tbody = document.querySelector('#tischTabelle tbody'); const nr = tid ?? tbody.children.length + 1; @@ -204,7 +221,7 @@ async function tischeSpeichern() { const r = await api('/sitzung/' + sitzung + '/tische', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ tische }), + body: JSON.stringify({ tische, nachbarRadius: geladenerRadius }), }); const nachbarn = r.tische.map(t => 'Tisch ' + t.id + ' ↔ [' + t.nachbarn.join(', ') + ']').join(' '); status('tischStatus', '✓ ' + r.tische.length + ' Tische, ' + r.plaetzeGesamt + @@ -250,14 +267,30 @@ Gast;Kollegium;;Kollegen;;4 Karl;Einzelgast;;;; `; -async function gaesteHochladen() { - const dateiInput = document.getElementById('csvDatei'); - let blob; - if (dateiInput.files.length > 0) { - blob = dateiInput.files[0]; - } else { - blob = new Blob([document.getElementById('csvText').value], { type: 'text/csv' }); +async function csvDateiGewaehlt(ev) { + // Ausgewaehlte CSV sofort sichtbar in die Textarea laden (Single Source): + // dekodieren wie das Backend (utf-8-sig, sonst cp1252), BOM strippen. + const datei = ev.target.files[0]; + if (!datei) return; + const puffer = await datei.arrayBuffer(); + let text; + try { + text = new TextDecoder('utf-8', { fatal: true }).decode(puffer); + } catch (e) { + text = new TextDecoder('windows-1252').decode(puffer); // Excel/Windows } + text = text.replace(/^/, ''); + document.getElementById('csvText').value = text; + // stale Ausgabe eines frueheren Uploads entfernen + document.getElementById('gruppenUebersicht').innerHTML = ''; + status('gaesteStatus', 'Datei „' + datei.name + '“ geladen — zum Übernehmen ' + + '„Gästeliste übernehmen“ klicken.', 'ok'); + ev.target.value = ''; // Textarea ist ab jetzt die alleinige Quelle +} + +async function gaesteHochladen() { + // immer die (ggf. aus einer Datei befuellte) Textarea senden + const blob = new Blob([document.getElementById('csvText').value], { type: 'text/csv' }); const form = new FormData(); form.append('datei', blob, 'gaeste.csv'); try { @@ -356,12 +389,17 @@ async function zeigeVariante(i) { /* ------------------------------------------------ Start */ window.addEventListener('DOMContentLoaded', async () => { document.getElementById('csvText').value = beispielCSV; - presetReihe(); + document.getElementById('csvDatei').addEventListener('change', csvDateiGewaehlt); try { sitzung = await sitzungHolen(); document.getElementById('sitzungsId').textContent = sitzung; + // Tische aus der (ggf. mit dem Editor geteilten) Session laden; + // Preset nur, wenn die Session noch keine Tische hat + await tischeAusSessionLaden(); + berechnenFreigeben(); } catch (e) { document.getElementById('sitzungsId').textContent = 'Fehler: ' + e.message; + presetReihe(); } });