"use client"; import { MoreHorizontalIcon, Pencil, PlusIcon, RefreshCwIcon, SearchIcon, Trash2Icon, UsersRoundIcon, } from "lucide-react"; import { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "sonner"; import { EditDialog } from "./team-edit"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { createAgentTeam, deleteAgentTeam, fetchAgentTeams, updateAgentTeam, type AdminAgentTeam, type CreateAdminAgentTeamPayload, } from "@/lib/api/admin"; import { Status } from "@/lib/generated/enums"; import { useI18n } from "@/i18n/provider"; import { cn } from "@/lib/utils"; type AgentTeamSidebarProps = { selectedTeamId: number | null; onSelectTeam: (team: AdminAgentTeam | null) => void; onTeamsChange?: (teams: AdminAgentTeam[]) => void; }; function getStatusTabs(t: (key: string, values?: Record) => string) { return [ { value: "all", label: t("agentProfile.all") }, { value: String(Status.Ok), label: t("agentProfile.enabled") }, { value: String(Status.Disabled), label: t("agentProfile.disabled") }, ] as const; } export function AgentTeamSidebar({ selectedTeamId, onSelectTeam, onTeamsChange, }: AgentTeamSidebarProps) { const t = useI18n(); const statusTabs = getStatusTabs(t); const [keyword, setKeyword] = useState(""); const [statusFilter, setStatusFilter] = useState<(typeof statusTabs)[number]["value"]>("all"); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [actionLoadingId, setActionLoadingId] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); const [editingItem, setEditingItem] = useState(null); const [teams, setTeams] = useState([]); const loadData = useCallback(async () => { setLoading(true); try { const data = await fetchAgentTeams({ page: 1, limit: 200 }); setTeams(data); onTeamsChange?.(data); } catch (error) { toast.error(error instanceof Error ? error.message : t("agentProfile.loadTeamsFailed")); } finally { setLoading(false); } }, [onTeamsChange, t]); useEffect(() => { void loadData(); }, [loadData]); useEffect(() => { if (selectedTeamId == null) { return; } const matchedTeam = teams.find((item) => item.id === selectedTeamId) ?? null; if (matchedTeam) { onSelectTeam(matchedTeam); return; } if (!loading && teams.length > 0) { onSelectTeam(teams[0]); } }, [loading, onSelectTeam, selectedTeamId, teams]); const filteredTeams = useMemo(() => { const output = keyword.trim().toLowerCase(); return teams.filter((item) => { const matchedKeyword = output.length === 0 || item.name.toLowerCase().includes(output) || item.description.toLowerCase().includes(output); const matchedStatus = statusFilter === "all" || String(item.status) === statusFilter; return matchedKeyword && matchedStatus; }); }, [keyword, statusFilter, teams]); function openCreateDialog() { setEditingItem(null); setDialogOpen(true); } function openEditDialog(item: AdminAgentTeam) { setEditingItem(item); setDialogOpen(true); } function handleDialogOpenChange(open: boolean) { if (saving) { return; } if (!open) { setEditingItem(null); } setDialogOpen(open); } async function handleSubmit(payload: CreateAdminAgentTeamPayload) { if (saving) { return; } setSaving(true); try { if (editingItem) { await updateAgentTeam({ id: editingItem.id, ...payload }); toast.success(t("agentProfile.teamUpdated", { name: editingItem.name })); } else { await createAgentTeam(payload); toast.success(t("agentProfile.teamCreated", { name: payload.name })); } setDialogOpen(false); setEditingItem(null); await loadData(); } catch (error) { toast.error(error instanceof Error ? error.message : t("agentProfile.teamSaveFailed")); } finally { setSaving(false); } } async function handleDelete(item: AdminAgentTeam) { setActionLoadingId(item.id); try { await deleteAgentTeam(item.id); toast.success(t("agentProfile.teamDeleted", { name: item.name })); await loadData(); } catch (error) { toast.error(error instanceof Error ? error.message : t("agentProfile.teamDeleteFailed")); } finally { setActionLoadingId(null); } } return ( <>
{t("agentProfile.teamTitle")}
setKeyword(event.target.value)} placeholder={t("agentProfile.searchTeams")} className="pl-9" />
{statusTabs.map((item) => ( ))}
{filteredTeams.map((item) => (
} aria-label={t("agentProfile.moreActions", { name: item.name })} > openEditDialog(item)}> {t("agentProfile.edit")} void handleDelete(item)} className="text-destructive focus:text-destructive" > {actionLoadingId === item.id ? t("agentProfile.deleting") : t("agentProfile.delete")}
))} {!loading && filteredTeams.length === 0 ? (
{t("agentProfile.noTeams")}
) : null}
); }