import React, { useEffect, useRef, useState } from 'react'; import { __ } from '@wordpress/i18n'; // prime import { Card } from 'primereact/card'; import { Button } from 'primereact/button'; import { Toast } from 'primereact/toast'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { TabView, TabPanel } from 'primereact/tabview'; import { InputNumber } from 'primereact/inputnumber'; import { InputSwitch } from 'primereact/inputswitch'; import { InputText } from 'primereact/inputtext'; import { InputTextarea } from 'primereact/inputtextarea'; import { Checkbox } from 'primereact/checkbox'; import { Dialog } from 'primereact/dialog'; import { Tag } from 'primereact/tag'; import { Message } from 'primereact/message'; import { Dropdown } from 'primereact/dropdown'; import { Divider } from 'primereact/divider'; import { ConfirmDialog, confirmDialog } from 'primereact/confirmdialog'; // service import Ar1Service from '../service/ar1Service'; // ================================================== // Mappe label in italiano — SINGLE SOURCE OF TRUTH // ================================================== // Stati template const TEMPLATE_STATUS_LABEL = { ACTIVE: 'In uso', ARCHIVED: 'Archiviato', DRAFT: 'Bozza' }; // Varianti template const VARIANT_LABEL = { A1: 'A1 — Persona Giuridica (societa, ente)', A2: 'A2 — Ditta Individuale (P.IVA persona fisica)', A3: 'A3 — Persona Fisica (senza P.IVA)' }; // Kind regole reminder PEC const PEC_KIND_LABEL = { AR1_REMINDER_30D: 'Promemoria 30 giorni prima della scadenza', AR1_REMINDER_7D: 'Promemoria 7 giorni prima della scadenza', AR1_EXPIRED: 'Notifica alla scadenza (giorno 0)', AR1_POST_EXPIRED_RECURRING: 'Sollecito ricorrente dopo la scadenza', AR1_BULK_MANUAL: 'Invio manuale massivo (superadmin)' }; const PEC_KIND_OPTIONS = [ { label: PEC_KIND_LABEL.AR1_REMINDER_30D, value: 'AR1_REMINDER_30D' }, { label: PEC_KIND_LABEL.AR1_REMINDER_7D, value: 'AR1_REMINDER_7D' }, { label: PEC_KIND_LABEL.AR1_EXPIRED, value: 'AR1_EXPIRED' }, { label: PEC_KIND_LABEL.AR1_POST_EXPIRED_RECURRING, value: 'AR1_POST_EXPIRED_RECURRING' }, { label: PEC_KIND_LABEL.AR1_BULK_MANUAL, value: 'AR1_BULK_MANUAL' } ]; /** * Ar1AdminConfig — configurazione AR1 per superadmin. (build 1776950352) * URL: /ar1-admin * * 5 sezioni (TabView): * 1. Template — lista (In uso / Archiviati separati) + anteprima PDF + editor form-based layout * 2. Policy — singleton con dropdown categoria documento + labels in italiano * 3. Regole — CRUD regole reminder PEC con kind parlante + help inline * 4. Invio massivo — bulk-request-recompilation (dry-run + live) * 5. Testi PEC — editor dei 5 template email AR1 (sync BE Gepafin via pull /internal/ar1-email-templates) */ const Ar1AdminConfig = () => { const toast = useRef(null); const [activeIndex, setActiveIndex] = useState(0); // ========= TEMPLATES ========= const [templates, setTemplates] = useState([]); const [loadingTpl, setLoadingTpl] = useState(false); const [editLayoutOpen, setEditLayoutOpen] = useState(false); const [editLayoutTpl, setEditLayoutTpl] = useState(null); const [layoutForm, setLayoutForm] = useState({}); // form strutturato const [layoutAdvancedJson, setLayoutAdvancedJson] = useState(''); // modalita JSON raw const [useAdvancedEditor, setUseAdvancedEditor] = useState(false); const [newVersionOpen, setNewVersionOpen] = useState(false); const [newVersionVariant, setNewVersionVariant] = useState('A1'); const [newVersionData, setNewVersionData] = useState({ version: '', activate_now: true }); // ========= POLICY ========= const [policy, setPolicy] = useState(null); const [policyDraft, setPolicyDraft] = useState(null); const [savingPolicy, setSavingPolicy] = useState(false); const [docCategories, setDocCategories] = useState([]); // ========= PEC RULES ========= const [pecRules, setPecRules] = useState([]); const [pecDialogOpen, setPecDialogOpen] = useState(false); const [pecEditing, setPecEditing] = useState(null); const [pecDraft, setPecDraft] = useState({ kind: '', offset_days: 0, is_recurring: false, recurring_interval_days: null, enabled: true, description: '' }); // ========= BULK ========= const [bulkCompanyIds, setBulkCompanyIds] = useState(''); const [bulkOnlyExpired, setBulkOnlyExpired] = useState(false); const [bulkOnlyMissing, setBulkOnlyMissing] = useState(false); const [bulkResult, setBulkResult] = useState(null); const [bulkRunning, setBulkRunning] = useState(false); // ========= EMAIL TEMPLATES ========= const [emailTemplates, setEmailTemplates] = useState([]); const [loadingEmail, setLoadingEmail] = useState(false); const [availableVariables, setAvailableVariables] = useState([]); const [editEmailOpen, setEditEmailOpen] = useState(false); const [editEmailData, setEditEmailData] = useState(null); const [previewHtml, setPreviewHtml] = useState(null); const [previewSubject, setPreviewSubject] = useState(null); // Tracking campo attivo per inserimento variabili con click const [activeEmailField, setActiveEmailField] = useState('body_html'); // 'subject' | 'body_html' | 'body_text' const subjectInputRef = useRef(null); const bodyHtmlInputRef = useRef(null); const bodyTextInputRef = useRef(null); // Inserisce {{variabile}} nel campo attivo, al cursore se possibile const insertVariable = (varName) => { if (!editEmailData) return; const token = '{{' + varName + '}}'; const fieldName = activeEmailField; const refMap = { subject: subjectInputRef, body_html: bodyHtmlInputRef, body_text: bodyTextInputRef }; const ref = refMap[fieldName]; const currentValue = editEmailData[fieldName] || ''; // InputText/InputTextarea PrimeReact espone l'elemento nativo via .getElement() o .current.element in v10+ // fallback sicuro: appendo in coda let insertAt = currentValue.length; let el = null; try { el = ref?.current?.getInput ? ref.current.getInput() : (ref?.current?.element || ref?.current); if (el && typeof el.selectionStart === 'number') { insertAt = el.selectionStart; } } catch (e) { // ignore, insertAt rimane a length } const before = currentValue.slice(0, insertAt); const after = currentValue.slice(insertAt); const newValue = before + token + after; setEditEmailData({ ...editEmailData, [fieldName]: newValue }); // riposiziono focus e cursor dopo il token appena inserito setTimeout(() => { try { if (el && typeof el.setSelectionRange === 'function') { el.focus(); const pos = insertAt + token.length; el.setSelectionRange(pos, pos); } } catch (e) { /* ignore */ } }, 0); }; // ---- load all ---- const loadTemplates = () => { setLoadingTpl(true); Ar1Service.listTemplates( (resp) => { setTemplates(resp?.items || resp || []); setLoadingTpl(false); }, (err) => { setLoadingTpl(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento template fallito' }); } ); }; const loadPolicy = () => { Ar1Service.getPolicy( (resp) => { setPolicy(resp); setPolicyDraft(resp); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento policy fallito' }); } ); }; const loadPecRules = () => { Ar1Service.listPecSchedule( (resp) => setPecRules(resp?.items || resp || []), (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento regole fallito' }); } ); }; const loadDocCategories = () => { Ar1Service.listDocumentCategories( (resp) => setDocCategories(resp?.items || []), (err) => console.warn('Categorie non caricate:', err) ); }; const loadEmailTemplates = () => { setLoadingEmail(true); Ar1Service.listEmailTemplates( (resp) => { setEmailTemplates(resp?.items || []); setAvailableVariables(resp?.available_variables || []); setLoadingEmail(false); }, (err) => { setLoadingEmail(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento testi fallito' }); } ); }; useEffect(() => { loadTemplates(); loadPolicy(); loadPecRules(); loadDocCategories(); loadEmailTemplates(); }, []); // ================================================== // SEZIONE 1: TEMPLATE // ================================================== // Divido active vs archived per UI separata const activeTemplates = templates.filter(t => t.status === 'ACTIVE' || t.status === 'DRAFT'); const archivedTemplates = templates.filter(t => t.status === 'ARCHIVED'); const openEditLayout = (tpl) => { setEditLayoutTpl(tpl); const lc = tpl.layout_config || {}; // popolo form con chiavi comuni; altre restano in "advanced JSON" setLayoutForm({ brand_name: lc.brand?.name || 'Gepafin S.p.A.', brand_logo_url: lc.brand?.logo_url || '', brand_color_primary: lc.brand?.color_primary || '#003d7a', brand_color_accent: lc.brand?.color_accent || '#e65100', header_title: lc.header?.title || 'Modulo AR1 — Adeguata Verifica', header_subtitle: lc.header?.subtitle || 'D.Lgs. 231/2007', intro_salutation: lc.intro?.salutation || 'Gentile Cliente,', intro_body: lc.intro?.body || '', privacy_url: lc.privacy?.url || '', privacy_body: lc.privacy?.body || '' }); setLayoutAdvancedJson(JSON.stringify(lc, null, 2)); setUseAdvancedEditor(false); setEditLayoutOpen(true); }; const buildLayoutFromForm = () => ({ brand: { name: layoutForm.brand_name, logo_url: layoutForm.brand_logo_url, color_primary: layoutForm.brand_color_primary, color_accent: layoutForm.brand_color_accent }, header: { title: layoutForm.header_title, subtitle: layoutForm.header_subtitle }, intro: { salutation: layoutForm.intro_salutation, body: layoutForm.intro_body }, privacy: { url: layoutForm.privacy_url, body: layoutForm.privacy_body } }); const saveLayout = () => { let payload; if (useAdvancedEditor) { try { payload = JSON.parse(layoutAdvancedJson); } catch (e) { if (toast.current) toast.current.show({ severity: 'error', summary: 'JSON non valido', detail: e.message }); return; } } else { payload = buildLayoutFromForm(); } Ar1Service.updateTemplateLayout(editLayoutTpl.id, payload, () => { if (toast.current) toast.current.show({ severity: 'success', summary: 'Salvato', detail: 'Layout aggiornato' }); setEditLayoutOpen(false); loadTemplates(); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); } ); }; const openNewVersion = (variant) => { setNewVersionVariant(variant); setNewVersionData({ version: '', activate_now: true }); setNewVersionOpen(true); }; const saveNewVersion = () => { // Eredita layout_config dalla versione ACTIVE corrente const active = templates.find(t => t.variant === newVersionVariant && t.status === 'ACTIVE'); const layoutConfig = active?.layout_config || {}; Ar1Service.createNewTemplateVersion(newVersionVariant, { version: newVersionData.version, layout_config: layoutConfig, activate_now: newVersionData.activate_now }, () => { if (toast.current) toast.current.show({ severity: 'success', summary: 'Creata', detail: `Nuova versione ${newVersionVariant} v${newVersionData.version}` }); setNewVersionOpen(false); loadTemplates(); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Creazione fallita' }); } ); }; // ================================================== // SEZIONE 2: POLICY // ================================================== const savePolicy = () => { setSavingPolicy(true); const patch = { validity_days: policyDraft.validity_days, popup_dismiss_hours: policyDraft.popup_dismiss_hours, popup_force_on_expired: policyDraft.popup_force_on_expired, auto_archive_on_company_document: policyDraft.auto_archive_on_company_document, company_document_category_id: policyDraft.company_document_category_id, allow_bulk_recompilation_request: policyDraft.allow_bulk_recompilation_request, }; Ar1Service.updatePolicy(patch, (resp) => { setSavingPolicy(false); setPolicy(resp); setPolicyDraft(resp); if (toast.current) toast.current.show({ severity: 'success', summary: 'Salvata', detail: 'Policy aggiornata' }); }, (err) => { setSavingPolicy(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); } ); }; // ================================================== // SEZIONE 3: REGOLE PEC // ================================================== const openPecDialog = (rule) => { if (rule) { setPecEditing(rule); setPecDraft({ kind: rule.kind, offset_days: rule.offset_days, is_recurring: rule.is_recurring, recurring_interval_days: rule.recurring_interval_days, enabled: rule.enabled, description: rule.description || '' }); } else { setPecEditing(null); setPecDraft({ kind: '', offset_days: 30, is_recurring: false, recurring_interval_days: null, enabled: true, description: '' }); } setPecDialogOpen(true); }; const savePecRule = () => { const payload = { ...pecDraft }; const onOk = () => { if (toast.current) toast.current.show({ severity: 'success', summary: 'Salvata', detail: pecEditing ? 'Regola aggiornata' : 'Regola creata' }); setPecDialogOpen(false); loadPecRules(); }; const onKo = (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); }; if (pecEditing) Ar1Service.updatePecRule(pecEditing.id, payload, onOk, onKo); else Ar1Service.createPecRule(payload, onOk, onKo); }; const deletePecRule = (rule) => { confirmDialog({ message: `Eliminare la regola "${PEC_KIND_LABEL[rule.kind] || rule.kind}"? Non sara piu inviata la PEC corrispondente.`, header: 'Conferma eliminazione', icon: 'pi pi-exclamation-triangle', acceptLabel: 'Elimina', rejectLabel: 'Annulla', acceptClassName: 'p-button-danger', accept: () => { Ar1Service.deletePecRule(rule.id, () => { if (toast.current) toast.current.show({ severity: 'success', summary: 'Eliminata', detail: 'Regola eliminata' }); loadPecRules(); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Eliminazione fallita' }); } ); } }); }; // ================================================== // SEZIONE 4: BULK // ================================================== const runBulk = (dryRun) => { setBulkRunning(true); const companyIds = bulkCompanyIds.trim() ? bulkCompanyIds.split(',').map(s => parseInt(s.trim(), 10)).filter(n => !isNaN(n)) : null; const payload = { dry_run: dryRun, only_expired: bulkOnlyExpired, only_missing: bulkOnlyMissing, company_ids: companyIds }; Ar1Service.bulkRequestRecompilation(payload, (resp) => { setBulkRunning(false); setBulkResult({ ...resp, was_dry_run: dryRun }); if (toast.current) toast.current.show({ severity: 'success', summary: dryRun ? 'Anteprima completata' : 'PEC inviate', detail: `${resp.matched || 0} aziende matchate` }); }, (err) => { setBulkRunning(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Invio fallito' }); } ); }; // ================================================== // SEZIONE 5: TESTI PEC // ================================================== const openEditEmail = (tpl) => { setEditEmailData({ ...tpl }); setPreviewHtml(null); setPreviewSubject(null); setEditEmailOpen(true); }; const saveEmail = () => { if (!editEmailData) return; Ar1Service.updateEmailTemplate(editEmailData.kind, { subject: editEmailData.subject, body_html: editEmailData.body_html, body_text: editEmailData.body_text, description: editEmailData.description || null }, (resp) => { if (toast.current) toast.current.show({ severity: 'success', summary: 'Salvato', detail: `Testo "${PEC_KIND_LABEL[resp.kind] || resp.kind}" aggiornato (version ${resp.version})` }); setEditEmailOpen(false); loadEmailTemplates(); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); } ); }; const runPreview = () => { if (!editEmailData) return; Ar1Service.previewEmailTemplate(editEmailData.kind, {}, // usa default mock del BE (resp) => { setPreviewSubject(resp.subject); setPreviewHtml(resp.body_html); }, (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Anteprima fallita' }); } ); }; // ================================================== // RENDER // ================================================== const tplStatusTpl = (row) => { const severity = row.status === 'ACTIVE' ? 'success' : row.status === 'ARCHIVED' ? 'secondary' : 'warning'; return ; }; const variantTpl = (row) => VARIANT_LABEL[row.variant] || row.variant; const tplActiveActionsTpl = (row) => (
); const pecKindTpl = (row) => (
{PEC_KIND_LABEL[row.kind] || row.kind}
{row.kind}
); const pecWhenTpl = (row) => { if (row.offset_days > 0) return `${row.offset_days} giorni PRIMA della scadenza`; if (row.offset_days === 0) return 'Il giorno della scadenza'; return `${Math.abs(row.offset_days)} giorni DOPO la scadenza`; }; const pecRecurringTpl = (row) => { if (!row.is_recurring) return una tantum; return ogni {row.recurring_interval_days} giorni; }; const pecActionsTpl = (row) => (
); const pecEnabledTpl = (row) => ( ); const emailActionsTpl = (row) => (
); return (

Configurazione AR1 — Adeguata Verifica

Gestione template, policy, regole di scadenza, invio massivo e testi PEC per il modulo antiriciclaggio (D.Lgs. 231/2007).

setActiveIndex(e.index)}> {/* ================ TAB 1: TEMPLATE ================ */} v{r.version}} /> r.quadri_count ?? (r.questions_snapshot?.quadri?.length ?? '—')} /> {archivedTemplates.length > 0 && ( 10} rows={10}> `v${r.version}`} /> r.created_at ? new Date(r.created_at).toLocaleDateString('it-IT') : '—'} /> )} {/* ================ TAB 2: POLICY ================ */} {!policyDraft &&

Caricamento…

} {policyDraft && (
setPolicyDraft({ ...policyDraft, validity_days: e.value })} min={30} max={1825} style={{ width: '100%' }} /> Giorni dopo la firma prima che la dichiarazione scada (default 365, min 30, max 1825).
setPolicyDraft({ ...policyDraft, popup_dismiss_hours: e.value })} min={1} max={168} style={{ width: '100%' }} /> Ore di silenzio dopo che l'utente clicca "Ricordamelo piu tardi" sul pop-up (default 24).
({ label: `${c.category_name} — ${c.description || ''}`, value: c.id }))} onChange={(e) => setPolicyDraft({ ...policyDraft, company_document_category_id: e.value })} style={{ width: '100%' }} placeholder="Seleziona categoria…" /> Categoria in cui l'AR1 firmato viene archiviato nei documenti aziendali (visibile in "I miei documenti").
)}
{/* ================ TAB 3: REGOLE ================ */}
{/* ================ TAB 4: BULK PEC ================ */}
setBulkCompanyIds(e.target.value)} placeholder="es. 1, 7, 42" style={{ width: '100%' }} />
setBulkOnlyExpired(e.checked)} />
setBulkOnlyMissing(e.checked)} />
{bulkResult && (

Aziende matchate: {bulkResult.matched ?? 0}

{!bulkResult.was_dry_run && (

Form segnati per invio PEC: {bulkResult.marked_for_pec ?? bulkResult.marked ?? 0}

)} {bulkResult.company_ids && bulkResult.company_ids.length > 0 && (

ID aziende: {bulkResult.company_ids.slice(0, 30).join(', ')}{bulkResult.company_ids.length > 30 ? '…' : ''}

)}
)}
{/* ================ TAB 5: TESTI PEC ================ */} (
{r.label || PEC_KIND_LABEL[r.kind] || r.kind}
{r.kind}
)} /> {r.subject}} /> } /> r.updated_at ? new Date(r.updated_at).toLocaleDateString('it-IT') : '—'} />
{/* ==================== DIALOGS ==================== */} {/* Edit layout template */} setEditLayoutOpen(false)} style={{ width: '780px', maxWidth: '95vw' }} modal >
setUseAdvancedEditor(e.value)} />
{!useAdvancedEditor && (
Brand
setLayoutForm({ ...layoutForm, brand_name: e.target.value })} style={{ width: '100%' }} />
setLayoutForm({ ...layoutForm, brand_logo_url: e.target.value })} style={{ width: '100%' }} placeholder="https://..." />
setLayoutForm({ ...layoutForm, brand_color_primary: e.target.value })} style={{ width: '100%' }} placeholder="#003d7a" />
setLayoutForm({ ...layoutForm, brand_color_accent: e.target.value })} style={{ width: '100%' }} placeholder="#e65100" />
Intestazione documento
setLayoutForm({ ...layoutForm, header_title: e.target.value })} style={{ width: '100%' }} />
setLayoutForm({ ...layoutForm, header_subtitle: e.target.value })} style={{ width: '100%' }} />
Introduzione
setLayoutForm({ ...layoutForm, intro_salutation: e.target.value })} style={{ width: '100%' }} />
setLayoutForm({ ...layoutForm, intro_body: e.target.value })} rows={3} style={{ width: '100%' }} />
Privacy
setLayoutForm({ ...layoutForm, privacy_url: e.target.value })} style={{ width: '100%' }} />
setLayoutForm({ ...layoutForm, privacy_body: e.target.value })} style={{ width: '100%' }} />
)} {useAdvancedEditor && (
setLayoutAdvancedJson(e.target.value)} rows={18} style={{ width: '100%', fontFamily: 'monospace', fontSize: 12 }} />
)}
{/* Nuova versione */} setNewVersionOpen(false)} style={{ width: '540px', maxWidth: '95vw' }} modal >
setNewVersionData({ ...newVersionData, version: e.target.value })} placeholder="es. 1.1.0" style={{ width: '100%' }} />
setNewVersionData({ ...newVersionData, activate_now: e.value })} />
{/* Edit regola PEC */} setPecDialogOpen(false)} style={{ width: '620px', maxWidth: '95vw' }} modal >
setPecDraft({ ...pecDraft, kind: e.value })} style={{ width: '100%' }} disabled={!!pecEditing} placeholder="Seleziona tipo…" /> {pecEditing ? 'Il tipo non e modificabile dopo la creazione' : 'Seleziona quale evento fa partire la PEC'}
setPecDraft({ ...pecDraft, offset_days: e.value })} style={{ flex: 1 }} /> {pecDraft.offset_days > 0 && `giorni PRIMA della scadenza`} {pecDraft.offset_days === 0 && `giorno della scadenza`} {pecDraft.offset_days < 0 && `giorni DOPO la scadenza`}
Numero positivo = prima della scadenza; 0 = il giorno stesso; negativo = dopo la scadenza.
setPecDraft({ ...pecDraft, is_recurring: e.value })} />
{pecDraft.is_recurring && (
setPecDraft({ ...pecDraft, recurring_interval_days: e.value })} min={1} style={{ width: '100%' }} /> Esempio: 30 = la PEC si ripete ogni 30 giorni finche la dichiarazione non viene aggiornata.
)}
setPecDraft({ ...pecDraft, enabled: e.value })} />
setPecDraft({ ...pecDraft, description: e.target.value })} rows={2} style={{ width: '100%' }} />
{/* Edit testo email */} setEditEmailOpen(false)} style={{ width: '900px', maxWidth: '95vw' }} modal maximizable > {editEmailData && (
{availableVariables.length > 0 && (
Variabili disponibili (inserite in: {activeEmailField === 'subject' ? 'Oggetto' : activeEmailField === 'body_html' ? 'Corpo HTML' : 'Corpo testo'})
{availableVariables.map(v => ( insertVariable(v)} /> ))}
)}
setEditEmailData({ ...editEmailData, subject: e.target.value })} onFocus={() => setActiveEmailField('subject')} style={{ width: '100%' }} />
setEditEmailData({ ...editEmailData, body_html: e.target.value })} onFocus={() => setActiveEmailField('body_html')} rows={10} style={{ width: '100%', fontFamily: 'monospace', fontSize: 12 }} />
setEditEmailData({ ...editEmailData, body_text: e.target.value })} onFocus={() => setActiveEmailField('body_text')} rows={5} style={{ width: '100%', fontSize: 13 }} /> Usato dai client email che non supportano HTML.
setEditEmailData({ ...editEmailData, description: e.target.value })} style={{ width: '100%' }} />
{previewSubject && (
Oggetto: {previewSubject}
)}
)}
); }; export default Ar1AdminConfig;