import React, { useEffect, useState, useCallback } from 'react'; import { ShieldCheck, LayoutGrid, Check, Loader2, Tag, AlertTriangle, Briefcase } from 'lucide-react'; import { useAuthStore } from '../store/authStore'; interface SettingsPanelProps { instanceId: string | null; } // Engines oferecidas no painel. A 'official' (Baileys 6, que dá 401) fica de fora. // baileys7 → Baileys 7 oficial (a que conecta) → rótulo "API estável" // infinite → InfinityAPI (com botões) // titulo = rótulo genérico (todos os usuários). tituloTec = rótulo técnico // (Baileys/Infinity), exibido apenas para admin/ruibto@gmail.com. const ENGINES: { value: string; titulo: string; tituloTec?: string; desc: string; icon: any; iconCls: string; activeBorder: string; activeBg: string; checkCls: string; btnCls: string; }[] = [ { value: 'baileys7', titulo: 'API estável', tituloTec: 'API estável (Baileys 7)', desc: 'Conexão recomendada do WhatsApp', icon: ShieldCheck, iconCls: 'text-emerald-500', activeBorder: 'border-emerald-400', activeBg: 'bg-emerald-50', checkCls: 'text-emerald-600', btnCls: 'bg-emerald-500 hover:bg-emerald-600', }, { value: 'infinite', titulo: 'API com botões', tituloTec: 'InfinityAPI', desc: 'Com botões interativos (experimental)', icon: LayoutGrid, iconCls: 'text-amber-500', activeBorder: 'border-amber-400', activeBg: 'bg-amber-50', checkCls: 'text-amber-600', btnCls: 'bg-amber-500 hover:bg-amber-600', }, ]; export default function SettingsPanel({ instanceId }: SettingsPanelProps) { const user = useAuthStore((s) => s.user); // Termos técnicos (Baileys/Infinity) só para admin ou ruibto@gmail.com. const canSeeTech = user?.role === 'ADMIN' || user?.email === 'ruibto@gmail.com'; const [engine, setEngine] = useState(null); const [isBusiness, setIsBusiness] = useState(null); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(null); const [error, setError] = useState(null); const [version, setVersion] = useState(null); const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8008'; const authHeader = (): Record => { const t = typeof window !== 'undefined' ? localStorage.getItem('token') : null; return t ? { Authorization: `Bearer ${t}` } : {}; }; // Versão do sistema (servida em /version.json) useEffect(() => { fetch('/version.json') .then((r) => (r.ok ? r.json() : null)) .then(setVersion) .catch(() => {}); }, []); // Engine atual da instância useEffect(() => { if (!instanceId) return; setLoading(true); fetch(`${API_URL}/api/instances`, { headers: authHeader() }) .then((r) => (r.ok ? r.json() : [])) .then((list) => { const inst = Array.isArray(list) ? list.find((i: any) => i.id === instanceId) : null; setEngine(inst?.engine ?? null); setIsBusiness(inst ? !!inst.isBusiness : null); }) .catch(() => {}) .finally(() => setLoading(false)); }, [instanceId]); const selectEngine = useCallback(async (value: string) => { if (!instanceId || saving || value === engine) return; // Trocar de engine invalida a sessão (credenciais não migram entre APIs): // confirma porque exige escanear o QR Code novamente. if (typeof window !== 'undefined' && !window.confirm( 'Trocar de API vai DESCONECTAR a sessão atual.\n\n' + 'Você precisará escanear o QR Code novamente para reconectar. Continuar?' )) return; setSaving(value); setError(null); try { const res = await fetch(`${API_URL}/api/instances/${instanceId}/engine`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', ...authHeader() }, body: JSON.stringify({ engine: value }), }); if (res.status === 429) { const d = await res.json().catch(() => ({})); throw new Error(d.error ?? 'Aguarde o intervalo entre trocas.'); } if (!res.ok) throw new Error('Falha ao trocar a API.'); setEngine(value); } catch (e: any) { setError(e?.message ?? 'Erro ao trocar a API.'); } finally { setSaving(null); } }, [instanceId, saving, engine]); return (

Configurações

Escolha a API de conexão do WhatsApp para esta instância.

Trocar de API desconecta a sessão — será necessário escanear o QR Code novamente para reconectar.

{!instanceId && (

Selecione uma instância primeiro.

)} {/* ── Engines ─────────────────────────────────────────────── */}
{ENGINES.map((opt) => { const Icon = opt.icon; const ativa = engine === opt.value; const salvando = saving === opt.value; return (

{canSeeTech && opt.tituloTec ? opt.tituloTec : opt.titulo}

{opt.desc}

{ativa ? ( Ativa ) : ( )}
); })}
{loading &&

Carregando configuração atual…

} {error &&

{error}

} {/* ── Conta Business ──────────────────────────────────────── */}

Conta Business

{isBusiness === null ? '—' : isBusiness ? 'Sim (WhatsApp Business)' : 'Não (conta pessoal)'}

Business App ≠ Business API — botões só são garantidos na Business API oficial.

{/* ── Versão ──────────────────────────────────────────────── */}

Versão

{version?.version ?? '—'}

{version?.buildCount != null && (

build {version.buildCount}

)}
); }