// Grape Elevate β€” Integration connect/configure modals. // Self-contained: a single driven by `state.openIntegration`. const INTEGRATION_DEFS = { Instagram: { emoji: 'πŸ“·', color: 'var(--coral)', blurb: 'Conecte sua conta business ou criador para que o Grape possa responder DMs, comentΓ‘rios e stories automaticamente.', permissions: [ 'Ler e responder Direct Messages', 'Ler e responder comentΓ‘rios nos seus posts e reels', 'Receber respostas a stories', 'Ver lista de seguidores e seguidos', ], fields: () => ([ { k: 'handle', label: 'Conta conectada', readOnly: true, value: '@fabiano.studio' }, { k: 'account', label: 'Tipo de conta', readOnly: true, value: 'Business' }, { k: 'webhook', label: 'Webhook URL', readOnly: true, value: 'https://hooks.grape.app/ig/u_8472a3' }, { k: 'reply', label: 'Resposta padrΓ£o', textarea: true, value: 'Oi! Recebi sua mensagem πŸ’œ Vou te responder em instantes.' }, ]), }, WhatsApp: { emoji: 'πŸ’¬', color: 'var(--green)', blurb: 'Encaminhe leads quentes do Instagram direto para o WhatsApp e responda manualmente ou via fluxo.', permissions: [ 'Enviar mensagens via WhatsApp Business API', 'Receber respostas dos contatos', 'Sincronizar templates aprovados', ], fields: () => ([ { k: 'phone', label: 'NΓΊmero conectado', readOnly: true, value: '+55 11 98xxx-xxxx' }, { k: 'name', label: 'Nome do remetente', value: 'Grape Studio' }, { k: 'greeting', label: 'Mensagem de boas-vindas', textarea: true, value: 'Oi! Aqui Γ© a equipe Grape, recebemos seu contato pelo Instagram πŸ‡' }, ]), }, Mailchimp: { emoji: 'πŸ“§', color: 'var(--sun)', blurb: 'Crie listas no Mailchimp a partir dos leads que o Grape captura.', permissions: ['Criar e atualizar listas', 'Adicionar e remover contatos', 'Disparar campanhas bΓ‘sicas'], fields: () => ([{ k: 'key', label: 'API Key', placeholder: 'us12-xxxxxxxx...' }]) }, Zapier: { emoji: '⚑', color: 'var(--cyan)', blurb: 'Conecte com 5.000+ apps via Zapier.', permissions: ['Acionar Zaps a partir de eventos do Grape'], fields: () => ([{ k: 'key', label: 'Zapier Webhook URL', value: 'https://hooks.zapier.com/hooks/catch/8123/abcde' }]) }, 'Google Sheets': { emoji: 'πŸ“Š', color: 'var(--grape)', blurb: 'Exporte cada novo lead para uma planilha.', permissions: ['Criar e editar planilhas', 'Adicionar linhas em planilhas existentes'], fields: () => ([{ k: 'sheet', label: 'Planilha de destino', placeholder: 'https://docs.google.com/...' }]) }, Webhook: { emoji: 'πŸ”—', color: 'var(--text-mute)', blurb: 'POST personalizado para qualquer URL.', permissions: ['Enviar POST com payload JSON em cada evento'], fields: () => ([{ k: 'url', label: 'Endpoint', placeholder: 'https://api.seusite.com/grape' }, { k: 'secret', label: 'Secret (assinatura HMAC)', placeholder: 'sk_...' }]) }, }; function IntegrationModal({ open, integration, status, onClose, onConnect, onDisconnect, onSave }) { // Stages: idle β†’ auth (Instagram) | phone β†’ otp (WhatsApp) | key (generic) β†’ success β†’ configure // For an already-connected integration, jump straight to "configure". const [stage, setStage] = React.useState('idle'); const [form, setForm] = React.useState({}); const def = open ? INTEGRATION_DEFS[integration] : null; React.useEffect(() => { if (!open) return; if (status === 'on') { // Existing connection β€” go straight to configure with the saved field values. const f = {}; (def.fields() || []).forEach((x) => { f[x.k] = x.value ?? ''; }); setForm(f); setStage('configure'); } else { setForm({}); setStage('idle'); } }, [open, integration, status]); if (!open || !def) return null; const startConnect = () => { if (integration === 'Instagram') setStage('auth'); else if (integration === 'WhatsApp') setStage('phone'); else setStage('key'); }; const finishConnect = () => { setStage('success'); setTimeout(() => { onConnect(integration, form); // Move into configure view so the user can edit details right after. const f = {}; (def.fields() || []).forEach((x) => { f[x.k] = x.value ?? f[x.k] ?? ''; }); setForm(f); setStage('configure'); }, 900); }; return ( <>
e.stopPropagation()}>
{def.emoji}
{stage === 'configure' ? 'Configurar' : 'Conectar'}

{integration}

{def.blurb}

{stage === 'idle' && ( <>
O Grape vai precisar
    {def.permissions.map((p) => (
  • {p}
  • ))}
)} {stage === 'auth' && setStage('idle')} onAuthorized={() => { setForm({ handle: '@fabiano.studio', account: 'Business', webhook: 'https://hooks.grape.app/ig/u_8472a3', reply: 'Oi! Recebi sua mensagem πŸ’œ Vou te responder em instantes.' }); finishConnect(); }} />} {stage === 'phone' && setStage('idle')} onSubmit={(phone) => { setForm((f) => ({ ...f, phone })); setStage('otp'); }} />} {stage === 'otp' && setStage('phone')} onSubmit={() => { setForm({ phone: form.phone, name: 'Grape Studio', greeting: 'Oi! Aqui Γ© a equipe Grape, recebemos seu contato pelo Instagram πŸ‡' }); finishConnect(); }} />} {stage === 'key' && ( <>
{def.fields().map((f) => (
setForm({ ...form, [f.k]: e.target.value })} />
))}
)} {stage === 'success' && (

Conectado!

JΓ‘ estΓ‘ pronto pra usar em seus fluxos.

)} {stage === 'configure' && ( <>
Conectado Β· sincronizando hΓ‘ 14 dias
{def.fields().map((f) => (
{f.textarea ? (