'use client'; import { useEffect, useState, useCallback } from 'react'; import { useSearchParams } from 'next/navigation'; import { useTranslations } from 'next-intl'; import { useAuth } from '@/lib/context/auth-context'; import { getOrganization, updateOrganization } from '@/lib/api/organizations'; import type { OrganizationResponse } from '@/types/api'; import SubscriptionTab from '@/components/organization/SubscriptionTab'; import LicensesTab from '@/components/organization/LicensesTab'; interface OrganizationForm { name: string; siren: string; eori: string; contact_phone: string; contact_email: string; address_street: string; address_city: string; address_postal_code: string; address_country: string; } type TabType = 'information' | 'address' | 'subscription' | 'licenses'; export default function OrganizationSettingsPage() { const t = useTranslations('dashboard.organizationSettings'); const { user } = useAuth(); const searchParams = useSearchParams(); const [activeTab, setActiveTab] = useState('information'); useEffect(() => { const isSuccess = searchParams.get('success') === 'true'; const isCanceled = searchParams.get('canceled') === 'true'; const canAccessBilling = user?.role === 'ADMIN' || user?.role === 'MANAGER'; if ((isSuccess || isCanceled) && canAccessBilling) { setActiveTab('subscription'); } }, [searchParams, user?.role]); const [organization, setOrganization] = useState(null); const [formData, setFormData] = useState({ name: '', siren: '', eori: '', contact_phone: '', contact_email: '', address_street: '', address_city: '', address_postal_code: '', address_country: 'FR', }); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); const canEdit = user?.role === 'ADMIN' || user?.role === 'MANAGER'; const loadOrganization = useCallback(async () => { if (!user?.organizationId) return; try { setIsLoading(true); setError(null); const org = await getOrganization(user.organizationId); setOrganization(org); setFormData({ name: org.name || '', siren: org.siren || '', eori: org.eori || '', contact_phone: org.contact_phone || '', contact_email: org.contact_email || '', address_street: org.address?.street || '', address_city: org.address?.city || '', address_postal_code: org.address?.postalCode || '', address_country: org.address?.country || 'FR', }); } catch (err) { console.error('Failed to load organization:', err); setError(err instanceof Error ? err.message : t('loadFailed')); } finally { setIsLoading(false); } }, [user, t]); useEffect(() => { if (user?.organizationId) { loadOrganization(); } }, [user?.organizationId, loadOrganization]); const handleChange = (field: keyof OrganizationForm, value: string) => { setFormData(prev => ({ ...prev, [field]: value })); setSuccessMessage(null); }; const handleCancel = () => { if (organization) { setFormData({ name: organization.name || '', siren: organization.siren || '', eori: organization.eori || '', contact_phone: organization.contact_phone || '', contact_email: organization.contact_email || '', address_street: organization.address?.street || '', address_city: organization.address?.city || '', address_postal_code: organization.address?.postalCode || '', address_country: organization.address?.country || 'FR', }); setSuccessMessage(null); setError(null); } }; const handleSave = async () => { if (!user?.organizationId) return; try { setIsSaving(true); setError(null); setSuccessMessage(null); const updatedOrg = await updateOrganization(user.organizationId, { name: formData.name, siren: formData.siren, eori: formData.eori, contact_phone: formData.contact_phone, contact_email: formData.contact_email, address: { street: formData.address_street, city: formData.address_city, postalCode: formData.address_postal_code, country: formData.address_country, }, }); setOrganization(updatedOrg); setSuccessMessage(t('saveSuccess')); } catch (err) { console.error('Failed to update organization:', err); setError(err instanceof Error ? err.message : t('saveFailed')); } finally { setIsSaving(false); } }; if (isLoading) { return (

{t('loading')}

); } if (!organization) { return (

{t('errorTitle')}

{error || t('loadError')}

); } const canViewBilling = user?.role === 'ADMIN' || user?.role === 'MANAGER'; const tabs = [ { id: 'information' as TabType, label: t('tabs.information'), icon: ( ), }, { id: 'address' as TabType, label: t('tabs.address'), icon: ( ), }, ...(canViewBilling ? [ { id: 'subscription' as TabType, label: t('tabs.subscription'), icon: ( ), }, { id: 'licenses' as TabType, label: t('tabs.licenses'), icon: ( ), }, ] : []), ]; return (

{t('header.title')}

{t('header.subtitle')}

{successMessage && (activeTab === 'information' || activeTab === 'address') && (

{successMessage}

)} {error && (activeTab === 'information' || activeTab === 'address') && (

{error}

)} {!canEdit && (activeTab === 'information' || activeTab === 'address') && (

{t('readOnlyWarning')}

)}
{activeTab === 'information' && (
handleChange('name', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('information.namePlaceholder')} required />
handleChange('siren', e.target.value.replace(/\D/g, '').slice(0, 9)) } disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('information.sirenPlaceholder')} maxLength={9} />

{t('information.sirenDigits')}

handleChange('eori', e.target.value.toUpperCase())} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('information.eoriPlaceholder')} maxLength={17} />

{t('information.eoriHelp')}

handleChange('contact_phone', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('information.phonePlaceholder')} />
handleChange('contact_email', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('information.emailPlaceholder')} />
)} {activeTab === 'address' && (
handleChange('address_street', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('address.streetPlaceholder')} required />
handleChange('address_postal_code', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('address.postalCodePlaceholder')} required />
handleChange('address_city', e.target.value)} disabled={!canEdit} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder={t('address.cityPlaceholder')} required />
)} {activeTab === 'subscription' && canViewBilling && } {activeTab === 'licenses' && canViewBilling && }
{canEdit && (activeTab === 'information' || activeTab === 'address') && (
)}
); }