diff --git a/src/routes/templates.ts b/src/routes/templates.ts index a123c4d..71e2d38 100644 --- a/src/routes/templates.ts +++ b/src/routes/templates.ts @@ -151,6 +151,21 @@ export function createTemplatesRouter(db: Db): Hono { return c.json(updated); }); + router.delete('/:id', async (c) => { + const id = c.req.param('id'); + + const existing = await db.query.templates.findFirst({ + where: eq(templates.id, id), + }); + + if (!existing) { + throw new HTTPException(404, { message: 'Template not found' }); + } + + await db.delete(templates).where(eq(templates.id, id)); + return c.json({ ok: true }); + }); + router.post('/preview', async (c) => { const body = await c.req.json(); const subjectTemplate = String(body.subject_template ?? ''); diff --git a/web/src/app/admin/page-content.tsx b/web/src/app/admin/page-content.tsx index 02a4b28..d0286a7 100644 --- a/web/src/app/admin/page-content.tsx +++ b/web/src/app/admin/page-content.tsx @@ -10,6 +10,7 @@ import { PlusIcon, Settings2Icon, SlidersHorizontalIcon, + Trash2Icon, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -52,6 +53,7 @@ import { createTemplate, updateTemplate, previewTemplate, + deleteTemplate, getCustomFields, getQueueCustomFields, assignQueueCustomField, @@ -1699,6 +1701,7 @@ Location: {{custom_fields.location}}`); const [previewError, setPreviewError] = useState(null); const [saving, setSaving] = useState(false); const [saveError, setSaveError] = useState(null); + const [deletingId, setDeletingId] = useState(null); const fetchTemplates = useCallback(async () => { setLoading(true); @@ -1741,6 +1744,14 @@ Location: {{custom_fields.location}}`; setSaveError(null); }; + const handleDeleteTemplate = async (templateId: string) => { + setDeletingId(templateId); + await deleteTemplate(templateId); + if (editingId === templateId) resetBuilder(); + await fetchTemplates(); + setDeletingId(null); + }; + const selectTemplate = (template: Template) => { setEditingId(template.id); setName(template.name); @@ -1835,7 +1846,7 @@ Location: {{custom_fields.location}}`; type="button" onClick={() => selectTemplate(template)} className={cn( - "min-w-0 max-w-full overflow-hidden rounded-md border p-3 text-left transition hover:border-primary/45 hover:bg-accent/45", + "group min-w-0 max-w-full overflow-hidden rounded-md border p-3 text-left transition hover:border-primary/45 hover:bg-accent/45", editingId === template.id ? "border-primary bg-primary/10" : "border-border bg-card" )} > @@ -1844,9 +1855,23 @@ Location: {{custom_fields.location}}`;
{template.name}
{queueName(template.queue_id)}
- - {template.queue_id ? "Queue" : "Global"} - +
+ + {template.queue_id ? "Queue" : "Global"} + + +
{template.subject_template} diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 70b7e2c..f9da707 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -169,6 +169,10 @@ export async function previewTemplate(data: { return request("/templates/preview", { method: "POST", body: JSON.stringify(data) }); } +export async function deleteTemplate(id: string): Promise<{ data: { ok: boolean } | null; error: string | null }> { + return request<{ ok: boolean }>(`/templates/${id}`, { method: "DELETE" }); +} + export async function getLifecycles(): Promise<{ data: Lifecycle[] | null; error: string | null }> { return request("/lifecycles"); }