feat: add templates for transactional emails (#103)

* add template migration & router

* template CRUD

* templated transactional emails API

* zod schema fix & rearranging template columns
This commit is contained in:
Ganapathy S
2025-03-07 00:50:25 +05:30
committed by KM Koushik
parent 1c2417df2f
commit 38314a35dc
16 changed files with 981 additions and 8 deletions

View File

@@ -0,0 +1,78 @@
"use client";
import { Button } from "@unsend/ui/src/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@unsend/ui/src/dialog";
import { api } from "~/trpc/react";
import React, { useState } from "react";
import { toast } from "@unsend/ui/src/toaster";
import { Copy } from "lucide-react";
import { Template } from "@prisma/client";
export const DuplicateTemplate: React.FC<{
template: Partial<Template> & { id: string };
}> = ({ template }) => {
const [open, setOpen] = useState(false);
const duplicateTemplateMutation =
api.template.duplicateTemplate.useMutation();
const utils = api.useUtils();
async function onTemplateDuplicate() {
duplicateTemplateMutation.mutate(
{
templateId: template.id,
},
{
onSuccess: () => {
utils.template.getTemplates.invalidate();
setOpen(false);
toast.success(`Template duplicated`);
},
}
);
}
return (
<Dialog
open={open}
onOpenChange={(_open) => (_open !== open ? setOpen(_open) : null)}
>
<DialogTrigger asChild>
<Button variant="ghost" size="sm" className="p-0 hover:bg-transparent">
<Copy className="h-[18px] w-[18px] text-blue-600/80" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Duplicate Template</DialogTitle>
<DialogDescription>
Are you sure you want to duplicate{" "}
<span className="font-semibold text-primary">{template.name}</span>?
</DialogDescription>
</DialogHeader>
<div className="py-2">
<div className="flex justify-end">
<Button
onClick={onTemplateDuplicate}
variant="default"
disabled={duplicateTemplateMutation.isPending}
>
{duplicateTemplateMutation.isPending
? "Duplicating..."
: "Duplicate"}
</Button>
</div>
</div>
</DialogContent>
</Dialog>
);
};
export default DuplicateTemplate;