// Tela: Meu Perfil /* ── Modal: Adicionar Conexão ────────────────────────────── */ function ConexoesModal({ onClose }) { const toast = useToast(); const plataformas = [ { color: 'blue', label: 'Slack', desc: 'Notificações e alertas', icon: 'SL' }, { color: 'pink', label: 'Zapier', desc: 'Automações personalizadas', icon: 'ZP' }, { color: 'lav', label: 'GitHub', desc: 'Rastrear issues e commits', icon: 'GH' }, { color: 'mint', label: 'Google Calendar', desc: 'Sincronizar agenda', icon: 'GC' }, { color: 'yellow',label: 'Pipedrive', desc: 'Migrar histórico de CRM', icon: 'PD' }, ]; return (
e.target === e.currentTarget && onClose()}>
Adicionar conexão
Escolha uma plataforma para integrar ao seu perfil:
{plataformas.map(p => (
{ toast(`Conectando com ${p.label}…`); onClose(); }} style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 12px', borderRadius:10, background:'var(--bg-soft)', cursor:'pointer', transition:'background .15s', }} onMouseEnter={e => e.currentTarget.style.background='var(--acc-blue-faint,oklch(0.97 0.02 250))'} onMouseLeave={e => e.currentTarget.style.background='var(--bg-soft)'} >
{p.icon}
{p.label}
{p.desc}
))}
); } /* ── Modal: Trocar Senha ─────────────────────────────────── */ function TrocarSenhaModal({ onClose }) { const [atual, setAtual] = React.useState(''); const [nova, setNova] = React.useState(''); const [conf, setConf] = React.useState(''); const toast = useToast(); const valid = atual.length >= 6 && nova.length >= 8 && nova === conf; const submit = () => { if (!valid) return; toast('Senha atualizada com sucesso ✓'); onClose(); }; const strength = nova.length === 0 ? 0 : nova.length < 8 ? 1 : /[A-Z]/.test(nova) && /[0-9]/.test(nova) ? 3 : 2; const strengthLabel = ['', 'Fraca', 'Média', 'Forte'][strength]; const strengthColor = ['', 'var(--danger)', 'oklch(0.68 0.18 70)', 'var(--ok)'][strength]; return (
e.stopPropagation()} style={{width: 440}}>
Trocar senha
Mínimo 8 caracteres · maiúsculas e números
{ICN.x}
setAtual(e.target.value)} autoFocus />
setNova(e.target.value)} /> {nova.length > 0 &&
{[1,2,3].map(i =>
)} {strengthLabel}
}
setConf(e.target.value)} style={{borderColor: conf.length > 0 && conf !== nova ? 'var(--danger)' : ''}} /> {conf.length > 0 && conf !== nova &&
As senhas não coincidem
}
); } /* ── Modal: Sessões Ativas ───────────────────────────────── */ function SessoesModal({ onClose }) { const [sessions, setSessions] = React.useState([ { id: 1, device: 'Chrome · macOS', local: 'São Paulo, SP', time: 'Agora', current: true }, { id: 2, device: 'Safari · iPhone 15', local: 'São Paulo, SP', time: 'há 2 horas' }, { id: 3, device: 'Chrome · Windows 11', local: 'Campinas, SP', time: 'há 1 dia' }, ]); const toast = useToast(); const encerrar = (id) => { setSessions(s => s.filter(x => x.id !== id)); toast('Sessão encerrada ✓'); }; const encerrarTodas = () => { setSessions(s => s.filter(x => x.current)); toast('Todas as outras sessões encerradas ✓'); }; return (
e.stopPropagation()} style={{width: 480}}>
Sessões ativas
{sessions.length} dispositivo{sessions.length !== 1 ? 's' : ''} conectado{sessions.length !== 1 ? 's' : ''}
{ICN.x}
{sessions.map((s, i) => (
{s.device.includes('iPhone') ? : }
{s.device} {s.current && Esta sessão}
{s.local} · {s.time}
{!s.current && }
))}
{sessions.length > 1 && }
); } function Perfil({ onBack }) { const [editing, setEditing] = React.useState(false); const [showSenha, setShowSenha] = React.useState(false); const [showSessoes, setShowSessoes] = React.useState(false); const [editingPrefs, setEditingPrefs] = React.useState(false); const [showConexoes, setShowConexoes] = React.useState(false); const [avatar, setAvatar] = React.useState('https://i.pravatar.cc/240?img=47'); const avatarRef = React.useRef(null); const toast = useToast(); const handleAvatarFile = (file) => { if (!file || !file.type.startsWith('image/')) return; setAvatar(URL.createObjectURL(file)); toast('Foto atualizada ✓'); }; const [vals, setVals] = React.useState({ nome: 'Letícia Andrade Borges', cargo: 'Head Comercial', dept: 'Vendas', bio: 'Lidero o time comercial da Ezza desde 2023. Foco em vendas consultivas para indústria e construção.', email: 'leticia.andrade@ezza.com.br', emailAlt: 'leticia.borges@gmail.com', tel: '+55 11 9 9412-7782', ramal: '2204', }); const [saved, setSaved] = React.useState({...vals}); const [savedAvatar, setSavedAvatar] = React.useState(avatar); const save = () => { setSaved({...vals}); setSavedAvatar(avatar); setEditing(false); toast('Perfil salvo com sucesso!'); }; const revert = () => { setVals({...saved}); setAvatar(savedAvatar); setEditing(false); }; const setV = (key) => (e) => setVals(prev => ({...prev, [key]: e.target.value})); return ( <> {showSenha && setShowSenha(false)} />} {showSessoes && setShowSessoes(false)} />} {showConexoes && setShowConexoes(false)} />} Meu perfil} subtitle="Dados pessoais, preferências e segurança" back onBack={onBack} right={
{editing ? <> : }
} />
Foto e identidade
avatarRef.current?.click() }, { ic: ICN.trash, label: 'Remover foto', danger: true, onClick: () => { setAvatar('https://i.pravatar.cc/240?img=47'); toast('Foto removida'); } }, ]} />
handleAvatarFile(e.target.files?.[0])} />
setEditing(true)} />
setEditing(true)} /> setEditing(true)} />
setEditing(true)} />
Contato
Verificado
Preferências
setEditingPrefs(e => !e)} />
{editingPrefs &&
Editando preferências
}
Atividade desta semana
↑ +12% vs semana anterior
R$ 482k
Receita fechada
↑ +R$ 48k
14
Negócios ativos
↑ +3
36
Reuniões
→ igual
128
Mensagens
↑ +22
Segurança
setShowSenha(true) }, { ic: ICN.bolt, label: 'Reconfigurar 2FA', toast: 'Redirecionando para app autenticador…' }, { ic: ICN.users, label: 'Encerrar sessões', onClick: () => setShowSessoes(true) }, ]} />
setShowSenha(true)} /> setShowSessoes(true)} /> { const data = JSON.stringify({ nome: vals.nome, email: vals.email, exportadoEm: new Date().toISOString() }, null, 2); const a = Object.assign(document.createElement('a'), { href: URL.createObjectURL(new Blob([data], {type:'application/json'})), download: 'meus-dados-ezza.json' }); a.click(); URL.revokeObjectURL(a.href); toast('Dados exportados ✓'); }} />
Conexões sociais
setShowConexoes(true)} />
); } function FieldRow({ label, value, badge, textarea, editing, onChange, onActivateEdit }) { return (
{label} {badge && {badge}}
{editing ? textarea ?