Mandantenfähigkeit: Domain + Kunden-E-Mail-Label dynamisch pro Provider

Alle hardcoded Referenzen auf 'stressfrei-wechseln.de' und 'Stressfrei-Wechseln'
durch dynamische Werte aus der EmailProviderConfig ersetzt. Notwendig für
Multi-Mandanten-Betrieb, wenn das CRM an Dritte vermietet wird.

Schema:
- Neues Feld EmailProviderConfig.customerEmailLabel (String?)
- Wenn leer, wird Label aus Domain abgeleitet ('stressfrei-wechseln.de' → 'Stressfrei-Wechseln')

Backend:
- Neuer Endpoint GET /api/email-providers/public-settings liefert { domain, customerEmailLabel }
- Neue Service-Funktionen: getProviderPublicSettings(), deriveLabelFromDomain()
- create/updateProviderConfig erweitert um customerEmailLabel

Frontend:
- Neuer Hook useProviderSettings() mit Auto-Caching
- Neues Eingabefeld 'Bezeichnung für Kunden-E-Mails' im Provider-Modal
- Dynamische Domain-Suffix im Adress-Hinzufügen-Dialog (@<domain>)
- Tab-Label 'Stressfrei-Wechseln' im Kunden-Detail → dynamisch
- 'Stressfrei-Wechseln Adresse' in ContractForm → dynamisch
- '(Stressfrei-Wechseln)' Badge in ContractDetail → dynamisch
- 'Stressfrei-Wechseln E-Mail' im Generate-Modal → dynamisch
- Leere-Zustand-Meldungen in Tab und E-Mail-Client → dynamisch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 15:43:19 +02:00
parent cf4370c905
commit cdde7b4ab7
13 changed files with 156 additions and 19 deletions
@@ -10,6 +10,7 @@ import Input from '../../components/ui/Input';
import Select from '../../components/ui/Select';
import type { ContractType } from '../../types';
import { formatDate } from '../../utils/dateFormat';
import { useProviderSettings } from '../../hooks/useProviderSettings';
import { Plus, Trash2, Eye, EyeOff, Info, X, ArrowLeft } from 'lucide-react';
// Contract types are now loaded dynamically from the database
@@ -67,6 +68,7 @@ export default function ContractForm() {
const queryClient = useQueryClient();
const isEdit = !!id;
const back = popHistory(location.state, isEdit ? `/contracts/${id}` : '/contracts');
const { customerEmailLabel } = useProviderSettings();
const preselectedCustomerId = searchParams.get('customerId');
@@ -914,7 +916,7 @@ export default function ContractForm() {
}}
className="text-blue-600"
/>
<span className="text-sm">Stressfrei-Wechseln Adresse</span>
<span className="text-sm">{customerEmailLabel} Adresse</span>
</label>
{usernameType === 'stressfrei' && (
<Select
@@ -929,7 +931,7 @@ export default function ContractForm() {
)}
{usernameType === 'stressfrei' && stressfreiEmails.length === 0 && (
<p className="text-xs text-amber-600">
Keine Stressfrei-Wechseln Adressen für diesen Kunden vorhanden. Bitte zuerst beim Kunden anlegen.
Keine {customerEmailLabel} Adressen für diesen Kunden vorhanden. Bitte zuerst beim Kunden anlegen.
</p>
)}
</div>