feat: add Settings component

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
Jonny 2026-09-14 08:16:33 +02:00
parent 9505bc2eb3
commit e6f0ce6116
1 changed files with 96 additions and 0 deletions

View File

@ -0,0 +1,96 @@
// web/src/components/Settings.tsx
import { useEffect, useState } from "react";
import { apiFetch } from "../api";
type SettingsData = { assistant_name: string; company_name: string; contact_email: string };
export default function Settings() {
const [settings, setSettings] = useState<SettingsData | null>(null);
const [error, setError] = useState<string | null>(null);
const [saving, setSaving] = useState(false);
const [saved, setSaved] = useState(false);
useEffect(() => {
async function load() {
try {
const response = await apiFetch("/api/v1/settings");
if (!response.ok) {
setError("Einstellungen nicht verfuegbar");
return;
}
setSettings(await response.json());
} catch {
setError("Einstellungen nicht verfuegbar");
}
}
load();
}, []);
function updateField(field: keyof SettingsData, value: string) {
setSettings((prev) => (prev ? { ...prev, [field]: value } : prev));
setSaved(false);
}
async function save() {
if (!settings) return;
setSaving(true);
setError(null);
try {
const response = await apiFetch("/api/v1/settings", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(settings),
});
if (!response.ok) {
setError("Speichern fehlgeschlagen");
return;
}
setSettings(await response.json());
setSaved(true);
} catch {
setError("Speichern fehlgeschlagen");
} finally {
setSaving(false);
}
}
if (!settings) {
return (
<div className="settings">
{error ? <p className="error">{error}</p> : <p>Lade Einstellungen...</p>}
</div>
);
}
return (
<div className="settings">
<h2>Einstellungen</h2>
{error && <p className="error">{error}</p>}
<label>
Name des Assistenten
<input
value={settings.assistant_name}
onChange={(e) => updateField("assistant_name", e.target.value)}
/>
</label>
<label>
Firmenname
<input
value={settings.company_name}
onChange={(e) => updateField("company_name", e.target.value)}
/>
</label>
<label>
Kontakt-E-Mail
<input
value={settings.contact_email}
onChange={(e) => updateField("contact_email", e.target.value)}
/>
</label>
<button onClick={save} disabled={saving}>
{saving ? "Speichert..." : "Speichern"}
</button>
{saved && <p>Gespeichert.</p>}
</div>
);
}