UNPKG

@bernierllc/email-ui

Version:

React UI components for email management, templates, scheduling, and analytics

69 lines (67 loc) 6.75 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ import { useState } from 'react'; export const EmailComposer = ({ templates = [], onSend, onSchedule, onSaveDraft, isLoading = false, className = '', style, }) => { const [formData, setFormData] = useState({ to: [], cc: [], bcc: [], subject: '', content: '', }); const [scheduleTime, setScheduleTime] = useState(null); const [showSchedule, setShowSchedule] = useState(false); const [attachments, setAttachments] = useState([]); const [variables, setVariables] = useState({}); const handleTemplateSelect = (templateId) => { const template = templates.find(t => t.id === templateId); if (template) { setFormData(prev => ({ ...prev, subject: template.subject, content: template.content, templateId: templateId, })); const templateVars = {}; template.variables.forEach(variable => { templateVars[variable] = ''; }); setVariables(templateVars); } }; const handleSubmit = async (e) => { e.preventDefault(); const emailData = { ...formData, attachments, variables: Object.keys(variables).length > 0 ? variables : undefined, scheduleTime: scheduleTime || undefined, }; if (scheduleTime && onSchedule) { await onSchedule(emailData); } else { await onSend(emailData); } }; const handleFileAttachment = (event) => { if (event.target.files) { setAttachments(prev => [...prev, ...Array.from(event.target.files)]); } }; const removeAttachment = (index) => { setAttachments(prev => prev.filter((_, i) => i !== index)); }; const selectedTemplate = templates.find(t => t.id === formData.templateId); return (_jsxs("div", { className: `email-composer ${className}`, style: style, children: [_jsxs("div", { className: "email-composer__header", children: [_jsx("h2", { className: "email-composer__title", children: "Compose Email" }), templates.length > 0 && (_jsxs("div", { className: "template-selector", children: [_jsx("label", { htmlFor: "template-select", children: "Use Template:" }), _jsxs("select", { id: "template-select", onChange: (e) => handleTemplateSelect(e.target.value), className: "form-select", children: [_jsx("option", { value: "", children: "Select a template" }), templates.map((template) => (_jsx("option", { value: template.id, children: template.name }, template.id)))] })] }))] }), _jsxs("form", { onSubmit: handleSubmit, className: "email-composer__form", children: [_jsxs("div", { className: "form-group", children: [_jsx("label", { htmlFor: "to", className: "form-label", children: "To" }), _jsx("input", { id: "to", type: "email", value: formData.to[0] || '', onChange: (e) => setFormData(prev => ({ ...prev, to: [e.target.value] })), className: "form-input", placeholder: "Enter recipient email", required: true })] }), _jsxs("div", { className: "form-group", children: [_jsx("label", { htmlFor: "subject", className: "form-label", children: "Subject" }), _jsx("input", { id: "subject", type: "text", value: formData.subject, onChange: (e) => setFormData(prev => ({ ...prev, subject: e.target.value })), className: "form-input", placeholder: "Enter email subject", required: true })] }), selectedTemplate?.variables && selectedTemplate.variables.length > 0 && (_jsxs("div", { className: "template-variables", children: [_jsx("h3", { children: "Template Variables" }), selectedTemplate.variables.map((variable) => (_jsxs("div", { className: "form-group", children: [_jsx("label", { htmlFor: `var-${variable}`, className: "form-label", children: variable }), _jsx("input", { id: `var-${variable}`, type: "text", value: variables[variable] || '', onChange: (e) => setVariables(prev => ({ ...prev, [variable]: e.target.value })), className: "form-input", placeholder: `Enter value for ${variable}` })] }, variable)))] })), _jsxs("div", { className: "form-group", children: [_jsx("label", { htmlFor: "content", className: "form-label", children: "Message" }), _jsx("textarea", { id: "content", rows: 10, value: formData.content, onChange: (e) => setFormData(prev => ({ ...prev, content: e.target.value })), className: "form-textarea", placeholder: "Enter your email message", required: true })] }), _jsxs("div", { className: "form-group", children: [_jsx("label", { htmlFor: "attachments", className: "form-label", children: "Attachments" }), _jsx("input", { id: "attachments", type: "file", multiple: true, onChange: handleFileAttachment, className: "form-input" }), attachments.length > 0 && (_jsx("div", { className: "attachments-list", children: attachments.map((file, index) => (_jsxs("div", { className: "attachment-item", children: [_jsx("span", { children: file.name }), _jsx("button", { type: "button", onClick: () => removeAttachment(index), className: "btn btn--small btn--danger", children: "Remove" })] }, index))) }))] }), _jsxs("div", { className: "email-composer__scheduling", children: [_jsxs("label", { className: "checkbox-label", children: [_jsx("input", { type: "checkbox", checked: showSchedule, onChange: (e) => setShowSchedule(e.target.checked) }), "Schedule for later"] }), showSchedule && (_jsx("div", { className: "schedule-picker", children: _jsx("input", { type: "datetime-local", value: scheduleTime ? scheduleTime.toISOString().slice(0, -8) : '', onChange: (e) => setScheduleTime(e.target.value ? new Date(e.target.value) : null), className: "form-input", min: new Date().toISOString().slice(0, -8) }) }))] }), _jsxs("div", { className: "email-composer__footer", children: [onSaveDraft && (_jsx("button", { type: "button", onClick: () => onSaveDraft({ to: formData.to, subject: formData.subject, content: formData.content, attachments }), className: "btn btn--secondary", disabled: isLoading, children: "Save Draft" })), _jsx("button", { type: "submit", className: "btn btn--primary", disabled: isLoading, children: isLoading ? 'Sending...' : showSchedule ? 'Schedule' : 'Send' })] })] })] })); };