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();
}
});