import React, { useState, useEffect, useRef } from 'react'; import { Box, Typography, Paper, Tabs, Tab, TextField, Button, Grid, Divider, CircularProgress, Alert, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Accordion, AccordionSummary, AccordionDetails, List, ListItem, ListItemText, Chip, Tooltip, Card, CardContent } from '@mui/material'; import { Add as AddIcon, Delete as DeleteIcon, Edit as EditIcon, Save as SaveIcon, Visibility as PreviewIcon, ExpandMore as ExpandMoreIcon, FormatBold as BoldIcon, FormatItalic as FormatItalicIcon, FormatListBulleted as BulletListIcon, FormatListNumbered as NumberedListIcon, Link as LinkIcon, Title as TitleIcon, Info as InfoIcon } from '@mui/icons-material'; import EmailEditor from 'react-email-editor'; import { useAdminSettingsByCategory, useDeleteSetting, useUpdateSetting } from '../../hooks/settingsAdminHooks'; // Available email template types const EMAIL_TYPES = [ { id: 'login_code', name: 'Login Code', description: 'Sent when a user requests a login code' }, { id: 'shipping_notification', name: 'Shipping Notification', description: 'Sent when an order is shipped' }, { id: 'order_confirmation', name: 'Order Confirmation', description: 'Sent when an order is placed' }, { id: 'low_stock_alert', name: 'Low Stock Alert', description: 'Sent when product stock falls below threshold' }, { id: 'welcome_email', name: 'Welcome Email', description: 'Sent when a user registers for the first time' }, { id: 'custom', name: 'Custom Template', description: 'A custom email template for any purpose' } ]; // Template variable placeholders for each email type const TEMPLATE_VARIABLES = { login_code: [ { key: '{{code}}', description: 'The login verification code' }, { key: '{{loginLink}}', description: 'Direct login link with the code' }, { key: '{{email}}', description: 'User\'s email address' } ], shipping_notification: [ { key: '{{first_name}}', description: 'Customer\'s first name' }, { key: '{{order_id}}', description: 'Order identifier' }, { key: '{{tracking_number}}', description: 'Shipping tracking number' }, { key: '{{carrier}}', description: 'Shipping carrier name' }, { key: '{{tracking_link}}', description: 'Link to track the package' }, { key: '{{shipped_date}}', description: 'Date the order was shipped' }, { key: '{{estimated_delivery}}', description: 'Estimated delivery date/time' }, { key: '{{items_html}}', description: 'HTML table of ordered items' }, { key: '{{customer_message}}', description: 'Optional message from staff' } ], order_confirmation: [ { key: '{{first_name}}', description: 'Customer\'s first name' }, { key: '{{order_id}}', description: 'Order identifier' }, { key: '{{order_date}}', description: 'Date the order was placed' }, { key: '{{order_total}}', description: 'Total amount of the order' }, { key: '{{shipping_address}}', description: 'Shipping address' }, { key: '{{items_html}}', description: 'HTML table of ordered items' } ], low_stock_alert: [ { key: '{{product_name}}', description: 'Name of the product low in stock' }, { key: '{{current_stock}}', description: 'Current stock quantity' }, { key: '{{threshold}}', description: 'Low stock threshold' } ], welcome_email: [ { key: '{{first_name}}', description: 'User\'s first name' }, { key: '{{email}}', description: 'User\'s email address' } ], custom: [] // Custom templates might have any variables }; // Sample placeholder data for preview const PREVIEW_DATA = { login_code: { code: '123456', loginLink: 'https://example.com/verify?code=123456&email=user@example.com', email: 'user@example.com' }, shipping_notification: { first_name: 'Jane', order_id: 'ORD-1234567', tracking_number: 'TRK123456789', carrier: 'FedEx', tracking_link: 'https://www.fedex.com/track?123456789', shipped_date: '2025-04-29', estimated_delivery: '2-3 business days', items_html: `
This code will expire in 15 minutes.
Or click here to log in directly.
" } } ] } ] } ] } }, shipping_notification: { // Simplified template - the actual structure would be more complex in the real editor body: { rows: [ { cells: [1], columns: [ { contents: [ { type: "text", values: { containerPadding: "10px", textAlign: "center", text: "Order #{{order_id}}
" } } ] } ] }, { cells: [1], columns: [ { contents: [ { type: "text", values: { containerPadding: "10px", textAlign: "left", text: "Hello {{first_name}},
Good news! Your order has been shipped and is on its way to you.
" } } ] } ] } ] } }, welcome_email: { // Simplified template body: { rows: [ { cells: [1], columns: [ { contents: [ { type: "text", values: { containerPadding: "10px", textAlign: "center", text: "Hello {{first_name}},
Thank you for creating an account with us. We're excited to have you join our community!
" } } ] } ] } ] } } }; const EmailTemplatesPage = () => { const [activeTab, setActiveTab] = useState(0); const [editingTemplate, setEditingTemplate] = useState(null); const [templateList, setTemplateList] = useState([]); const [previewDialogOpen, setPreviewDialogOpen] = useState(false); const [previewContent, setPreviewContent] = useState(''); const emailEditorRef = useRef(null); const { data: emailSettings, isLoading, error } = useAdminSettingsByCategory('email_templates'); const deleteSettingMutation = useDeleteSetting(); const updateSetting = useUpdateSetting(); useEffect(() => { if (emailSettings) { const templates = emailSettings.map(setting => { try { const templateData = JSON.parse(setting.value); return { id: setting.key, ...templateData }; } catch { return null; } }).filter(Boolean); setTemplateList(templates); } }, [emailSettings]); const handleTabChange = (e, newValue) => { // Only allow tab switching if not currently editing a template if (!editingTemplate) { setActiveTab(newValue); } }; const handleEditTemplate = (template) => { setEditingTemplate({ ...template }); // If the email editor is loaded, set its design if (emailEditorRef.current && template.design) { setTimeout(() => { emailEditorRef.current.editor.loadDesign(template.design); }, 500); } }; const handleSaveTemplate = async () => { if (!editingTemplate || !emailEditorRef.current) return; try { // Save the design from the email editor emailEditorRef.current.editor.exportHtml(async (data) => { const { design, html } = data; // Update the template with the new design and HTML const updatedTemplate = { ...editingTemplate, design: design, // Store the design JSON for future editing content: html, // Store the generated HTML for rendering updatedAt: new Date().toISOString() }; await updateSetting.mutateAsync({ key: updatedTemplate.id, value: JSON.stringify(updatedTemplate), category: 'email_templates' }); setTemplateList(prev => prev.map(t => t.id === updatedTemplate.id ? updatedTemplate : t)); setEditingTemplate(null); }); } catch (error) { console.error('Failed to save template:', error); } }; const handlePreviewTemplate = (template) => { if (template.content) { setPreviewContent(`Start editing this template to customize it for your needs.
`; // Add sample placeholders based on template type if (templateType === 'login_code') { defaultContent = `This code will expire in 15 minutes.
Or click here to log in directly.
`; } else if (templateType === 'shipping_notification') { defaultContent = `Hello {{first_name}},
Good news! Your order #{{order_id}} has been shipped and is on its way to you.
`; } else if (templateType === 'welcome_email') { defaultContent = `Hello {{first_name}},
Thank you for creating an account with us. We're excited to have you join our community!
`; } const newTemplate = { id: `email_template_${Date.now()}`, name: `New ${templateName}`, type: templateType, subject: `Your ${templateName}`, content: defaultContent, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; setEditingTemplate(newTemplate); }; const onEditorReady = () => { // You can perform any setup actions here when the editor is loaded console.log('Email editor is ready'); // If there's a template being edited, load its design if (editingTemplate?.design && emailEditorRef.current) { emailEditorRef.current.editor.loadDesign(editingTemplate.design); } // If there's no design but we have HTML content, create a default design with that content else if (editingTemplate?.content && emailEditorRef.current) { const defaultDesign = { body: { rows: [ { cells: [1], columns: [ { contents: [ { type: "html", values: { html: editingTemplate.content, containerPadding: "10px" } } ] } ] } ] } }; emailEditorRef.current.editor.loadDesign(defaultDesign); } // If it's a new template with no design or content, load the default template else if (editingTemplate && emailEditorRef.current) { // Try to load a default template for the template type const defaultTemplate = DEFAULT_TEMPLATES[editingTemplate.type] || { body: { rows: [ { cells: [1], columns: [ { contents: [ { type: "html", values: { html: "Start editing your email template here.
", containerPadding: "10px" } } ] } ] } ] } }; emailEditorRef.current.editor.loadDesign(defaultTemplate); } }; if (isLoading) return