diff --git a/docs/todo.md b/docs/todo.md index c7e7729b..d4324030 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -97,6 +97,15 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung ## ✅ Erledigt +- [x] **🐞 Modal-Felder ließen sich nicht editieren (ZĂ€hler/Bankkarte/Ausweis/ZĂ€hlerstand)** + - Vier identische Vorkommen desselben Anti-Patterns wie beim + AddressModal-Fix von 2026-06-03: `setFormData(getInitialFormData())` + im Render-Body, getriggert durch `formData.X !== prop.X`. Jeder + Tastendruck setzte den State zurĂŒck. + - Fix in allen vier Modals (MeterModal, BankCardModal, + IdentityDocumentModal, MeterReadingModal): nach `useEffect` mit + `[?.id]`-Dependency umgezogen. + - [x] **🐞 JpgToPdfModal: PDF blieb trotz vorherigem Fix bei 20+ MB** - Stage-Test: 2 Handy-JPGs → 23 MB PDF. Ursache: Smartphone-Fotos haben 4000-6000 px Kante (24 MP), das vergrĂ¶ĂŸert die JPEG-Datei diff --git a/frontend/src/pages/customers/CustomerDetail.tsx b/frontend/src/pages/customers/CustomerDetail.tsx index fbc3532f..07a6c970 100644 --- a/frontend/src/pages/customers/CustomerDetail.tsx +++ b/frontend/src/pages/customers/CustomerDetail.tsx @@ -2679,10 +2679,12 @@ function BankCardModal({ const isPending = createMutation.isPending || updateMutation.isPending; - // Update form when bankCard prop changes - if (isEditing && formData.iban !== bankCard.iban) { + // Re-Init nur beim Wechsel zur anderen Karte – nicht bei jedem + // Tastendruck (das löste vorher Reset auf DB-Wert aus). + useEffect(() => { setFormData(getInitialFormData()); - } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [bankCard?.id]); return ( @@ -2829,10 +2831,12 @@ function DocumentModal({ const isPending = createMutation.isPending || updateMutation.isPending; - // Update form when document prop changes - if (isEditing && formData.documentNumber !== document.documentNumber) { + // Re-Init nur beim Wechsel zum anderen Ausweis – nicht bei jedem + // Tastendruck (das löste vorher Reset auf DB-Wert aus). + useEffect(() => { setFormData(getInitialFormData()); - } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [document?.id]); return ( @@ -3039,10 +3043,12 @@ function MeterModal({ const isPending = createMutation.isPending || updateMutation.isPending; - // Update form when meter prop changes - if (isEditing && formData.meterNumber !== meter.meterNumber) { + // Re-Init nur beim Wechsel zum anderen ZĂ€hler – nicht bei jedem + // Tastendruck (das löste vorher Reset auf DB-Wert aus). + useEffect(() => { setFormData(getInitialFormData()); - } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [meter?.id]); const noDeliveryAddresses = deliveryAddresses.length === 0; const successorLocked = !isEditing && formData.isSuccessor && !!predecessor; @@ -3276,10 +3282,12 @@ function MeterReadingModal({ const isPending = createMutation.isPending || updateMutation.isPending; - // Update form when reading prop changes - if (isEditing && formData.value !== reading.value.toString()) { + // Re-Init nur beim Wechsel zum anderen ZĂ€hlerstand – nicht bei + // jedem Tastendruck (das löste vorher Reset auf DB-Wert aus). + useEffect(() => { setFormData(getInitialFormData()); - } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [reading?.id]); return (