'use client';
import { useState } from 'react';
import {
Building2,
ChevronDown,
ChevronRight,
Link2,
Network,
Unlink,
} from 'lucide-react';
import { useAction } from 'next-safe-action/hooks';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import { toast } from '@kit/ui/sonner';
import {
linkChildAccount,
unlinkChildAccount,
} from '../server/actions/hierarchy-actions';
import type { HierarchyNode } from '../server/api';
interface HierarchyTreeProps {
accountId: string;
tree: HierarchyNode;
availableAccounts: Array<{
id: string;
name: string;
slug: string | null;
}>;
}
function countDescendants(node: HierarchyNode): number {
let count = node.children.length;
for (const child of node.children) {
count += countDescendants(child);
}
return count;
}
function TreeNodeRow({
node,
onUnlink,
isUnlinking,
}: {
node: HierarchyNode;
onUnlink: (childId: string) => void;
isUnlinking: boolean;
}) {
const [expanded, setExpanded] = useState(node.depth < 2);
const hasChildren = node.children.length > 0;
const isRoot = node.depth === 0;
return (
{hasChildren ? (
) : (
)}
{node.name}
{node.slug && (
/{node.slug}
)}
{hasChildren && (
{node.children.length} direkt
)}
{isRoot ? (
Dachverband
) : node.depth === 1 ? (
Unterverband
) : (
Verein
)}
{!isRoot && (
)}
{expanded &&
hasChildren &&
node.children.map((child) => (
))}
);
}
export function HierarchyTree({
accountId,
tree,
availableAccounts,
}: HierarchyTreeProps) {
const [selectedAccountId, setSelectedAccountId] = useState('');
const totalDescendants = countDescendants(tree);
const { execute: executeLink, isPending: isLinking } = useAction(
linkChildAccount,
{
onSuccess: ({ data }) => {
if (data?.success) {
toast.success('Organisation erfolgreich verknüpft');
setSelectedAccountId('');
}
},
onError: ({ error }) => {
toast.error(
error.serverError ?? 'Fehler beim Verknüpfen der Organisation',
);
},
},
);
const { execute: executeUnlink, isPending: isUnlinking } = useAction(
unlinkChildAccount,
{
onSuccess: ({ data }) => {
if (data?.success) {
toast.success('Verknüpfung gelöst');
}
},
onError: ({ error }) => {
toast.error(
error.serverError ?? 'Fehler beim Entfernen der Verknüpfung',
);
},
},
);
function handleLink() {
if (!selectedAccountId) return;
executeLink({
parentAccountId: accountId,
childAccountId: selectedAccountId,
});
}
function handleUnlink(childId: string) {
executeUnlink({
childAccountId: childId,
parentAccountId: accountId,
});
}
return (
{/* Summary */}
Direkte Unterverbände
{tree.children.length}
Organisationen gesamt
{totalDescendants}
Verfügbar zum Verknüpfen
{availableAccounts.length}
{/* Tree */}
Organisationsstruktur
{/* Link Account */}
{availableAccounts.length > 0 && (
Organisation hinzufügen
)}
);
}