"use client"; import { EditWorkflowPopup } from "@/components/workflow/edit-workflow-popup"; import { authClient } from "auth/client"; import { canCreateWorkflow } from "lib/auth/client-permissions"; import { ArrowUpRight, ChevronDown, MousePointer2 } from "lucide-react"; import { Card, CardDescription, CardHeader, CardTitle } from "ui/card"; import { Button } from "ui/button"; import useSWR, { mutate } from "swr"; import { fetcher } from "lib/utils"; import { Skeleton } from "ui/skeleton"; import { BackgroundPaths } from "ui/background-paths"; import { ShareableCard } from "@/components/shareable-card"; import { DBEdge, DBNode, DBWorkflow, WorkflowSummary, } from "app-types/workflow"; import { useTranslations } from "next-intl"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "ui/dropdown-menu"; import { BabyResearch, GetWeather } from "lib/ai/workflow/examples"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; import { Dialog, DialogContent, DialogTitle, DialogTrigger } from "ui/dialog"; import { WorkflowGreeting } from "@/components/workflow/workflow-greeting"; import { notify } from "lib/notify"; import { useState } from "react"; const createWithExample = async (exampleWorkflow: { workflow: Partial; nodes: Partial[]; edges: Partial[]; }) => { const response = await fetch("/api/workflow", { method: "POST", body: JSON.stringify({ ...exampleWorkflow.workflow, noGenerateInputNode: true, isPublished: true, }), }); if (!response.ok) return toast.error("Error creating workflow"); const workflow = await response.json(); const structureResponse = await fetch( `/api/workflow/${workflow.id}/structure`, { method: "POST", body: JSON.stringify({ nodes: exampleWorkflow.nodes, edges: exampleWorkflow.edges, }), }, ); if (!structureResponse.ok) return toast.error("Error creating workflow"); return workflow.id as string; }; interface WorkflowListPageProps { userRole?: string | null; } export default function WorkflowListPage({ userRole, }: WorkflowListPageProps = {}) { const t = useTranslations(); const router = useRouter(); const { data: session } = authClient.useSession(); const currentUserId = session?.user?.id; const [isVisibilityChangeLoading, setIsVisibilityChangeLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false); const { data: workflows, isLoading } = useSWR( "/api/workflow", fetcher, { fallbackData: [], }, ); // Separate workflows into user's own and shared const myWorkflows = workflows?.filter((w) => w.userId === currentUserId) || []; const sharedWorkflows = workflows?.filter((w) => w.userId !== currentUserId) || []; const createExample = async (exampleWorkflow: { workflow: Partial; nodes: Partial[]; edges: Partial[]; }) => { const workflowId = await createWithExample(exampleWorkflow); mutate("/api/workflow"); router.push(`/workflow/${workflowId}`); }; const updateVisibility = async ( workflowId: string, visibility: "private" | "public" | "readonly", ) => { try { setIsVisibilityChangeLoading(true); const response = await fetch(`/api/workflow/${workflowId}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ visibility }), }); if (!response.ok) throw new Error("Failed to update visibility"); // Refresh the workflows data mutate("/api/workflow"); toast.success(t("Workflow.visibilityUpdated")); } catch { toast.error(t("Common.error")); } finally { setIsVisibilityChangeLoading(false); } }; const deleteWorkflow = async (workflowId: string) => { const ok = await notify.confirm({ description: t("Workflow.deleteConfirm"), }); if (!ok) return; try { setIsDeleteLoading(true); const response = await fetch(`/api/workflow/${workflowId}`, { method: "DELETE", }); if (!response.ok) throw new Error("Failed to delete workflow"); mutate("/api/workflow"); toast.success(t("Workflow.deleted")); } catch (_error) { toast.error(t("Common.error")); } finally { setIsDeleteLoading(false); } }; // Check if user can create workflows using Better Auth permissions const canCreate = canCreateWorkflow(userRole); // For regular users, combine all workflows into one list const displayWorkflows = canCreate ? myWorkflows : [...myWorkflows, ...sharedWorkflows]; return (
workflow greeting {canCreate && ( createExample(BabyResearch())}> 👨🏻‍🔬 {t("Workflow.example.babyResearch")} createExample(GetWeather())}> 🌤️ {t("Workflow.example.getWeather")} )}
{/* My Workflows / Available Workflows Section */} {(canCreate || displayWorkflows.length > 0) && (

{canCreate ? t("Workflow.myWorkflows") : t("Workflow.availableWorkflows")}

{canCreate && (

{t("Workflow.createWorkflow")}

{t("Workflow.createWorkflowDescription")}

)} {isLoading ? Array(6) .fill(null) .map((_, index) => ( )) : displayWorkflows?.map((workflow) => ( ))}
)} {/* Only show Shared Workflows section for users who can create (to differentiate between owned and shared) */} {canCreate && sharedWorkflows.length > 0 && (

{t("Workflow.sharedWorkflows")}

{sharedWorkflows?.map((workflow) => ( ))}
)} {/* Empty state for users without create permission and no available workflows */} {!canCreate && displayWorkflows.length === 0 && !isLoading && ( {t("Workflow.noAvailableWorkflows")} {t("Workflow.noAvailableWorkflowsDescription")} )}
); }