'use client' import { Button } from '../ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '../ui/dropdown-menu' import { Braces } from 'lucide-react' export interface MergeField { key: string label: string example: string category: string } export interface MergeFieldCategory { name: string label: string } /** Default merge field categories for email composition */ export const DEFAULT_CATEGORIES: MergeFieldCategory[] = [ { name: 'recipient', label: 'Recipient' }, { name: 'organization', label: 'Organization' }, { name: 'sender', label: 'Sender' }, { name: 'date', label: 'Date' }, ] /** Default merge fields for email composition */ export const DEFAULT_MERGE_FIELDS: MergeField[] = [ // Recipient fields { key: '{{recipient.firstName}}', label: 'First Name', example: 'John', category: 'recipient' }, { key: '{{recipient.lastName}}', label: 'Last Name', example: 'Smith', category: 'recipient' }, { key: '{{recipient.fullName}}', label: 'Full Name', example: 'John Smith', category: 'recipient' }, { key: '{{recipient.email}}', label: 'Email', example: 'john@example.com', category: 'recipient' }, { key: '{{recipient.title}}', label: 'Title', example: 'Partner', category: 'recipient' }, // Organization fields { key: '{{organization.name}}', label: 'Organization', example: 'Acme Corp', category: 'organization' }, { key: '{{organization.type}}', label: 'Type', example: 'Enterprise', category: 'organization' }, // Sender fields { key: '{{sender.name}}', label: 'Your Company', example: 'My Company', category: 'sender' }, { key: '{{sender.contactName}}', label: 'Your Name', example: 'Jane Doe', category: 'sender' }, // Date fields { key: '{{date.today}}', label: 'Today', example: 'December 8, 2024', category: 'date' }, { key: '{{date.month}}', label: 'Current Month', example: 'December', category: 'date' }, { key: '{{date.quarter}}', label: 'Current Quarter', example: 'Q4 2024', category: 'date' }, { key: '{{date.year}}', label: 'Current Year', example: '2024', category: 'date' }, ] interface MergeFieldsMenuProps { onInsert: (field: string) => void variant?: 'default' | 'compact' /** Custom merge fields to display. Defaults to DEFAULT_MERGE_FIELDS. */ fields?: MergeField[] /** Custom categories for grouping. Defaults to DEFAULT_CATEGORIES. */ categories?: MergeFieldCategory[] } export function MergeFieldsMenu({ onInsert, variant = 'default', fields = DEFAULT_MERGE_FIELDS, categories = DEFAULT_CATEGORIES, }: MergeFieldsMenuProps) { const fieldsByCategory = categories.map((cat) => ({ ...cat, fields: fields.filter((f) => f.category === cat.name), })) return ( {variant === 'compact' ? ( Merge ) : ( Insert Merge Field )} {fieldsByCategory.map((cat, idx) => ( {idx > 0 && } {cat.label} {cat.fields.map((field) => ( ))} ))} ) } function MergeFieldItem({ field, onInsert }: { field: MergeField; onInsert: (field: string) => void }) { return ( onInsert(field.key)} className="flex justify-between"> {field.label} {field.example} ) } // Preview component to show merge fields as visual tokens interface MergeFieldPreviewProps { content: string sampleData?: Record } /** Replace merge field tokens in content with sample data for previewing */ export function MergeFieldPreview({ content, sampleData }: MergeFieldPreviewProps) { const defaultSampleData: Record = { '{{recipient.firstName}}': 'John', '{{recipient.lastName}}': 'Smith', '{{recipient.fullName}}': 'John Smith', '{{recipient.email}}': 'john@example.com', '{{recipient.title}}': 'Partner', '{{organization.name}}': 'Acme Corp', '{{organization.type}}': 'Enterprise', '{{sender.name}}': 'My Company', '{{sender.contactName}}': 'Jane Doe', '{{date.today}}': new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }), '{{date.month}}': new Date().toLocaleDateString('en-US', { month: 'long' }), '{{date.quarter}}': `Q${Math.ceil((new Date().getMonth() + 1) / 3)} ${new Date().getFullYear()}`, '{{date.year}}': new Date().getFullYear().toString(), } const data = { ...defaultSampleData, ...sampleData } let preview = content for (const [key, value] of Object.entries(data)) { preview = preview.replace(new RegExp(key.replace(/[{}]/g, '\\$&'), 'g'), value) } return preview } /** Replace merge fields in content with actual recipient data for sending */ export function replaceMergeFields( content: string, recipient: { firstName?: string | null lastName?: string | null name?: string | null email?: string | null title?: string | null }, organization?: { name?: string | null type?: string | null }, sender?: { name?: string | null contactName?: string | null } ): string { const firstName = recipient.firstName || recipient.name?.split(' ')[0] || '' const lastName = recipient.lastName || recipient.name?.split(' ').slice(1).join(' ') || '' const fullName = recipient.name || `${firstName} ${lastName}`.trim() const replacements: Record = { '{{recipient.firstName}}': firstName, '{{recipient.lastName}}': lastName, '{{recipient.fullName}}': fullName, '{{recipient.email}}': recipient.email || '', '{{recipient.title}}': recipient.title || '', '{{organization.name}}': organization?.name || '', '{{organization.type}}': organization?.type || '', '{{sender.name}}': sender?.name || '', '{{sender.contactName}}': sender?.contactName || '', '{{date.today}}': new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }), '{{date.month}}': new Date().toLocaleDateString('en-US', { month: 'long' }), '{{date.quarter}}': `Q${Math.ceil((new Date().getMonth() + 1) / 3)} ${new Date().getFullYear()}`, '{{date.year}}': new Date().getFullYear().toString(), } let result = content for (const [key, value] of Object.entries(replacements)) { result = result.replace(new RegExp(key.replace(/[{}]/g, '\\$&'), 'g'), value) } return result }