import { useState, useEffect } from 'react'; import { listTemplates, saveTemplate, updateTemplate, deleteTemplate, submitTemplateToMeta, syncTemplatesFromMeta, } from '../services/templateService'; // ── Constants ────────────────────────────────────────────────────────────── const META_STATUS_MAP = { APPROVED: { label: 'Aprovado', color: '#1a7a44', bg: '#edfaf3', border: '#b6e8c8' }, PENDING: { label: 'Aguardando Meta', color: '#a05a00', bg: '#fff8f0', border: '#f5d9a8' }, REJECTED: { label: 'Rejeitado', color: '#b00020', bg: '#fff2f2', border: '#f5c6c6' }, PAUSED: { label: 'Pausado', color: '#6b4700', bg: '#fffbf0', border: '#f5e0a8' }, DISABLED: { label: 'Desabilitado', color: '#555', bg: '#f5f5f5', border: '#ddd' }, }; const DRAFT_STATUS = { label: 'Rascunho', color: '#555', bg: '#f0f2f5', border: '#dde1e7' }; function getMetaStatus(t) { return t.meta_status ? (META_STATUS_MAP[t.meta_status] || DRAFT_STATUS) : DRAFT_STATUS; } const CATEGORIES = [ { value: 'UTILITY', label: 'Utilidade' }, { value: 'MARKETING', label: 'Marketing' }, { value: 'AUTHENTICATION', label: 'Autenticação' }, ]; const LANGUAGES = [ { value: 'pt_BR', label: 'Português (Brasil)' }, { value: 'en_US', label: 'English (US)' }, { value: 'es', label: 'Español' }, ]; const BUTTON_TYPES = [ { value: 'QUICK_REPLY', label: 'Resposta rápida' }, { value: 'URL', label: 'Abrir URL' }, { value: 'PHONE_NUMBER', label: 'Ligar' }, ]; const EMPTY_FORM = { name: '', language: 'pt_BR', category: 'UTILITY', areaId: '', headerType: '', headerText: '', content: '', bodyVariables: [], footerText: '', buttons: [], }; // ── Helpers ───────────────────────────────────────────────────────────────── function toMetaName(name) { return String(name || '') .normalize('NFD').replace(/[̀-ͯ]/g, '') .toLowerCase() .replace(/[^a-z0-9]+/g, '_') .replace(/^_+|_+$/g, '') .substring(0, 60) || ''; } function syncBodyVars(content, prevVars) { const matches = [...content.matchAll(/\{\{(\d+)\}\}/g)]; const indices = [...new Set(matches.map(m => Number(m[1])))].sort((a, b) => a - b); return indices.map(i => prevVars.find(v => v.index === i) || { index: i, label: '', example: '' }); } function renderPreviewBody(content, bodyVariables) { return content.replace(/\{\{(\d+)\}\}/g, (_, n) => { const v = bodyVariables.find(v => v.index === Number(n)); return v?.example || (v?.label ? `[${v.label}]` : `{{${n}}}`); }); } // ── Styles ──────────────────────────────────────────────────────────────── const fieldStyle = { width: '100%', border: '1px solid var(--color-border)', borderRadius: 8, padding: '0.6rem 0.75rem', fontSize: '0.9rem', fontWeight: 600, color: 'var(--color-text)', background: '#fff', boxSizing: 'border-box', }; const labelStyle = { display: 'block', fontSize: '0.78rem', fontWeight: 800, color: 'var(--color-text-soft)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '0.3rem', }; function pill(bg, color) { return { fontSize: '0.7rem', fontWeight: 700, background: bg, color, borderRadius: 6, padding: '0.15rem 0.45rem' }; } function actionBtn(bg, color, disabled = false) { return { border: 'none', borderRadius: 6, padding: '0.4rem 0.75rem', background: disabled ? '#f0f2f5' : bg, color: disabled ? '#aaa' : color, fontWeight: 800, fontSize: '0.8rem', cursor: disabled ? 'not-allowed' : 'pointer', }; } // ── WhatsApp Preview ────────────────────────────────────────────────────── function WhatsAppPreview({ form }) { const { headerType, headerText, content, bodyVariables, footerText, buttons } = form; const bodyText = renderPreviewBody(content || '', bodyVariables); return (
Pré-visualização
{headerType === 'TEXT' && headerText && (

{headerText}

)} {headerType === 'IMAGE' && (
📷 Imagem
)}

