'use client'; import { useState, useEffect } from 'react'; import { useTranslations } from 'next-intl'; import { getAllOrganizations, verifySiret, approveSiret, rejectSiret } from '@/lib/api/admin'; import { createOrganization, updateOrganization } from '@/lib/api/organizations'; import { PageHeader } from '@/components/ui/PageHeader'; interface Organization { id: string; name: string; type: string; scac?: string; siren?: string; siret?: string; siretVerified?: boolean; statusBadge?: string; eori?: string; contact_phone?: string; contact_email?: string; address: { street: string; city: string; state?: string; postalCode: string; country: string; }; logoUrl?: string; isActive: boolean; createdAt: string; } export default function AdminOrganizationsPage() { const t = useTranslations('dashboard.admin.organizations'); const [organizations, setOrganizations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedOrg, setSelectedOrg] = useState(null); const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [verifyingId, setVerifyingId] = useState(null); // Form state const [formData, setFormData] = useState<{ name: string; type: string; scac: string; siren: string; siret: string; eori: string; contact_phone: string; contact_email: string; address: { street: string; city: string; state?: string; postalCode: string; country: string; }; logoUrl: string; }>({ name: '', type: 'FREIGHT_FORWARDER', scac: '', siren: '', siret: '', eori: '', contact_phone: '', contact_email: '', address: { street: '', city: '', state: '', postalCode: '', country: 'FR', }, logoUrl: '', }); useEffect(() => { fetchOrganizations(); }, []); const fetchOrganizations = async () => { try { setLoading(true); const response = await getAllOrganizations(); setOrganizations(response.organizations || []); setError(null); } catch (err: any) { setError(err.message || t('loadError')); } finally { setLoading(false); } }; const handleCreate = async (e: React.FormEvent) => { e.preventDefault(); try { const apiData = { name: formData.name, type: formData.type as any, address_street: formData.address.street, address_city: formData.address.city, address_postal_code: formData.address.postalCode, address_country: formData.address.country, contact_email: formData.contact_email || undefined, contact_phone: formData.contact_phone || undefined, logo_url: formData.logoUrl || undefined, }; await createOrganization(apiData); await fetchOrganizations(); setShowCreateModal(false); resetForm(); } catch (err: any) { alert(err.message || t('createError')); } }; const handleUpdate = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedOrg) return; try { await updateOrganization(selectedOrg.id, formData); await fetchOrganizations(); setShowEditModal(false); setSelectedOrg(null); resetForm(); } catch (err: any) { alert(err.message || t('updateError')); } }; const resetForm = () => { setFormData({ name: '', type: 'FREIGHT_FORWARDER', scac: '', siren: '', siret: '', eori: '', contact_phone: '', contact_email: '', address: { street: '', city: '', state: '', postalCode: '', country: 'FR', }, logoUrl: '', }); }; const handleVerifySiret = async (orgId: string) => { try { setVerifyingId(orgId); const result = await verifySiret(orgId); if (result.verified) { alert( t('siretVerified', { companyName: result.companyName || 'N/A', address: result.address || 'N/A', }) ); await fetchOrganizations(); } else { alert(result.message || t('siretInvalid')); } } catch (err: any) { alert(err.message || t('siretError')); } finally { setVerifyingId(null); } }; const handleApproveSiret = async (orgId: string) => { if (!confirm(t('confirmApprove'))) return; try { setVerifyingId(orgId); const result = await approveSiret(orgId); alert(result.message); await fetchOrganizations(); } catch (err: any) { alert(err.message || t('siretApproveError')); } finally { setVerifyingId(null); } }; const handleRejectSiret = async (orgId: string) => { if (!confirm(t('confirmReject'))) return; try { setVerifyingId(orgId); const result = await rejectSiret(orgId); alert(result.message); await fetchOrganizations(); } catch (err: any) { alert(err.message || t('siretRejectError')); } finally { setVerifyingId(null); } }; const openEditModal = (org: Organization) => { setSelectedOrg(org); setFormData({ name: org.name, type: org.type, scac: org.scac || '', siren: org.siren || '', siret: org.siret || '', eori: org.eori || '', contact_phone: org.contact_phone || '', contact_email: org.contact_email || '', address: org.address, logoUrl: org.logoUrl || '', }); setShowEditModal(true); }; const getTypeLabel = (type: string) => { const allowed = ['FREIGHT_FORWARDER', 'CARRIER', 'SHIPPER']; if (allowed.includes(type)) { return t(`types.${type}` as any); } return type.replace('_', ' '); }; if (loading) { return (

{t('loading')}

); } return (
setShowCreateModal(true)} className="px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors" > {t('create')} } /> {/* Error Message */} {error && (
{error}
)} {/* Organizations Grid */}
{organizations.map(org => (

{org.name}

{getTypeLabel(org.type)}
{org.isActive ? t('active') : t('inactive')}
{org.scac && (
{t('scac')}: {org.scac}
)} {org.siren && (
{t('siren')}: {org.siren}
)}
{t('siret')}: {org.siret ? ( <> {org.siret} {org.siretVerified ? ( {t('verified')} ) : ( {t('notVerified')} )} ) : ( {t('notProvided')} )}
{org.contact_email && (
{t('email')}: {org.contact_email}
)}
{t('location')}: {org.address.city},{' '} {org.address.country}
{org.siret && !org.siretVerified && ( )}
{(org.siret || org.siren) && (
{!org.siretVerified ? ( ) : ( )}
)}
))}
{/* Create/Edit Modal */} {(showCreateModal || showEditModal) && (

{showCreateModal ? t('modal.createTitle') : t('modal.editTitle')}

setFormData({ ...formData, name: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
{formData.type === 'CARRIER' && (
setFormData({ ...formData, scac: e.target.value.toUpperCase() }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
)}
setFormData({ ...formData, siren: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, siret: e.target.value.replace(/\D/g, '') }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" placeholder={t('modal.siretPlaceholder')} />
setFormData({ ...formData, eori: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, contact_phone: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, contact_email: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, address: { ...formData.address, street: e.target.value }, }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, address: { ...formData.address, city: e.target.value }, }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, address: { ...formData.address, postalCode: e.target.value }, }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, address: { ...formData.address, state: e.target.value }, }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, address: { ...formData.address, country: e.target.value.toUpperCase() }, }) } className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
setFormData({ ...formData, logoUrl: e.target.value })} className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 focus:outline-none" />
)}
); }