import { useState } from "react"; import { Link } from "@tanstack/react-router"; import { motion, AnimatePresence } from "framer-motion"; import { z } from "zod"; import { Webhook, Trash2, Plus, ArrowLeft, Zap, ExternalLink } from "lucide-react"; import { useWebhooks, useCreateWebhook, useDeleteWebhook, useTestWebhook } from "@/api/queries"; import { PageLoader } from "@/components/shared/LoadingSpinner"; import { ErrorAlert } from "@/components/shared/ErrorAlert"; import { ConfirmDialog } from "@/components/shared/ConfirmDialog"; const urlSchema = z.string().url("Must be a valid URL"); interface Props { workspaceId: string; } export function WebhookManager({ workspaceId }: Props) { const { data: webhooks, isLoading, error } = useWebhooks(workspaceId); const createWebhook = useCreateWebhook(workspaceId); const deleteWebhook = useDeleteWebhook(workspaceId); const testWebhook = useTestWebhook(workspaceId); const [url, setUrl] = useState(""); const [urlError, setUrlError] = useState(""); const [deleteTarget, setDeleteTarget] = useState(null); const [testResult, setTestResult] = useState(null); const handleCreate = async (e: React.SyntheticEvent) => { e.preventDefault(); const result = urlSchema.safeParse(url); if (!result.success) { setUrlError(result.error.errors[0].message); return; } await createWebhook.mutateAsync(url); setUrl(""); setUrlError(""); }; const handleTest = async () => { const data = await testWebhook.mutateAsync(); setTestResult(JSON.stringify(data, null, 2)); setTimeout(() => setTestResult(null), 5000); }; const list = Array.isArray(webhooks) ? webhooks : []; return (
{workspaceId}

Webhooks

Event webhook endpoints for this workspace

{isLoading && } {/* Add webhook form */}

Add endpoint

{ setUrl(e.target.value); setUrlError(""); }} placeholder="https://your-server.com/webhook" className="theme-input w-full text-sm px-3 py-2 rounded-lg" /> {urlError && (

{urlError}

)}
{/* Test result */} {testResult && ( {testResult} )} {/* Webhook list */} {!isLoading && ( {list.length === 0 ? (

No webhook endpoints yet.

) : (
{list.map((wh, i) => (
{(wh as { url: string }).url}
{(wh as { id: string }).id}
))}
)}
)}
{ if (deleteTarget) await deleteWebhook.mutateAsync(deleteTarget); setDeleteTarget(null); }} onCancel={() => setDeleteTarget(null)} loading={deleteWebhook.isPending} />
); }