{bodyText || 'Corpo do template…'}

{footerText && (

{footerText}

)}

12:00

{buttons.length > 0 && (
{buttons.map((b, i) => (
{b.type === 'URL' ? '🔗 ' : b.type === 'PHONE_NUMBER' ? '📞 ' : '↩ '} {b.text || '(sem texto)'}
))}
)}
); } // ── Template Card ───────────────────────────────────────────────────────── function TemplateCard({ t, onEdit, onSubmit, onDelete, submitting, deleting }) { const ms = getMetaStatus(t); const btns = Array.isArray(t.buttons) ? t.buttons : []; const isSubmitting = submitting === t.id; const isDeleting = deleting === t.id; const canSubmit = t.meta_status !== 'PENDING'; return (
{t.name} {ms.label}
{t.category || 'UTILITY'} {t.language || 'pt_BR'} {t.area_nome && {t.area_nome}}

{t.content || '(sem corpo)'}

{(t.header_type || t.footer_text || btns.length > 0) && (
{t.header_type && Header: {t.header_type}} {t.footer_text && Footer} {btns.length > 0 && ( {btns.length} botão{btns.length > 1 ? 'ões' : ''} )}
)} {t.meta_template_name && (

{t.meta_template_name}

)}
); } // ── Template Form ───────────────────────────────────────────────────────── function TemplateFormView({ form, setForm, editingId, onSave, saving, error, success, onBack, areas }) { function handleContent(e) { const content = e.target.value; setForm(f => ({ ...f, content, bodyVariables: syncBodyVars(content, f.bodyVariables) })); } function insertVar() { const nextIdx = form.bodyVariables.length > 0 ? Math.max(...form.bodyVariables.map(v => v.index)) + 1 : 1; const ta = document.getElementById('tpl-body'); const pos = ta ? (ta.selectionStart ?? form.content.length) : form.content.length; const tag = `{{${nextIdx}}}`; const newContent = form.content.slice(0, pos) + tag + form.content.slice(pos); setForm(f => ({ ...f, content: newContent, bodyVariables: syncBodyVars(newContent, f.bodyVariables) })); setTimeout(() => { if (ta) { ta.focus(); ta.setSelectionRange(pos + tag.length, pos + tag.length); } }, 0); } function setVar(index, field, value) { setForm(f => ({ ...f, bodyVariables: f.bodyVariables.map(v => v.index === index ? { ...v, [field]: value } : v), })); } function addButton(type) { setForm(f => ({ ...f, buttons: [...f.buttons, { type, text: '', url: '', phone: '' }] })); } function updateBtn(i, field, value) { setForm(f => ({ ...f, buttons: f.buttons.map((b, j) => j === i ? { ...b, [field]: value } : b) })); } function removeBtn(i) { setForm(f => ({ ...f, buttons: f.buttons.filter((_, j) => j !== i) })); } const metaNamePreview = toMetaName(form.name); return (
{/* Header */}
{editingId ? 'Editar template' : 'Novo template'}
{/* Two-column */}
{/* ── Form column ── */}
{/* Nome */}
setForm(f => ({ ...f, name: e.target.value }))} placeholder="ex: Boas Vindas Suporte" style={fieldStyle} /> {metaNamePreview && (

Nome Meta:{' '} {metaNamePreview}

)}
{/* Categoria / Idioma / Área */}
{/* Header */}
{form.headerType && ( setForm(f => ({ ...f, headerText: e.target.value }))} placeholder={form.headerType === 'TEXT' ? 'Texto do cabeçalho' : 'URL da imagem'} style={fieldStyle} /> )}
{/* Corpo */}