import React, { useState, useEffect } from 'react' import { Plus, Pencil, Trash2, ArrowLeft, Bell } from 'lucide-react' import { useFormStore } from '../store/useFormStore' import ConditionalLogic from './ConditionalLogic' import { Switch, fieldInputCls, fieldLabelCls } from './settings/SettingsUI' import RichTextEditor from './settings/RichTextEditor' import { TagTextInput } from './settings/MergeTagPicker' import { logicValue, logicPatch } from './settings/logicKeys' import { emailTagFields, invalidEmailItems, isValidEmail, plainText } from './settings/mergeTags' const errorCls = 'text-xs text-red-600 mt-1' /** { field: message } for the notification being edited; empty when it can be saved (the reference builder rules). */ function validateNotification(n, emailFieldIds) { const e = {} if (!plainText(n.name)) e.name = 'Enter a name for this notification.' if (n.sendTo === 'field') { if (!n.sendToField) e.sendToField = 'Choose the email field to send to.' else if (!emailFieldIds.includes(n.sendToField)) e.sendToField = 'The selected field is no longer in the form.' } else if (!String(n.sendToEmail || '').trim()) { e.sendToEmail = 'Enter at least one recipient email address.' } else if (invalidEmailItems(n.sendToEmail).length) { e.sendToEmail = `Not a valid email address: ${invalidEmailItems(n.sendToEmail).join(', ')}` } if (n.fromEmail && !isValidEmail(n.fromEmail)) e.fromEmail = 'Enter a valid email address.' if (n.replyTo && invalidEmailItems(n.replyTo).length) e.replyTo = 'Use an email address or a tag such as {field_email}.' if (n.bcc && invalidEmailItems(n.bcc).length) e.bcc = `Not a valid email address: ${invalidEmailItems(n.bcc).join(', ')}` if (!plainText(n.subject)) e.subject = 'Enter a subject.' if (!plainText(n.message)) e.message = 'Enter the email message (use {all_fields} for every answer).' return e } const INTRO = 'Send email notifications when someone submits your form. Configure who receives them, the subject line, and message content (e.g. include form data with merge tags).' export default function EmailAlerts() { const notifications = useFormStore((state) => state.notifications) || [] const addNotification = useFormStore((state) => state.addNotification) const updateNotification = useFormStore((state) => state.updateNotification) const deleteNotification = useFormStore((state) => state.deleteNotification) const settings = useFormStore((state) => state.settings) const setSettings = useFormStore((state) => state.setSettings) const fields = useFormStore((state) => state.fields) const [editingId, setEditingId] = useState(null) const [editingNotif, setEditingNotif] = useState(null) const [errors, setErrors] = useState({}) const [pendingDelete, setPendingDelete] = useState(null) // Migration logic useEffect(() => { if (settings.emailRecipient && (!notifications || notifications.length === 0 || (notifications.length === 1 && notifications[0].id === 'default' && notifications[0].message === '{all_fields}' && notifications[0].subject === 'New Form Submission' && !notifications[0].sendToEmail))) { const migrated = { id: 'migrated', name: 'Default Notification', sendTo: 'email', sendToEmail: settings.emailRecipient || '', sendToField: '', fromName: '', fromEmail: '', replyTo: '', bcc: '', subject: settings.emailSubject || 'New Form Submission', message: settings.emailBody || '{all_fields}', active: true, conditionalLogic: null } if (notifications && notifications.length > 0) { updateNotification(notifications[0].id, migrated) } else { addNotification(migrated) } setSettings({ emailRecipient: null, emailSubject: null, emailBody: null }) } }, [settings.emailRecipient, settings.emailSubject, notifications, addNotification, updateNotification, setSettings]) // Email fields anywhere in the form (grid columns included), like the server's send-to-field lookup. const emailFields = emailTagFields(fields) const setField = (key) => (v) => setEditingNotif((prev) => ({ ...prev, [key]: v })) const closeEditor = () => { setEditingId(null); setEditingNotif(null); setErrors({}) } // Once errors are shown they follow the edits (a fixed field loses its message). useEffect(() => { if (editingNotif && Object.keys(errors).length) setErrors(validateNotification(editingNotif, emailFields.map((f) => f.id))) // eslint-disable-next-line react-hooks/exhaustive-deps }, [editingNotif]) if (editingId) { return (
{INTRO}
{errors.name}
}No email fields found in the form.
)} {errors.sendToField &&{errors.sendToField}
}{errors.sendToEmail}
}{errors.fromEmail}
}{errors.replyTo}
}{errors.bcc}
}{errors.subject}
}{errors.message}
}{INTRO}
Subject: {notif.subject || 'No subject set'}
No notifications configured
Create a notification to send an email when someone submits this form.