import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { apiGet, apiPost, apiPatch, apiDelete } from '@/api/client'; interface Address { id: string; entity_type: string; entity_id: string; label: string; address_type: string; street: string | null; street_number: string | null; city: string | null; zip: string | null; state: string | null; country: string | null; is_default: boolean; created_at: string | null; updated_at: string | null; } interface AddressListProps { entityType: 'company' | 'contact'; entityId: string; } const ADDRESS_TYPE_COLORS: Record = { billing: 'bg-blue-100 text-blue-800', shipping: 'bg-purple-100 text-purple-800', headquarters: 'bg-green-100 text-green-800', branch: 'bg-yellow-100 text-yellow-800', private: 'bg-pink-100 text-pink-800', other: 'bg-gray-100 text-gray-800', }; export function AddressList({ entityType, entityId }: AddressListProps) { const { t } = useTranslation(); const [addresses, setAddresses] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showForm, setShowForm] = useState(false); const [editingAddress, setEditingAddress] = useState
(null); const fetchAddresses = React.useCallback(async () => { setLoading(true); setError(null); try { const data = await apiGet<{ items: Address[]; total: number }>( `/addresses?entity_type=${entityType}&entity_id=${entityId}` ); setAddresses(data.items); } catch (err: any) { setError(err.message || t('common.error')); } finally { setLoading(false); } }, [entityType, entityId, t]); React.useEffect(() => { fetchAddresses(); }, [fetchAddresses]); const handleDelete = async (id: string) => { if (!window.confirm(t('address.confirmDelete'))) return; try { await apiDelete(`/addresses/${id}`); await fetchAddresses(); } catch (err: any) { setError(err.message || t('common.error')); } }; const handleSetDefault = async (id: string) => { try { await apiPatch(`/addresses/${id}`, { is_default: true }); await fetchAddresses(); } catch (err: any) { setError(err.message || t('common.error')); } }; const handleSave = async (data: Partial
) => { try { if (editingAddress) { await apiPatch(`/addresses/${editingAddress.id}`, data); } else { await apiPost('/addresses', { ...data, entity_type: entityType, entity_id: entityId }); } setShowForm(false); setEditingAddress(null); await fetchAddresses(); } catch (err: any) { setError(err.message || t('common.error')); } }; if (loading) { return
{t('common.loading')}
; } return (

{t('address.title')}

{error && (
{error}
)} {showForm && ( { setShowForm(false); setEditingAddress(null); }} /> )} {addresses.length === 0 && !showForm ? (

{t('address.noAddresses')}

) : (
{addresses.map((addr) => (
{addr.label} {t(`addressType.${addr.address_type}`)} {addr.is_default && ( {t('address.defaultAddress')} )}
{addr.street && {addr.street}} {addr.street_number && {addr.street_number}} {(addr.street || addr.street_number) &&
} {addr.zip && {addr.zip} } {addr.city && {addr.city}} {(addr.zip || addr.city) &&
} {addr.state && {addr.state}, } {addr.country && {addr.country}}
{!addr.is_default && ( )}
))}
)}
); } function AddressForm({ address, onSave, onCancel, }: { address: Address | null; onSave: (data: Partial
) => void; onCancel: () => void; }) { const { t } = useTranslation(); const [label, setLabel] = useState(address?.label || ''); const [addressType, setAddressType] = useState(address?.address_type || 'headquarters'); const [street, setStreet] = useState(address?.street || ''); const [streetNumber, setStreetNumber] = useState(address?.street_number || ''); const [city, setCity] = useState(address?.city || ''); const [zip, setZip] = useState(address?.zip || ''); const [state, setState] = useState(address?.state || ''); const [country, setCountry] = useState(address?.country || ''); const [isDefault, setIsDefault] = useState(address?.is_default || false); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ label, address_type: addressType, street, street_number: streetNumber, city, zip, state, country, is_default: isDefault }); }; const addressTypes = ['billing', 'shipping', 'headquarters', 'branch', 'private', 'other']; return (
setLabel(e.target.value)} required className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setStreet(e.target.value)} className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setStreetNumber(e.target.value)} className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setZip(e.target.value)} className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setCity(e.target.value)} className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setState(e.target.value)} className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
setCountry(e.target.value)} maxLength={2} placeholder="DE" className="mt-1 block w-full rounded-md border border-secondary-300 px-3 py-1.5 text-sm" />
); }