"use client"; import { useTranslations } from "next-intl"; import { AgentSummary, AgentUpdateSchema } from "app-types/agent"; import { Card, CardDescription, CardHeader, CardTitle } from "ui/card"; import { Button } from "ui/button"; import { Plus, ArrowUpRight } from "lucide-react"; import Link from "next/link"; import { BackgroundPaths } from "ui/background-paths"; import { useBookmark } from "@/hooks/queries/use-bookmark"; import { useMutateAgents } from "@/hooks/queries/use-agents"; import { toast } from "sonner"; import useSWR from "swr"; import { fetcher } from "lib/utils"; import { Visibility } from "@/components/shareable-actions"; import { ShareableCard } from "@/components/shareable-card"; import { notify } from "lib/notify"; import { useState } from "react"; import { handleErrorWithToast } from "ui/shared-toast"; import { safe } from "ts-safe"; import { canCreateAgent } from "lib/auth/client-permissions"; interface AgentsListProps { initialMyAgents: AgentSummary[]; initialSharedAgents: AgentSummary[]; userId: string; userRole?: string | null; } export function AgentsList({ initialMyAgents, initialSharedAgents, userId, userRole, }: AgentsListProps) { const t = useTranslations(); const mutateAgents = useMutateAgents(); const [deletingAgentLoading, setDeletingAgentLoading] = useState< string | null >(null); const [visibilityChangeLoading, setVisibilityChangeLoading] = useState< string | null >(null); const { data: allAgents } = useSWR( "/api/agent?filters=mine,shared", fetcher, { fallbackData: [...initialMyAgents, ...initialSharedAgents], }, ); const myAgents = allAgents?.filter((agent: AgentSummary) => agent.userId === userId) || initialMyAgents; const sharedAgents = allAgents?.filter((agent: AgentSummary) => agent.userId !== userId) || initialSharedAgents; const { toggleBookmark: toggleBookmarkHook, isLoading: isBookmarkLoading } = useBookmark({ itemType: "agent", }); const toggleBookmark = async (agentId: string, isBookmarked: boolean) => { await toggleBookmarkHook({ id: agentId, isBookmarked }); }; const updateVisibility = async (agentId: string, visibility: Visibility) => { safe(() => setVisibilityChangeLoading(agentId)) .map(() => AgentUpdateSchema.parse({ visibility })) .map(JSON.stringify) .map(async (body) => fetcher(`/api/agent/${agentId}`, { method: "PUT", body, }), ) .ifOk(() => { mutateAgents({ id: agentId, visibility }); toast.success(t("Agent.visibilityUpdated")); }) .ifFail((e) => { handleErrorWithToast(e); toast.error(t("Common.error")); }) .watch(() => setVisibilityChangeLoading(null)); }; const deleteAgent = async (agentId: string) => { const ok = await notify.confirm({ description: t("Agent.deleteConfirm"), }); if (!ok) return; safe(() => setDeletingAgentLoading(agentId)) .map(() => fetcher(`/api/agent/${agentId}`, { method: "DELETE", }), ) .ifOk(() => { mutateAgents({ id: agentId }, true); toast.success(t("Agent.deleted")); }) .ifFail((e) => { handleErrorWithToast(e); toast.error(t("Common.error")); }) .watch(() => setDeletingAgentLoading(null)); }; // Check if user can create agents using Better Auth permissions const canCreate = canCreateAgent(userRole); return (
{t("Layout.createYourOwnAgent")}