feat(tenants): UI fuer Mandanten-Verwaltung — Modul 4/16 des UI-Backlogs

Backend existierte vollstaendig (list, create, list users, assign user;
tenants:read/write), Frontend hatte 0% Abdeckung.

- api/tenants.ts: TanStack-Hooks (useTenants, useTenantUsers mit
  enabled-Gating, create, assignUser mit Cache-Invalidierung)
- pages/Tenants.tsx: Tenant-Karten (Name, Slug, Standard-Badge),
  expandierbare User-Liste pro Tenant (Rolle, E-Mail), Create-Dialog
  (Name + Slug mit Auto-Normalisierung), Assign-User-Dialog mit
  User-Picker (bereits zugewiesene gefiltert) — Create/Users/Assign
  hinter tenants:write gegated
- Platzierung: Settings-Subpage /settings/tenants (statisch, Core-Route)
  + Settings-Nav-Item
- i18n tenants.* de/en

Verifikation: Vitest 8/8 (Rendering, Standard-Badge, Expand-User-Liste,
Create-Flow, Assign-Flow, Permission-Gating, Empty/Error) · tsc exit 0 ·
production build exit 0.
This commit is contained in:
Agent Zero
2026-09-13 09:29:42 +02:00
parent 8d8beebd38
commit 79ca1cbe6d
7 changed files with 655 additions and 0 deletions
+21
View File
@@ -1684,5 +1684,26 @@
"revokeConfirm": "Token '{{name}}' wirklich widerrufen? Anwendungen damit verlieren sofort den Zugriff.",
"empty": "Keine API-Tokens vorhanden.",
"loadError": "API-Tokens konnten nicht geladen werden."
},
"tenants": {
"title": "Mandanten",
"create": "Mandant erstellen",
"createTitle": "Neuen Mandanten erstellen",
"createSubmit": "Erstellen",
"name": "Name",
"namePlaceholder": "z.B. Zweite Firma GmbH",
"slug": "Slug",
"slugPlaceholder": "z.B. zweite-firma",
"slugHelper": "Kleingeschrieben, Bindestriche statt Leerzeichen.",
"users": "Benutzer",
"loadingUsers": "Lade Benutzer...",
"assign": "Benutzer zuweisen",
"assignTitle": "Benutzer zu {{name}} zuweisen",
"assignSubmit": "Zuweisen",
"user": "Benutzer",
"userPlaceholder": "Benutzer auswaehlen",
"defaultBadge": "Standard",
"empty": "Keine Mandanten vorhanden.",
"loadError": "Mandanten konnten nicht geladen werden."
}
}
+21
View File
@@ -1684,5 +1684,26 @@
"revokeConfirm": "Really revoke token '{{name}}'? Applications using it lose access immediately.",
"empty": "No API tokens yet.",
"loadError": "Failed to load API tokens."
},
"tenants": {
"title": "Tenants",
"create": "Create tenant",
"createTitle": "Create a new tenant",
"createSubmit": "Create",
"name": "Name",
"namePlaceholder": "e.g. Second Company Ltd",
"slug": "Slug",
"slugPlaceholder": "e.g. second-company",
"slugHelper": "Lowercase, hyphens instead of spaces.",
"users": "Users",
"loadingUsers": "Loading users...",
"assign": "Assign user",
"assignTitle": "Assign user to {{name}}",
"assignSubmit": "Assign",
"user": "User",
"userPlaceholder": "Select a user",
"defaultBadge": "Default",
"empty": "No tenants yet.",
"loadError": "Failed to load tenants."
}
}