import { useEffect, useState } from 'react' import { adminService, Company, CreateCompanyRequest } from '@/services/adminService' import { useCepLookup } from '@/hooks/useCepLookup' import { formatCNPJ, validateCNPJ } from '@/utils/cnpj' import { formatPhone } from '@/utils/phone' export function CompaniesPage() { const [companies, setCompanies] = useState([]) const [loading, setLoading] = useState(true) const [filterStatus, setFilterStatus] = useState<'all' | 'verified' | 'pending'>('all') const [page, setPage] = useState(1) const [total, setTotal] = useState(0) const [showModal, setShowModal] = useState(false) const [editingCompany, setEditingCompany] = useState(null) const [companyDocuments, setCompanyDocuments] = useState([]) const [formData, setFormData] = useState({ cnpj: '', corporate_name: '', fantasy_name: '', category: 'farmacia', license_number: '', latitude: -16.3281, longitude: -48.9530, city: 'An├ípolis', state: 'GO', phone: '', email: '', founded_at: '', }) const [cep, setCep] = useState('') const [cnpjError, setCnpjError] = useState(null) const { loading: cepLoading, error: cepError, lookup } = useCepLookup() const handleCepChange = async (value: string) => { const clean = value.replace(/\D/g, '') setCep(value) if (clean.length === 8) { const data = await lookup(clean) if (data) { setFormData(prev => ({ ...prev, city: data.localidade, state: data.uf, latitude: data.latitude, longitude: data.longitude })) } } } const pageSize = 50 useEffect(() => { loadCompanies() }, [page]) const loadCompanies = async () => { setLoading(true) try { const data = await adminService.listCompanies(page, pageSize) setCompanies(data.tenants || []) setTotal(data.total) } catch (err) { console.error('Error loading companies:', err) } finally { setLoading(false) } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() // Only validate CNPJ on create (not on edit, since existing CNPJs may be legacy/test values) if (!editingCompany) { if (!formData.cnpj) { setCnpjError('CNPJ ├® obrigat├│rio') return } const cnpjDigits = formData.cnpj.replace(/\D/g, '') if (cnpjDigits.length !== 14) { setCnpjError('CNPJ deve ter 14 d├¡gitos') return } if (!validateCNPJ(formData.cnpj)) { setCnpjError('CNPJ inv├ílido. Verifique o d├¡gito verificador') return } } // Strip CNPJ formatting before sending to API const payload = { ...formData, cnpj: formData.cnpj.replace(/\D/g, ''), } try { if (editingCompany) { await adminService.updateCompany(editingCompany.id, payload) } else { await adminService.createCompany(payload) } setShowModal(false) resetForm() void loadCompanies() } catch (err) { console.error('Error saving company:', err) alert('Erro ao salvar empresa') } } const handleDelete = async (id: string) => { if (!confirm('Tem certeza que deseja excluir esta empresa?')) return try { await adminService.deleteCompany(id) loadCompanies() } catch (err) { console.error('Error deleting company:', err) alert('Erro ao excluir empresa') } } const handleVerify = async (id: string) => { try { await adminService.verifyCompany(id) loadCompanies() } catch (err) { console.error('Error verifying company:', err) } } const openEdit = async (company: Company) => { setEditingCompany(company) setCnpjError(null) setFormData({ cnpj: formatCNPJ(company.cnpj ?? ''), corporate_name: company.corporate_name ?? '', fantasy_name: company.fantasy_name ?? '', category: company.category ?? 'farmacia', license_number: company.license_number ?? '', latitude: typeof company.latitude === 'number' ? company.latitude : -16.3281, longitude: typeof company.longitude === 'number' ? company.longitude : -48.9530, city: company.city ?? '', state: company.state ?? '', phone: company.phone ?? '', email: company.email ?? '', founded_at: company.founded_at ? company.founded_at.slice(0, 10) : '', }) setShowModal(true) try { const docs = await adminService.getCompanyDocuments(company.id) setCompanyDocuments(Array.isArray(docs) ? docs : []) } catch (err) { console.error('Failed to load company docs', err) setCompanyDocuments([]) } } const resetForm = () => { setEditingCompany(null) setCep('') setCnpjError(null) setCompanyDocuments([]) setFormData({ cnpj: '', corporate_name: '', fantasy_name: '', category: 'farmacia', license_number: '', latitude: -16.3281, longitude: -48.9530, city: 'An├ípolis', state: 'GO', phone: '', email: '', founded_at: '', }) } const openCreate = () => { resetForm() setShowModal(true) } const filteredCompanies = companies.filter(c => { if (filterStatus === 'all') return true if (filterStatus === 'verified') return c.is_verified if (filterStatus === 'pending') return !c.is_verified return true }) const totalPages = Math.ceil(total / pageSize) return (

Empresas

{/* Table */}
{loading ? ( ) : filteredCompanies.length === 0 ? ( ) : ( filteredCompanies.map((company) => ( )) )}
Raz├úo Social CNPJ Categoria Cidade Verificada A├º├Áes
Carregando...
Nenhuma empresa encontrada
{company.corporate_name} {company.cnpj} {company.category} {company.city}/{company.state}
{/* Pagination */} {totalPages > 1 && (

Mostrando {(page - 1) * pageSize + 1} a {Math.min(page * pageSize, total)} de {total}

)} {/* Modal */} {showModal && (

{editingCompany ? 'Editar Empresa' : 'Nova Empresa'}

{/* CNPJ */}
{ const formatted = formatCNPJ(e.target.value) setFormData({ ...formData, cnpj: formatted }) if (cnpjError) setCnpjError(null) }} maxLength={18} placeholder="00.000.000/0000-00" disabled={!!editingCompany} className={`mt-1 w-full rounded border px-3 py-2 font-mono focus:ring-1 outline-none ${editingCompany ? 'border-gray-200 bg-gray-100 text-gray-500 cursor-not-allowed' : cnpjError ? 'border-red-500 bg-red-50 focus:border-red-500 focus:ring-red-500' : 'border-gray-300 focus:border-blue-500 focus:ring-blue-500' }`} required={!editingCompany} /> {cnpjError && (

{cnpjError}

)}
{/* Nome Fantasia */}
setFormData({ ...formData, fantasy_name: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" placeholder="Nome fantasia da empresa" />
{/* Razão Social */}
setFormData({ ...formData, corporate_name: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" required />
{/* Data de Abertura */}
setFormData({ ...formData, founded_at: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" />
{/* Categoria */}
{/* Telefone */}
setFormData({ ...formData, phone: formatPhone(e.target.value) })} placeholder="(00) 00000-0000" maxLength={15} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" />
{/* Email */}
setFormData({ ...formData, email: e.target.value })} placeholder="contato@empresa.com.br" className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" />
{/* Licença Sanitária */}
setFormData({ ...formData, license_number: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" required />
{editingCompany && (
{ const file = e.target.files?.[0]; if (!file) return; try { await adminService.uploadDocument(file, 'LICENSE', editingCompany.id); alert('Documento enviado com sucesso!'); // reload docs const docs = await adminService.getCompanyDocuments(editingCompany.id) setCompanyDocuments(docs) } catch (err) { console.error('Upload failed', err); alert('Falha ao enviar documento.'); } // Reset input so it can be used again e.target.value = ''; }} className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" /> {(companyDocuments ?? []).length > 0 && (

Documentos Anexados:

    {(companyDocuments ?? []).map(doc => (
  • {doc.type}: {(doc.url ?? '').split('/').pop()} {doc.status}
    Abrir
  • ))}
)}
)}
handleCepChange(e.target.value)} placeholder="00000-000" maxLength={9} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" /> {cepError &&

{cepError}

}
setFormData({ ...formData, city: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" required />
setFormData({ ...formData, state: e.target.value })} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" maxLength={2} required />
{ const v = parseFloat(e.target.value) setFormData({ ...formData, latitude: Number.isFinite(v) ? v : 0 }) }} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" required />
{ const v = parseFloat(e.target.value) setFormData({ ...formData, longitude: Number.isFinite(v) ? v : 0 }) }} className="mt-1 w-full rounded border border-gray-300 px-3 py-2 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none" required />
)}
) }