);
}
// ── Main Component ─────────────────────────────────────────────────────────
export function TemplateManagementPanel({ areas = [] }) {
const [templates, setTemplates] = useState([]);
const [loading, setLoading] = useState(true);
const [view, setView] = useState('list');
const [editingId, setEditingId] = useState(null);
const [form, setForm] = useState(EMPTY_FORM);
const [saving, setSaving] = useState(false);
const [submitting, setSubmitting] = useState(null);
const [syncing, setSyncing] = useState(false);
const [deleting, setDeleting] = useState(null);
const [error, setError] = useState('');
const [success, setSuccess] = useState('');
useEffect(() => { load(); }, []);
async function load() {
setLoading(true);
try {
const data = await listTemplates();
setTemplates(Array.isArray(data) ? data : []);
} catch {
setError('Erro ao carregar templates.');
} finally {
setLoading(false);
}
}
function openNew() {
setForm(EMPTY_FORM); setEditingId(null);
setError(''); setSuccess(''); setView('form');
}
function openEdit(t) {
setForm({
name: t.name || '',
language: t.language || 'pt_BR',
category: t.category || 'UTILITY',
areaId: t.area_id ? String(t.area_id) : '',
headerType: t.header_type || '',
headerText: t.header_text || '',
content: t.content || '',
bodyVariables: Array.isArray(t.body_variables) ? t.body_variables : [],
footerText: t.footer_text || '',
buttons: Array.isArray(t.buttons) ? t.buttons : [],
});
setEditingId(t.id); setError(''); setSuccess(''); setView('form');
}
async function handleSave() {
if (!form.name.trim() || !form.content.trim()) {
setError('Nome e Corpo são obrigatórios.');
return;
}
setSaving(true); setError(''); setSuccess('');
try {
const payload = {
name: form.name.trim(),
content: form.content,
language: form.language,
category: form.category,
areaId: form.areaId ? Number(form.areaId) : null,
headerType: form.headerType || null,
headerText: form.headerText.trim() || null,
footerText: form.footerText.trim() || null,
buttons: form.buttons.length ? form.buttons : null,
bodyVariables: form.bodyVariables.length ? form.bodyVariables : null,
};
if (editingId) await updateTemplate(editingId, payload);
else await saveTemplate(payload);
setSuccess('Template salvo! Clique em "Enviar para Meta" para submeter à aprovação.');
await load();
setTimeout(() => { setView('list'); setSuccess(''); }, 2500);
} catch (err) {
setError(err?.message || 'Erro ao salvar.');
} finally {
setSaving(false);
}
}
async function handleSubmit(id) {
setSubmitting(id); setError(''); setSuccess('');
try {
const result = await submitTemplateToMeta(id);
setSuccess(`Enviado para Meta! Status: ${result.status || 'PENDING'}. Clique "Sincronizar" para atualizar.`);
await load();
} catch (err) {
setError(err?.message || 'Erro ao enviar para Meta. Verifique o WABA ID em Admin → WhatsApp → Configurar.');
} finally {
setSubmitting(null);
}
}
async function handleSync() {
setSyncing(true); setError('');
try {
const result = await syncTemplatesFromMeta();
setSuccess(`Sincronizado! ${result.synced ?? 0} template(s) atualizado(s).`);
await load();
} catch (err) {
setError(err?.message || 'Erro ao sincronizar com a Meta.');
} finally {
setSyncing(false);
}
}
async function handleDelete(id) {
if (!window.confirm('Excluir este template? A remoção na Meta também será tentada.')) return;
setDeleting(id); setError('');
try {
await deleteTemplate(id);
await load();
} catch (err) {
setError(err?.message || 'Erro ao excluir.');
} finally {
setDeleting(null);
}
}
function goBack() { setView('list'); setError(''); setSuccess(''); }
// ── Form view ──
if (view === 'form') {
return (
);
}
// ── List view ──
return (
{/* Toolbar */}
Templates HSM
{/* Info banner */}
Templates HSM são aprovados pela Meta para iniciar conversas fora da janela de 24h.
Crie → Salve → Envie para Meta → aguarde aprovação →{' '}
Sincronize para atualizar o status. Templates Aprovados ficam
disponíveis em Atendimento Ativo.
{/* Feedback */}
{error &&
{error}
}
{success &&
{success}
}
{/* List */}
{loading && (
Carregando…
)}
{!loading && templates.length === 0 && (
📝
Nenhum template cadastrado.
Clique em "+ Novo template" para criar o primeiro.