feat(admin): eigene Vorlage fuer die Willkommensmail mit Platzhaltern, Vorschau und Testmail
Tessera CI/CD / Lint & Type Check (push) Successful in 50s
Tessera CI/CD / Tests (push) Successful in 1m22s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 19s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m10s

Administrator -> Willkommensmail: Betreff, Ueberschrift, Einleitung, Abschluss je
Mandant (Tabelle WelcomeMailTemplate, RLS je Mandant, Migration 20260930150000);
Platzhalter {{name}} {{vorname}} {{benutzername}} {{email}} {{adresse}} {{firma}},
unbekannte -> 400 bzw. Hinweis beim Tippen; Werte escaped, Vorlage reiner Text.
Live-Vorschau per API gerendert, Testmail an die eigene Adresse ohne Token,
Zuruecksetzen auf Standard. Feste Bausteine (Kopf, Zugangsdaten, Anmeldehinweis,
Knoepfe, Fusszeile) bleiben immer drin.
Kopf: Wellenzelle dunkel statt weiss, Streifen 600x40, Inhalt 24 px naeher –
keine weisse Luecke, wenn OWA das CID-Bild nicht zeigt.
Lokal nachgewiesen: Hinweis/Sperre bei {{xyz}}, Speichern, Testmail (Link nur
/login), echte Mail mit eigener Vorlage und 7-Tage-Link.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 16:49:17 +02:00
parent 31d514b7ca
commit e10da76259
27 changed files with 2471 additions and 82 deletions
@@ -0,0 +1,27 @@
'use client';
import { useTranslations } from 'next-intl';
import { WelcomeMailTemplateEditor } from '@/components/admin/welcome-mail-template-editor';
import { useAuthStore } from '@/lib/stores/auth-store';
/**
* Administrator → Willkommensmail: eigene Vorlage je Mandant (Betreff,
* Ueberschrift, Einleitung, Abschluss mit Platzhaltern). ADMIN und
* SUPER_ADMIN; die Rollenpruefung hier ist nur Anzeige — durchgesetzt wird
* sie serverseitig (`@Roles` an `/welcome-mail-template`).
*/
export default function AdminWelcomeMailPage() {
const tCommon = useTranslations('common');
const currentUser = useAuthStore((s) => s.user);
const hasAccess = currentUser?.role === 'ADMIN' || currentUser?.role === 'SUPER_ADMIN';
if (!hasAccess) {
return (
<div className="flex min-h-[60vh] items-center justify-center">
<p className="text-lg text-muted-foreground">{tCommon('accessDenied')}</p>
</div>
);
}
return <WelcomeMailTemplateEditor />;
}