import React, { useState, useEffect } from 'react'; import { Menu, X, Copy, CheckCircle, MessageCircle, Clock, ShieldAlert, ListChecks, Heart, Users, ChevronRight, Upload, Save, Play, History, Calendar, MapPin, Mail, Phone as PhoneIcon, UserCog, Lock, LogOut, User } from 'lucide-react'; // --- Componentes UI Reutilizáveis --- const Button = ({ children, onClick, variant = 'primary', className = '', disabled = false, type = 'button' }) => { const baseStyle = "px-4 py-2 rounded-lg transition-all duration-200 font-medium text-sm flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"; const variants = { primary: "bg-stone-800 text-white hover:bg-stone-700 shadow-sm", secondary: "bg-stone-200 text-stone-800 hover:bg-stone-300", outline: "border border-stone-300 text-stone-600 hover:bg-stone-50", ghost: "text-stone-500 hover:text-stone-800 hover:bg-stone-100", success: "bg-green-600 text-white hover:bg-green-700", danger: "bg-red-50 text-red-600 hover:bg-red-100" }; return ( ); }; const Card = ({ title, children, className = '' }) => (
{title && (

{title}

)}
{children}
); // --- Tela de Login --- const LoginScreen = ({ onLogin }) => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const handleSubmit = (e) => { e.preventDefault(); setError(''); setLoading(true); // Simulação de delay de rede e verificação setTimeout(() => { // Base de usuários mockada const users = { 'admin': { name: 'Adamo', role: 'Gerente' }, 'comercial': { name: 'Angela', role: 'Consultor' }, 'vendas': { name: 'Beatriz', role: 'SDR' } }; if (users[username] && password === 'aosiQU33aosiQU33') { onLogin({ username, ...users[username] }); } else { setError('Credenciais inválidas. Tente admin / aosiQU33aosiQU33'); setLoading(false); } }, 800); }; return (

PINHEIRO
MARTINEZ

Acesso Restrito

setUsername(e.target.value)} />
setPassword(e.target.value)} />
{error && (
{error}
)}
© Pinheiro Martinez Arquitetura
); }; // --- ScriptBox Inteligente (Conectado ao Lead e Atendente) --- const ScriptBox = ({ title, content, context, onAction, activeLead, attendantName }) => { const [copied, setCopied] = useState(false); // Lógica de Primeiro Nome do Cliente const clientFirstName = activeLead ? activeLead.name.split(' ')[0] : '[Nome]'; // Lógica do Nome do Atendente (usa o configurado ou mantém o placeholder se vazio) const myName = attendantName || '[Seu Nome]'; // Personaliza o conteúdo substituindo placeholders const processedContent = content .replace(/\[Nome\]/g, clientFirstName) .replace(/\[Nome do Cliente\]/g, clientFirstName) .replace(/\[Seu Nome\]/g, myName); const handleCopy = () => { const textArea = document.createElement("textarea"); textArea.value = processedContent; textArea.style.position = "fixed"; textArea.style.left = "-9999px"; textArea.style.top = "0"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { const successful = document.execCommand('copy'); if (successful) { setCopied(true); if (activeLead && onAction) { onAction(title, processedContent); } setTimeout(() => setCopied(false), 2000); } else { console.error('Falha ao copiar texto.'); } } catch (err) { console.error('Erro ao copiar texto: ', err); } document.body.removeChild(textArea); }; return (

{title} {activeLead && copied && ( Registrado para {clientFirstName} )}

{context && {context}}
"{processedContent}"
); }; // --- Seções de Conteúdo --- const ManifestoSection = () => (

Postura e Tom de Voz

"Não vendemos plantas ou obras. Vendemos a materialização da identidade do cliente. Nosso atendimento é o primeiro esboço do projeto: deve ser seguro, elegante, atento e sem pressa."

  • Consultores Orientamos o cliente com autoridade.
  • Calmos O luxo não tem pressa.
  • Ouvintes O cliente fala mais que nós.
  • Vendedores Não empurramos serviços.
  • Ansiosos Não usamos "só hoje", "última vaga".
); const FlowSection = ({ activeLead, logAction, attendantName }) => { const [step, setStep] = useState(1); return (
{activeLead && (

Atendendo Agora

{activeLead.name}

{activeLead.state && {activeLead.state}} {activeLead.contactType && {activeLead.contactType}}

Status Atual

{activeLead.status}
)}
{[1, 2, 3, 4].map((s) => ( ))}
{step === 1 && (

Objetivo: Mostrar que existe um humano do outro lado.

)} {step === 2 && (

Opção A: Cliente aceitou ÁUDIO

Opção B: Cliente prefere TEXTO

)} {step === 3 && ( )} {step === 4 && ( )}
); }; const LeadsManager = ({ leads, setLeads, onSelectLead, activeLead, attendantName, setAttendantName, currentUser }) => { const [showImport, setShowImport] = useState(false); const [importText, setImportText] = useState(''); const handleImport = () => { const rows = importText.trim().split('\n'); const newLeads = rows.map((row, index) => { const cols = row.split(',').map(s => s?.trim()); if (cols.length < 2) return null; const [date, name, phone, email, state, type] = cols; if (!name) return null; return { id: Date.now() + index, date: date || new Date().toLocaleDateString(), name: name, phone: phone || 'Sem telefone', email: email || '', state: state || '', contactType: type || 'Lead', status: 'Novo', history: [], lastInteraction: new Date().toISOString() }; }).filter(Boolean); setLeads([...leads, ...newLeads]); setImportText(''); setShowImport(false); }; return (
{/* Configuração do Atendente */}

{attendantName}

{currentUser?.role || 'Usuário'}

setAttendantName(e.target.value)} className="w-full p-2 bg-stone-50 border border-stone-200 rounded text-sm focus:outline-none focus:border-stone-500" />

Você pode editar como seu nome aparece nas mensagens.

{/* Cabeçalho e Botões */}

Gestão de Leads

Importe e controle seus contatos.

{showImport && (

Formato obrigatório das colunas (separado por vírgula):
Data de contato, Nome, Telefone, Email, Estado, Tipo de Contato

Exemplo:
22/11/2023, Ana Souza, 11999999999, ana@email.com, SP, Indicação
23/11/2023, Carlos Lima, 11888888888, carlos@email.com, RJ, Instagram