'use client'; import { useState, useCallback } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Search, UserPlus, Phone, MapPin, ChevronRight } from 'lucide-react'; import { api } from '@/lib/api'; import Link from 'next/link'; import { useDebounce } from '@/lib/hooks'; interface Client { id: string; firstName: string; lastName: string; email?: string; phone: string; address: string; accountNumber: string; isActive: boolean; subscriptions?: { status: string; plan?: { name: string; monthlyPrice: number } }[]; createdAt: string; } interface ClientsResponse { data: Client[]; meta?: { total: number; page: number; limit: number }; } function getSubStatus(client: Client): string { return client.subscriptions?.[0]?.status ?? 'NO_SUB'; } const STATUS_COLORS: Record = { ACTIVE: 'bg-emerald-100 text-emerald-700', PENDING: 'bg-yellow-100 text-yellow-700', SUSPENDED: 'bg-red-100 text-red-700', DISCONNECTED: 'bg-gray-100 text-gray-600', CANCELLED: 'bg-gray-100 text-gray-500', NO_SUB: 'bg-gray-100 text-gray-400', }; export default function ClientsPage() { const [search, setSearch] = useState(''); const [page, setPage] = useState(1); const debouncedSearch = useDebounce(search, 400); const limit = 20; const { data, isLoading } = useQuery({ queryKey: ['clients', debouncedSearch, page], queryFn: async () => { const params = new URLSearchParams({ page: String(page), limit: String(limit) }); if (debouncedSearch) params.set('search', debouncedSearch); const res = await api.get(`/api/v1/clients?${params}`); return res.data; }, }); const clients: Client[] = Array.isArray(data) ? data : (data?.data ?? []); const total = (data as any)?.meta?.total ?? clients.length; return (
{/* Header */}

Clients

{isLoading ? '...' : `${total} subscriber${total !== 1 ? 's' : ''}`}

{/* Search */}
{ setSearch(e.target.value); setPage(1); }} />
{/* Table */} Account # Name Phone Plan Status Address {isLoading ? ( Array.from({ length: 8 }).map((_, i) => ( {Array.from({ length: 7 }).map((_, j) => ( ))} )) ) : clients.length === 0 ? ( {search ? `No clients matching "${search}"` : 'No clients yet'} ) : ( clients.map((c) => { const subStatus = getSubStatus(c); const planName = c.subscriptions?.[0]?.plan?.name ?? '—'; return ( {c.accountNumber} {c.firstName} {c.lastName} {c.phone} {planName} {subStatus.replace('_', ' ')} {c.address} ); }) )}
{/* Pagination */} {total > limit && (
Page {page} of {Math.ceil(total / limit)}
)}
); }