"use client"; import { useCallback, useEffect, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { Alert, Toast, ArchiveButton } from "@/src/Components/UI"; import { useClientAddresses } from "@/src/hooks/useClientAddresses"; import { clientService } from "@/src/services/client.service"; import { getStoredToken } from "@/src/lib/auth"; import type { Client, ClientFormData } from "@/src/types/client"; import type { ClientAddress } from "@/src/types/client_adresses"; import { AddressFormModal, DeleteConfirmModal, ClientFormModal } from "@/src/Components/Client"; import { ArchivedClientsAddressesModal } from "@/src/Components/Client_Adress/archive/ArchivedClientsAddressesModal"; import type { CreateAddressFormValues, UpdateAddressFormValues, } from "@/src/validations/client_address.validator"; // ─── Helpers ─────────────────────────────────────────────────────────────── function labelIcon(label: string): string { const map: Record = { "فوترة": "💳", "شحن": "📦", "المقر الرئيسي": "🏢", "فرع": "🏬", "مستودع": "🏭", billing: "💳", shipping: "📦", "head office": "🏢", branch: "🏬", warehouse: "🏭", }; return map[label.toLowerCase()] ?? "📍"; } // ─── AddressCard ─────────────────────────────────────────────────────────── interface AddressCardProps { address: ClientAddress; onEdit: () => void; onDelete: () => void; } function AddressCard({ address, onEdit, onDelete }: AddressCardProps) { const { details, contactPerson } = address; const { street, city, state, district, buildingNo, unitNo, additionalNo, zipCode, country, } = details; return (
{/* Label row */}
{address.label} {address.branchName && ( {address.branchName} )} {address.isPrimary && ( أساسي )}
{/* Address details — rendered fully in-card */}

{street}

{district &&

حي {district}

}

{city} {state ? `، ${state}` : ""} {zipCode ? ` ${zipCode}` : ""}

{(buildingNo || unitNo || additionalNo) && (

{buildingNo && `مبنى ${buildingNo}`} {unitNo && ` · وحدة ${unitNo}`} {additionalNo && ` · رقم إضافي ${additionalNo}`}

)}

{country}

{/* Contact person — only when present */} {(contactPerson?.name || contactPerson?.phone) && (
👤 {contactPerson?.name && {contactPerson.name}} {contactPerson?.phone && ( {contactPerson.phone} )}
)} {/* Actions */}
تعديل حذف
); } function ActionBtn({ onClick, color, bg, border, style, disabled, children, }: { onClick: () => void; color: string; bg: string; border: string; style?: React.CSSProperties; disabled?: boolean; children: React.ReactNode; }) { return ( ); } // ─── ClientEditModal ─────────────────────────────────────────────────────── interface ClientEditModalProps { client: Client; onClose: () => void; onSubmit: (data: ClientFormData, isNew: boolean) => Promise; } function ClientEditModal({ client, onClose, onSubmit }: ClientEditModalProps) { return (
{ if (e.target === e.currentTarget) onClose(); }} style={{ position: "fixed", inset: 0, zIndex: 50, background: "rgba(15,23,42,0.55)", backdropFilter: "blur(4px)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "2rem 1rem", overflowY: "auto", }} >
e.stopPropagation()} style={{ width: "100%", maxWidth: 520, background: "var(--color-surface)", borderRadius: "var(--radius-2xl)", border: "1px solid var(--color-border)", boxShadow: "0 24px 64px rgba(0,0,0,.18)", overflow: "hidden", }} >
); } // ─── Page ────────────────────────────────────────────────────────────────── export default function ClientAddressesPage() { const params = useParams(); const router = useRouter(); const clientId = (params?.clientId ?? params?.id) as string | undefined; useEffect(() => { if (!clientId) { console.warn("ClientAddressesPage: clientId missing from route params."); } }, [clientId]); // ── Parent client ──────────────────────────────────────────────────────── const [client, setClient] = useState(null); const [clientLoading, setClientLoading] = useState(true); const loadClient = useCallback(() => { if (!clientId) return; queueMicrotask(() => { setClientLoading(true); clientService .getById(clientId, getStoredToken()) .then((res) => setClient(res.data)) .catch(() => router.replace("/dashboard/clients")) .finally(() => setClientLoading(false)); }); }, [clientId, router]); useEffect(() => { loadClient(); }, [loadClient]); // ── Address hook ───────────────────────────────────────────────────────── const { addresses, loading: addrLoading, error, notification, clearError, createAddress, updateAddress, deleteAddress, } = useClientAddresses(clientId ?? ""); // ── Modal state ────────────────────────────────────────────────────────── const [addrFormTarget, setAddrFormTarget] = useState(false); const [deleteTarget, setDeleteTarget] = useState(null); const [deleting, setDeleting] = useState(false); const [editingClient, setEditingClient] = useState(false); // Archive browser modal open/closed — scoped to this client's addresses const [archiveOpen, setArchiveOpen] = useState(false); // ── Address form handler ───────────────────────────────────────────────── const handleAddressSubmit = async ( data: CreateAddressFormValues | UpdateAddressFormValues ): Promise => { if (addrFormTarget === null) return createAddress(data as CreateAddressFormValues); if (addrFormTarget === false) return false; return updateAddress(addrFormTarget.id, data as UpdateAddressFormValues); }; // ── Delete handler ─────────────────────────────────────────────────────── const handleDeleteConfirm = async () => { if (!deleteTarget || deleting) return; setDeleting(true); const ok = await deleteAddress(deleteTarget.id); setDeleting(false); if (ok) setDeleteTarget(null); }; // ── Client edit handler ────────────────────────────────────────────────── const handleClientEditSubmit = async ( data: ClientFormData, ): Promise => { if (!client) return false; try { const res = await clientService.update(client.id, data, getStoredToken()); setClient(res.data); return true; } catch { return false; } }; // ── Loading guard ──────────────────────────────────────────────────────── if (!clientId || clientLoading) { return (
); } // ── Render ──────────────────────────────────────────────────────────────── return ( <> {/* Address create / edit modal */} {addrFormTarget !== false && ( setAddrFormTarget(false)} onSubmit={handleAddressSubmit} /> )} {/* Delete confirmation */} {deleteTarget && ( { if (!deleting) setDeleteTarget(null); }} onConfirm={handleDeleteConfirm} /> )} {/* Client edit modal */} {editingClient && client && ( setEditingClient(false)} onSubmit={handleClientEditSubmit} /> )} {/* Archived addresses browser — scoped to this client */} {archiveOpen && ( setArchiveOpen(false)} /> )}
{/* ── Header ── */}

إدارة العناوين

{client ? `${client.name} — العناوين` : "العناوين"}

إجمالي{" "} {addresses.length}{" "} عنوان

{client && ( )}
{/* Client info strip */} {client && (
{client.name} {client.email} {client.phone} {client.taxId && ( {client.taxId} )}
)}
{error && } {/* ── Address grid ── */} {addrLoading ? (
جارٍ تحميل العناوين…
) : addresses.length === 0 ? (

📍

لا توجد عناوين بعد

أضف عنواناً واحداً على الأقل حتى يتمكن العميل من استقبال الشحنات والفواتير.

) : (
{addresses.map((addr) => ( setAddrFormTarget(addr)} onDelete={() => setDeleteTarget(addr)} /> ))}
)}
{/* Floating button to open the address archive for this client */} setArchiveOpen(true)} label="أرشيف العناوين" /> ); }