// ─── Settings View ─── import { api } from '../api.js'; export class SettingsView { constructor(container, setStatus) { this.container = container; this.setStatus = setStatus; this.sections = []; this.changedValues = {}; } async render() { this.container.innerHTML = `
Lade Einstellungen …
`; document.getElementById('set-save-btn').addEventListener('click', () => this.save()); document.getElementById('set-reload-btn').addEventListener('click', () => this.load()); await this.load(); } async load() { this.setStatus('Lade Einstellungen …'); this.changedValues = {}; try { const data = await api.get('/api/settings'); if (!Array.isArray(data)) return; this.sections = data; const formContainer = document.getElementById('settings-form-container'); if (!formContainer) return; formContainer.innerHTML = data.map((section, sIdx) => `
${section.title} ▾
${section.fields.map(f => this.renderField(f)).join('')}
`).join(''); // Wire input changes data.forEach(sec => { sec.fields.forEach(f => { const inputEl = document.getElementById(`field-${this.escapeId(f.path)}`); if (inputEl) { inputEl.addEventListener('change', () => { if (f.typeName === 'bool') { this.changedValues[f.path] = inputEl.checked; } else if (f.typeName === 'int' || f.typeName === 'decimal') { this.changedValues[f.path] = Number(inputEl.value); } else { this.changedValues[f.path] = inputEl.value; } document.getElementById('set-status-msg').textContent = `${Object.keys(this.changedValues).length} Änderung(en) ungespeichert`; }); } }); }); this.setStatus('Einstellungen geladen.'); document.getElementById('set-status-msg').textContent = 'Bereit.'; } catch (err) { this.setStatus(`Fehler beim Laden: ${err.message}`); } } escapeId(path) { return path.replace(/[^a-zA-Z0-9_-]/g, '_'); } renderField(f) { const id = `field-${this.escapeId(f.path)}`; let controlHtml = ''; if (f.typeName === 'bool') { controlHtml = ``; } else if (f.typeName === 'enum' && f.enumValues) { controlHtml = ` `; } else if (f.isPassword) { controlHtml = ` `; } else if (f.typeName === 'int' || f.typeName === 'decimal') { controlHtml = ` `; } else { controlHtml = ` `; } return `
${f.displayName}
${f.description ? `
${f.description}
` : ''}
${controlHtml}
`; } escapeHtml(str) { return String(str) .replace(/&/g, '&') .replace(/"/g, '"') .replace(//g, '>'); } async save() { const count = Object.keys(this.changedValues).length; if (count === 0) { this.setStatus('Keine Änderungen vorhanden.'); return; } this.setStatus(`Speichere ${count} Einstellung(en) …`); try { const res = await api.post('/api/settings', { updates: this.changedValues }); this.setStatus(res.message || 'Einstellungen erfolgreich gespeichert.'); document.getElementById('set-status-msg').textContent = 'Gespeichert.'; await this.load(); } catch (err) { this.setStatus(`Speichern fehlgeschlagen: ${err.message}`); } } }