"use client"; import { type TenantLDAPConfig, type LDAPTestResult, type LDAPFilterSuggestion } from "@/lib/api"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { Separator } from "@/components/ui/separator"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; interface TenantLDAPTabProps { tenantLdapConfig: TenantLDAPConfig | null; tenantLdapLoading: boolean; tenantLdapSaving: boolean; tenantLdapTesting: boolean; tenantLdapError: string; tenantLdapTestResult: LDAPTestResult | null; tenantLdapForm: TenantLDAPConfig; setTenantLdapForm: React.Dispatch>; tenantLdapChangePassword: boolean; setTenantLdapChangePassword: (v: boolean) => void; ownLogoPreviewUrl: string | null; ownLogoUploading: boolean; ownLogoError: string; onSave: (e: React.FormEvent) => void; onTest: () => void; onDelete: () => void; onOwnLogoUpload: (file: File) => void; onOwnLogoDelete: () => void; } export function TenantLDAPTab({ tenantLdapConfig, tenantLdapLoading, tenantLdapSaving, tenantLdapTesting, tenantLdapError, tenantLdapTestResult, tenantLdapForm, setTenantLdapForm, tenantLdapChangePassword, setTenantLdapChangePassword, ownLogoPreviewUrl, ownLogoUploading, ownLogoError, onSave, onTest, onDelete, onOwnLogoUpload, onOwnLogoDelete, }: TenantLDAPTabProps) { return (

LDAP / Active Directory — Mandantenkonfiguration

Konfiguriere den LDAP-Server für deinen Mandanten.

LDAP aktiviert setTenantLdapForm((f) => ({ ...f, enabled: e.target.checked }))} />
{tenantLdapError && ( {tenantLdapError} )} {tenantLdapLoading ? (
{Array.from({ length: 6 }).map((_, i) => ( ))}
) : (
setTenantLdapForm((f) => ({ ...f, url: e.target.value }))} />

Port frei wählbar · Standard: 389 (LDAP), 636 (LDAPS) · Univention UCS: 7389 / 7636

setTenantLdapForm((f) => ({ ...f, bind_dn: e.target.value }))} />
{tenantLdapConfig && !tenantLdapChangePassword ? (
) : ( setTenantLdapForm((f) => ({ ...f, bind_password: e.target.value }))} /> )}
setTenantLdapForm((f) => ({ ...f, base_dn: e.target.value }))} />
setTenantLdapForm((f) => ({ ...f, user_filter: e.target.value }))} />
{/* Group mappings -- domain_admin: nur user + auditor */}
{tenantLdapForm.group_mappings.length === 0 ? (

Keine Gruppen-Zuordnungen definiert.

) : (
{tenantLdapForm.group_mappings.map((gm, i) => (
{ const gms = [...tenantLdapForm.group_mappings]; gms[i] = { ...gms[i], group_dn: e.target.value }; setTenantLdapForm((f) => ({ ...f, group_mappings: gms })); }} />
))}
)}
{/* Test result */} {tenantLdapTestResult && (
{tenantLdapTestResult.ok ? "Verbunden" : "Fehler"} {tenantLdapTestResult.message} {tenantLdapTestResult.latency_ms > 0 && ( {tenantLdapTestResult.latency_ms} ms )}
{tenantLdapTestResult.server_info && (

{tenantLdapTestResult.server_info}

)} {tenantLdapTestResult.error_detail && (

{tenantLdapTestResult.error_detail}

)} {tenantLdapTestResult.ok && tenantLdapTestResult.users_found > 0 && (

{tenantLdapTestResult.users_found} Benutzer gefunden {tenantLdapTestResult.users?.length < tenantLdapTestResult.users_found && ( (Vorschau: {tenantLdapTestResult.users?.length}) )}

{tenantLdapTestResult.users?.map((u, i) => ( ))}
UID Name E-Mail
{u.uid || "–"} {u.display_name || "–"} {u.mail || "–"}
)} {tenantLdapTestResult.ok && tenantLdapTestResult.filter_suggestions?.length > 0 && (

Filter-Vorschläge — klicken zum Übernehmen:

{tenantLdapTestResult.filter_suggestions.map((s: LDAPFilterSuggestion, i: number) => ( ))}

%s wird beim Login durch den Benutzernamen ersetzt

)}
)} {/* Action bar */}
{tenantLdapConfig && ( )}
)} {tenantLdapConfig && (

Zuletzt geändert: {tenantLdapConfig.updated_at ? new Date(tenantLdapConfig.updated_at).toLocaleString("de-DE") : "–"} {tenantLdapConfig.updated_by ? ` von ${tenantLdapConfig.updated_by}` : ""}

)} {/* Logo section for domain_admin */}

Mandanten-Logo

Logo deines Mandanten hochladen (PNG, JPEG, GIF, WebP oder SVG, max. 2 MB).

{ownLogoError &&

{ownLogoError}

} {ownLogoPreviewUrl ? (
{/* eslint-disable-next-line @next/next/no-img-element */} Logo
{ const f = e.target.files?.[0]; if (f) onOwnLogoUpload(f); }} className="w-auto" />
) : (
Kein Logo
{ const f = e.target.files?.[0]; if (f) onOwnLogoUpload(f); }} className="w-auto" />
)}
); }