"use client"; import { Button } from "@mdxui/primitives/button"; import { Card } from "@mdxui/primitives/card"; import { Input } from "@mdxui/primitives/input"; import { Label } from "@mdxui/primitives/label"; import { cn } from "@mdxui/primitives/lib/utils"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@mdxui/primitives/select"; import { Toggle } from "@mdxui/primitives/toggle"; import Link from "@tiptap/extension-link"; import { EditorContent, useEditor } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import { Bold, Code, Eye, Italic, Link as LinkIcon, Monitor, Smartphone, } from "lucide-react"; import type React from "react"; import { useCallback, useState } from "react"; export interface EmailBuilderProps { /** Initial email HTML */ initialValue?: string; /** Callback when content changes */ onChange?: (html: string, subject: string) => void; /** Initial subject line */ initialSubject?: string; /** Template presets */ templates?: EmailTemplate[]; /** Additional CSS class */ className?: string; /** Preview width */ previewWidth?: "mobile" | "desktop"; } export interface EmailTemplate { id: string; name: string; subject: string; html: string; } const DEFAULT_TEMPLATES: EmailTemplate[] = [ { id: "welcome", name: "Welcome Email", subject: "Welcome to {{company_name}}!", html: "

Welcome!

Thank you for joining us.

", }, { id: "notification", name: "Notification", subject: "You have a new notification", html: "

You have a new notification from {{app_name}}.

", }, { id: "reset-password", name: "Password Reset", subject: "Reset your password", html: "

Reset Password

Click the link below to reset your password.

", }, ]; export const EmailBuilder: React.FC = ({ initialValue = "", onChange, initialSubject = "", templates = DEFAULT_TEMPLATES, className, previewWidth: initialPreviewWidth = "desktop", }) => { const [subject, setSubject] = useState(initialSubject); const [previewMode, setPreviewMode] = useState(false); const [previewWidth, setPreviewWidth] = useState<"mobile" | "desktop">( initialPreviewWidth, ); const editor = useEditor({ extensions: [ StarterKit, Link.configure({ openOnClick: false, }), ], content: initialValue, onUpdate: ({ editor }) => { const html = editor.getHTML(); onChange?.(html, subject); }, }); const handleSubjectChange = useCallback( (newSubject: string) => { setSubject(newSubject); if (editor) { onChange?.(editor.getHTML(), newSubject); } }, [editor, onChange], ); const loadTemplate = useCallback( (templateId: string) => { const template = templates.find((t) => t.id === templateId); if (template && editor) { editor.commands.setContent(template.html); setSubject(template.subject); onChange?.(template.html, template.subject); } }, [editor, templates, onChange], ); const setLink = useCallback(() => { const url = window.prompt("Enter URL"); if (url && editor) { editor.chain().focus().setLink({ href: url }).run(); } }, [editor]); const insertVariable = useCallback( (variable: string) => { if (editor) { editor.chain().focus().insertContent(`{{${variable}}}`).run(); } }, [editor], ); if (!editor) { return null; } const emailHtml = ` ${subject} ${editor.getHTML()} `.trim(); return (
handleSubjectChange(e.target.value)} placeholder="Enter email subject..." />
editor.chain().focus().toggleBold().run()} > editor.chain().focus().toggleItalic().run() } >
{previewMode ? (
							{emailHtml}
						
) : (
)}
); };