"use client"; /** * ClientTable — Enhanced version * * Changes from original: * 1. Clicking a row now opens an inline ClientDetailPanel (slide-down) showing full client info. * 2. "Addresses" link inside the detail panel navigates to /dashboard/clients/[clientId]/addresses. * 3. The row-level onClick still calls onManageAddresses (kept for backwards-compatibility), * but the primary UX is now the expandable detail panel. * 4. Active row is highlighted with a brand-tinted left border. */ import { useState } from "react"; import { Spinner } from "../UI"; import type { Client } from "@/src/types/client"; // ── Address count badge ──────────────────────────────────────────────────── function AddressBadge({ count, onClick }: { count: number; onClick: () => void }) { const hasAddr = count > 0; return ( ); } // ── Status badge ─────────────────────────────────────────────────────────── function StatusBadge({ active }: { active?: boolean }) { const isActive = active !== false; return ( {isActive ? "نشط" : "غير نشط"} ); } // ── Icon button ──────────────────────────────────────────────────────────── function IconBtn({ onClick, title, color, bg, borderColor, children, }: { onClick: () => void; title: string; color: string; bg: string; borderColor: string; children: React.ReactNode; }) { return ( ); } // ── Client detail panel (inline expandable) ──────────────────────────────── /** * ClientDetailPanel — shown below the clicked row. * Displays all client fields (name, email, phone, taxId, notes, createdAt) * and provides a direct link to the addresses sub-page. * * @param client The client whose details are rendered. * @param onGoAddresses Callback that navigates to /dashboard/clients/[id]/addresses. * @param onEdit Opens the edit modal for this client. */ function ClientDetailPanel({ client, onGoAddresses, onEdit, }: { client: Client; onGoAddresses: () => void; onEdit: () => void; }) { const infoItem = (label: string, value: React.ReactNode) => (
{label} {value || }
); return (
{/* ── Top row: name + quick actions ── */}

{client.name}

{client.taxId && ( {client.taxId} )}
{/* Action buttons */}
{/* Edit client */} {/* * "Addresses" button — KEY FEATURE: * Navigates to /dashboard/clients/[clientId]/addresses */}
{/* ── Info grid ── */}
{infoItem( "البريد الإلكتروني", e.stopPropagation()} style={{ color: "#2563EB", textDecoration: "none" }} > {client.email} , )} {infoItem("الهاتف", client.phone)} {infoItem( "تاريخ الإضافة", new Date(client.createdAt).toLocaleDateString("ar-SA", { year: "numeric", month: "long", day: "numeric", }), )} {infoItem( "آخر تحديث", new Date(client.updatedAt).toLocaleDateString("ar-SA", { year: "numeric", month: "long", day: "numeric", }), )} {client.notes && infoItem("ملاحظات", client.notes)}
{/* Keyframe animation injected via a style tag (scoped) */}
); } // ── Shared card & header styles ──────────────────────────────────────────── const cardStyle: React.CSSProperties = { borderRadius: "var(--radius-xl)", border: "1px solid var(--color-border)", background: "var(--color-surface)", overflow: "hidden", boxShadow: "var(--shadow-card)", }; const thStyle: React.CSSProperties = { padding: "0.75rem 1.5rem", fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.2em", color: "var(--color-text-muted)", background: "var(--color-surface-muted)", borderBottom: "1px solid var(--color-border)", }; // ── Props ────────────────────────────────────────────────────────────────── interface ClientTableProps { clients: Client[]; loading: boolean; search: string; page: number; pages: number; onEdit: (client: Client) => void; onDelete: (client: Client) => void; onAddFirst: () => void; onPageChange: (p: number) => void; /** Navigate to address management for a client */ onManageAddresses: (client: Client) => void; } // ── Main table ───────────────────────────────────────────────────────────── export function ClientTable({ clients, loading, search, page, pages, onEdit, onDelete, onAddFirst, onPageChange, onManageAddresses, }: ClientTableProps) { /** * expandedId — tracks which client row is currently expanded. * Clicking the same row again collapses it (toggle behaviour). */ const [expandedId, setExpandedId] = useState(null); const handleRowClick = (client: Client) => { // Toggle: collapse if already open, expand otherwise setExpandedId((prev) => (prev === client.id ? null : client.id)); }; return (
{/* Column headers */}
العميل البريد الإلكتروني الهاتف العناوين تاريخ الإضافة إجراءات
{/* Loading */} {loading ? (
جارٍ التحميل…
) : clients.length === 0 ? ( /* Empty state */

{search ? `لا توجد نتائج لـ "${search}"` : "لا يوجد عملاء لعرضهم."}

{!search && ( )}
) : ( /* Data rows */
    {clients.map((c, i) => { const isExpanded = expandedId === c.id; return (
  • {/* ── Main row ── */}
    { if (e.key === "Enter" || e.key === " ") handleRowClick(c); }} onClick={() => handleRowClick(c)} style={{ display: "grid", gridTemplateColumns: "2fr 1.5fr 1.5fr 1fr 1fr 80px", alignItems: "center", gap: "0.5rem", padding: "0.875rem 1.5rem", borderBottom: isExpanded ? "none" : "1px solid var(--color-border)", /* Highlight the expanded row with a brand-tinted background */ background: isExpanded ? "#EFF6FF" : i % 2 !== 0 ? "var(--color-surface-muted)" : "transparent", /* Left accent border when expanded (RTL: border-right in visual) */ borderRight: isExpanded ? "3px solid var(--color-brand-600)" : "3px solid transparent", fontSize: 13, cursor: "pointer", transition: "background 120ms, border-color 120ms", outline: "none", }} > {/* Name */}

    {c.name} {/* Chevron indicator — rotates when expanded */}

    {c.taxId && (

    {c.taxId}

    )}
    {/* Email */} {c.email} {/* Phone */} {c.phone} {/* * Address count badge — clicking it navigates directly to * /dashboard/clients/[clientId]/addresses (bypasses the detail panel). */} onManageAddresses(c)} /> {/* Created at */} {new Date(c.createdAt).toLocaleDateString("ar-SA", { year: "numeric", month: "short", day: "numeric", })} {/* Row action buttons */}
    e.stopPropagation()} > onEdit(c)} > onDelete(c)} >
    {/* * ── Expandable detail panel ── * Rendered inline below the row when isExpanded is true. * Contains full client metadata + "العناوين" navigation button. * * TEST: Click any row → panel slides in with client details. * Click "العناوين" → router.push to /dashboard/clients/[id]/addresses. * Click same row again → panel collapses. */} {isExpanded && ( onManageAddresses(c)} onEdit={() => onEdit(c)} /> )}
  • ); })}
)} {/* Pagination */} {pages > 1 && (
صفحة{" "} {page}{" "} من{" "} {pages}
{[ { label: "السابق", action: () => onPageChange(Math.max(1, page - 1)), disabled: page === 1, }, { label: "التالي", action: () => onPageChange(Math.min(pages, page + 1)), disabled: page === pages, }, ].map((btn) => ( ))}
)}
); }