import React, { useState, useEffect, useCallback } from 'react'; import { UsersRound, Building2, RefreshCw, Trash2, Plus, KeyRound, Save } from 'lucide-react'; import { HybridBackend } from '../services/backend.ts'; import { useToast } from '../contexts/ToastContext.tsx'; import { useConfirm } from '../contexts/ConfirmContext.tsx'; import { PageHeader } from '../components/PageHeader.tsx'; // Área do Laboratório (Fase 4): dados PF/PJ (CPF/CNPJ) + equipe de técnicos. export const LabEquipeView: React.FC = () => { const toast = useToast(); const confirm = useConfirm(); const [dados, setDados] = useState(null); const [equipe, setEquipe] = useState([]); const [loading, setLoading] = useState(false); const [busy, setBusy] = useState(false); const [email, setEmail] = useState(''); const [nome, setNome] = useState(''); const [cred, setCred] = useState<{ email: string; senha: string } | null>(null); const carregar = useCallback(async () => { setLoading(true); try { const [d, e] = await Promise.all([HybridBackend.getLabDados(), HybridBackend.getLabEquipe()]); setDados(d || {}); setEquipe(Array.isArray(e) ? e : []); } catch { /* silent */ } finally { setLoading(false); } }, []); useEffect(() => { carregar(); }, [carregar]); const salvarDados = async () => { if (!dados?.nome_fantasia?.trim()) { toast.error('INFORME O NOME.'); return; } setBusy(true); try { await HybridBackend.updateLabDados({ nome_fantasia: dados.nome_fantasia, documento: dados.documento || '', pessoa_tipo: dados.pessoa_tipo }); toast.success('DADOS SALVOS.'); carregar(); } catch (e: any) { toast.error((e.message || 'ERRO').toUpperCase()); } finally { setBusy(false); } }; const addTecnico = async () => { if (!email.trim()) { toast.error('INFORME O E-MAIL.'); return; } setBusy(true); try { const r = await HybridBackend.addLabTecnico({ email: email.trim(), nome: nome.trim() || undefined }); toast.success('TÉCNICO ADICIONADO.'); if (r?.created && r?.tempPassword) setCred({ email: email.trim().toLowerCase(), senha: r.tempPassword }); setEmail(''); setNome(''); carregar(); } catch (e: any) { toast.error((e.message || 'ERRO').toUpperCase()); } finally { setBusy(false); } }; const remover = async (u: any) => { if (!(await confirm(`REMOVER ${u.nome || u.email} DA EQUIPE?`))) return; try { await HybridBackend.removeLabTecnico(u.id); toast.success('REMOVIDO.'); carregar(); } catch (e: any) { toast.error((e.message || 'ERRO').toUpperCase()); } }; if (loading || !dados) return
; const ehPJ = dados.pessoa_tipo === 'PJ'; return (
{/* Dados do provedor */}

Dados do provedor

{(['PF', 'PJ'] as const).map(t => ( ))}
setDados((d: any) => ({ ...d, nome_fantasia: e.target.value }))} className="w-full p-3 bg-gray-50 border-2 border-gray-100 rounded-xl text-sm font-bold text-gray-700 outline-none focus:border-teal-400 uppercase" />
setDados((d: any) => ({ ...d, documento: e.target.value }))} placeholder={ehPJ ? '00.000.000/0000-00' : '000.000.000-00'} className="w-full p-3 bg-gray-50 border-2 border-gray-100 rounded-xl text-sm font-bold text-gray-700 outline-none focus:border-teal-400" />
{/* Equipe */}

Equipe de técnicos

Técnicos veem a bancada e operam a produção — sem acesso a clientes, financeiro ou valores do paciente.

{cred && (

Credencial criada

{cred.email} · senha temporária: {cred.senha}

)}
{equipe.map(u => (
{(u.nome || u.email || '?')[0].toUpperCase()}

{u.nome || '—'}

{u.email}

))} {equipe.length === 0 &&

Nenhum técnico na equipe.

}
setNome(e.target.value)} placeholder="Nome (opcional)" className="w-32 p-2.5 bg-gray-50 border border-gray-100 rounded-lg text-xs outline-none focus:border-teal-400" /> setEmail(e.target.value)} placeholder="E-mail do técnico" className="flex-1 p-2.5 bg-gray-50 border border-gray-100 rounded-lg text-xs outline-none focus:border-teal-400" />
); };