"use client"; import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { UserPlus, Trash2, Crown, Scale, Briefcase, FileText, Phone } from "lucide-react"; import { api } from "@/lib/api"; import type { UserTenant, UserRole } from "@/lib/types"; import { ROLE_LABELS } from "@/lib/types"; import { Skeleton } from "@/components/ui/Skeleton"; import { EmptyState } from "@/components/ui/EmptyState"; import { usePermissions } from "@/lib/hooks/usePermissions"; const ROLE_CONFIG: Record = { owner: { label: ROLE_LABELS.owner, icon: Crown }, partner: { label: ROLE_LABELS.partner, icon: Scale }, associate: { label: ROLE_LABELS.associate, icon: Briefcase }, paralegal: { label: ROLE_LABELS.paralegal, icon: FileText }, secretary: { label: ROLE_LABELS.secretary, icon: Phone }, }; const INVITE_ROLES: UserRole[] = ["partner", "associate", "paralegal", "secretary"]; export function TeamSettings() { const queryClient = useQueryClient(); const { can, role: myRole } = usePermissions(); const tenantId = typeof window !== "undefined" ? localStorage.getItem("kanzlai_tenant_id") : null; const [email, setEmail] = useState(""); const [role, setRole] = useState("associate"); const canManageTeam = can("manage_team"); const { data: members, isLoading, error, } = useQuery({ queryKey: ["tenant-members", tenantId], queryFn: () => api.get(`/tenants/${tenantId}/members`), enabled: !!tenantId, }); const inviteMutation = useMutation({ mutationFn: (data: { email: string; role: string }) => api.post(`/tenants/${tenantId}/invite`, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tenant-members"] }); setEmail(""); setRole("associate"); toast.success("Benutzer eingeladen"); }, onError: (err: { error?: string }) => { toast.error(err.error || "Fehler beim Einladen"); }, }); const removeMutation = useMutation({ mutationFn: (userId: string) => api.delete(`/tenants/${tenantId}/members/${userId}`), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tenant-members"] }); toast.success("Mitglied entfernt"); }, onError: (err: { error?: string }) => { toast.error(err.error || "Fehler beim Entfernen"); }, }); const updateRoleMutation = useMutation({ mutationFn: ({ userId, newRole }: { userId: string; newRole: string }) => api.put(`/tenants/${tenantId}/members/${userId}/role`, { role: newRole }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tenant-members"] }); queryClient.invalidateQueries({ queryKey: ["me"] }); toast.success("Rolle aktualisiert"); }, onError: (err: { error?: string }) => { toast.error(err.error || "Fehler beim Aktualisieren der Rolle"); }, }); const handleInvite = (e: React.FormEvent) => { e.preventDefault(); if (!email.trim()) return; inviteMutation.mutate({ email: email.trim(), role }); }; if (isLoading) { return (
); } if (error) { return ( ); } return (
{/* Invite Form — only for owners/partners */} {canManageTeam && (
setEmail(e.target.value)} placeholder="name@example.com" className="flex-1 rounded-md border border-neutral-200 px-3 py-1.5 text-sm outline-none focus:border-neutral-400 focus:ring-1 focus:ring-neutral-400" />
)} {/* Members List */} {Array.isArray(members) && members.length > 0 ? (
{members.map((member, i) => { const roleKey = (member.role as UserRole) || "associate"; const roleInfo = ROLE_CONFIG[roleKey] || ROLE_CONFIG.associate; const RoleIcon = roleInfo.icon; return (

{member.user_id.slice(0, 8)}...

{roleInfo.label}

{/* Role dropdown — only for owners/partners, not for the member's own row if they are owner */} {canManageTeam && member.role !== "owner" && ( )} {canManageTeam && member.role !== "owner" && ( )}
); })}
) : ( )}
); }