"use client" import { useEffect, useState } from "react" import { useRouter } from "next/navigation" import { toast } from "sonner" import { Zap, Plus, MoreVertical, Copy, Pencil, Trash2, FileText, MessageCircle, Clock, Users, PhoneCall, Loader2, } from "lucide-react" import { createClient } from "@/lib/supabase/client" import type { Automation } from "@/types" import { Button } from "@/components/ui/button" import { Switch } from "@/components/ui/switch" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { AUTOMATION_TEMPLATES, type TemplateSlug } from "@/lib/automations/templates" import { triggerMeta, formatRelative } from "@/lib/automations/trigger-meta" import { cn } from "@/lib/utils" const TEMPLATE_ORDER: TemplateSlug[] = [ "welcome_message", "out_of_office", "lead_qualifier", "follow_up_reminder", ] const TEMPLATE_ICON: Record = { welcome_message: MessageCircle, out_of_office: Clock, lead_qualifier: Users, follow_up_reminder: PhoneCall, } export default function AutomationsPage() { const router = useRouter() const [automations, setAutomations] = useState(null) const [error, setError] = useState(null) const [pendingDelete, setPendingDelete] = useState(null) const [deleting, setDeleting] = useState(false) async function load() { try { const supabase = createClient() const { data, error: fetchErr } = await supabase .from("automations") .select("*") .order("created_at", { ascending: false }) if (fetchErr) throw fetchErr setAutomations((data ?? []) as Automation[]) } catch (err) { setError(err instanceof Error ? err.message : "Failed to load automations") } } useEffect(() => { load() }, []) async function toggleActive(a: Automation, next: boolean) { // Optimistic flip so the switch feels instant. setAutomations((prev) => prev?.map((x) => (x.id === a.id ? { ...x, is_active: next } : x)) ?? prev, ) const res = await fetch(`/api/automations/${a.id}`, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ is_active: next }), }) if (!res.ok) { // Roll back on error. setAutomations((prev) => prev?.map((x) => (x.id === a.id ? { ...x, is_active: !next } : x)) ?? prev, ) const body = await res.json().catch(() => ({})) toast.error(body?.error ?? "Failed to update") return } toast.success(next ? "Automation activated" : "Automation paused") } async function duplicate(a: Automation) { const res = await fetch(`/api/automations/${a.id}/duplicate`, { method: "POST" }) if (!res.ok) { const body = await res.json().catch(() => ({})) toast.error(body?.error ?? "Failed to duplicate") return } toast.success("Automation duplicated") load() } async function confirmDelete() { if (!pendingDelete) return setDeleting(true) const res = await fetch(`/api/automations/${pendingDelete.id}`, { method: "DELETE" }) setDeleting(false) if (!res.ok) { const body = await res.json().catch(() => ({})) toast.error(body?.error ?? "Failed to delete") return } toast.success("Automation deleted") setPendingDelete(null) load() } async function startFromTemplate(slug: TemplateSlug) { router.push(`/automations/new?template=${slug}`) } if (error) { return (

{error}

) } if (automations === null) { return (
) } const showTemplates = automations.length < 3 return (

Automations

Build workflows that react to WhatsApp events automatically.

{showTemplates && (

Quick-start templates

{TEMPLATE_ORDER.map((slug) => { const t = AUTOMATION_TEMPLATES[slug] const Icon = TEMPLATE_ICON[slug] return ( ) })}
)} {automations.length === 0 ? (

No automations yet

Pick a template above or create one from scratch.

) : (
    {automations.map((a) => ( toggleActive(a, next)} onEdit={() => router.push(`/automations/${a.id}/edit`)} onDuplicate={() => duplicate(a)} onLogs={() => router.push(`/automations/${a.id}/logs`)} onDelete={() => setPendingDelete(a)} /> ))}
)} !v && setPendingDelete(null)}> Delete automation This permanently removes{" "} {pendingDelete?.name} and its execution history. This cannot be undone.
) } function AutomationCard({ automation, onToggle, onEdit, onDuplicate, onLogs, onDelete, }: { automation: Automation onToggle: (next: boolean) => void onEdit: () => void onDuplicate: () => void onLogs: () => void onDelete: () => void }) { const meta = triggerMeta(automation.trigger_type) return (
  • onToggle(!!v)} aria-label={automation.is_active ? "Deactivate" : "Activate"} /> Edit Duplicate View Logs Delete
  • ) }