From e2a73f4e6ddb453a8be16d363ac902913c3f1230 Mon Sep 17 00:00:00 2001 From: Kundencenter Date: Thu, 1 Oct 2026 11:16:44 +0200 Subject: [PATCH] fix(web): Rules-of-Hooks-Verletzung auf der Kundenseite (React #310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit welcomeBusy's useState stand hinter dem frühen "noch am Laden"-Return, wurde also erst ab dem zweiten Render (sobald die Kundendaten da sind) aufgerufen - unterschiedliche Hook-Anzahl zwischen den Renders, siehe React-Fehler #310. Bestand schon vor der heutigen Impersonation-Änderung (seit der Begrüßungsmail-Funktion), ist aber in der Praxis bei jedem Öffnen der Kundenseite aufgetreten ("This page couldn't load"). Hook vor den frühen Return verschoben. Rest der Datei und eine grobe Suche über die restliche Web-App auf dasselbe Muster geprüft - keine weiteren echten Treffer (nur falsch-positive in anderen, unabhängigen Komponenten derselben Dateien). Co-Authored-By: Claude Sonnet 5 --- apps/web/src/app/(app)/admin/kunden/[id]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/app/(app)/admin/kunden/[id]/page.tsx b/apps/web/src/app/(app)/admin/kunden/[id]/page.tsx index d02364a..c34bb58 100644 --- a/apps/web/src/app/(app)/admin/kunden/[id]/page.tsx +++ b/apps/web/src/app/(app)/admin/kunden/[id]/page.tsx @@ -18,6 +18,7 @@ export default function Kunde() { const [contracts, setContracts] = useState(null); const [orders, setOrders] = useState(null); const [ress, setRess] = useState(null); const [o, setO] = useState(null); const [msg, setMsg] = useState<{ k: 'ok' | 'err' | 'warn'; t: string } | null>(null); const [confirm, setConfirm] = useState(null); const [switchTo, setSwitchTo] = useState<'private' | 'business' | null>(null); const [impersonateOpen, setImpersonateOpen] = useState(false); const [impersonateBusy, setImpersonateBusy] = useState(false); + const [welcomeBusy, setWelcomeBusy] = useState(false); const load = useCallback(() => api('GET', `/admin/customers/${id}`).then(setO).catch((e) => setMsg({ k: 'err', t: errMsg(e) })), [id]); useEffect(() => { void load(); api('GET', `/contracts?org=${id}`).then(setContracts).catch(() => setContracts([])); api('GET', `/orders?org=${id}`).then(setOrders).catch(() => setOrders([])); api('GET', `/resources?org=${id}`).then(setRess).catch(() => setRess([])); }, [load, id]); if (!o) return msg ? {msg.t} :

Wird geladen …

; @@ -45,7 +46,6 @@ export default function Kunde() { await reload(); r.push('/dashboard'); } catch (x) { setMsg({ k: 'err', t: errMsg(x) }); setImpersonateBusy(false); } } - const [welcomeBusy, setWelcomeBusy] = useState(false); async function sendWelcome() { setWelcomeBusy(true); try { const r = await api<{ status: string }>('POST', `/admin/customers/${id}/welcome-mail`); setMsg({ k: r.status === 'sent' ? 'ok' : 'warn', t: r.status === 'sent' ? 'Begrüßungsmail gesendet.' : `Nicht gesendet (Status: ${r.status}).` }); }