"use client"; import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; import { UserPlus, Search, ChevronRight, RefreshCw } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card"; import { Button } from "@/components/ui/Button"; import { Input } from "@/components/ui/Input"; import { Modal } from "@/components/ui/Modal"; import { Badge } from "@/components/ui/Badge"; import api from "@/lib/api"; import { toast } from "sonner"; interface Area { id: string; name: string; } interface Plan { id: string; name: string; monthlyPrice: number; } interface Client { id: string; accountNumber: string; firstName: string; lastName: string; phone: string; email: string; address?: string; isActive: boolean; area: { id: string; name: string } | null; subscriptions: Array<{ status: string; type: string; monthlyPrice: string; plan?: { name: string }; }>; } interface ClientsMeta { total: number; page: number; limit: number; totalPages: number; } interface ClientsResponse { data: Client[]; meta: ClientsMeta; } const statusVariant: Record = { ACTIVE: "success", PENDING: "warning", SUSPENDED: "danger", DISCONNECTED: "muted", CANCELLED: "muted", }; export default function ClientsPage() { const router = useRouter(); const qc = useQueryClient(); const [search, setSearch] = useState(""); const [page, setPage] = useState(1); const [showAdd, setShowAdd] = useState(false); const [form, setForm] = useState({ firstName: "", lastName: "", email: "", phone: "", address: "", areaId: "", planId: "", billingType: "POSTPAID", }); const { data, isLoading, refetch } = useQuery({ queryKey: ["clients", search, page], queryFn: async () => { const params = new URLSearchParams({ page: String(page), limit: "20" }); if (search) params.set("search", search); const res = await api.get(`/api/v1/clients?${params}`); return res.data; }, }); const { data: areas = [] } = useQuery({ queryKey: ["areas"], queryFn: async () => { const r = await api.get("/api/v1/areas"); return r.data; }, }); // Fetch only active plans, filter client-side by billing type const { data: allActivePlans = [] } = useQuery<(Plan & { type: string; isActive: boolean })[]>({ queryKey: ["plans", "active"], queryFn: async () => { const r = await api.get("/api/v1/plans?isActive=true"); const raw = Array.isArray(r.data) ? r.data : (r.data as any).data ?? []; return raw; }, }); // Filter plans by selected billing type const filteredPlans = allActivePlans.filter(p => !form.billingType || p.type === form.billingType ); const createClient = useMutation({ mutationFn: async () => { const res = await api.post("/api/v1/clients", { firstName: form.firstName, lastName: form.lastName, email: form.email, phone: form.phone, address: form.address, areaId: form.areaId || undefined, planId: form.planId || undefined, }); return res.data; }, onSuccess: (data: any) => { toast.success("Client created successfully!"); qc.invalidateQueries({ queryKey: ["clients"] }); setShowAdd(false); setForm({ firstName: "", lastName: "", email: "", phone: "", address: "", areaId: "", planId: "", billingType: "POSTPAID" }); if (data?.id) router.push(`/clients/${data.id}`); }, onError: (e: any) => toast.error(e.response?.data?.message ?? "Failed to create client"), }); const clients = data?.data ?? []; const total = data?.meta?.total ?? 0; return (

Clients

{total} total clients

{ setSearch(e.target.value); setPage(1); }} />
{isLoading ? ( Array.from({ length: 8 }).map((_, i) => ( )) ) : clients.map((client) => { const sub = client.subscriptions?.[0]; const status = sub?.status ?? (client.isActive ? "ACTIVE" : "INACTIVE"); return ( router.push(`/clients/${client.id}`)} className="border-b hover:bg-blue-50 cursor-pointer transition-colors"> ); })}
Account # Name Area Plan Status Monthly
{client.accountNumber} {client.firstName} {client.lastName}
{client.phone}
{client.area?.name ?? "—"} {sub?.plan?.name ?? (sub ? sub.type : "—")} {status} {sub ? `₱${Number(sub.monthlyPrice).toLocaleString()}` : "—"}
{!isLoading && clients.length === 0 && (
No clients found{search ? ` for "${search}"` : ""}
)} {total > 20 && (
Showing {(page - 1) * 20 + 1}–{Math.min(page * 20, total)} of {total}
)}
{/* Add Client Modal */} setShowAdd(false)} title="Add New Client" className="max-w-xl">
setForm(f => ({ ...f, firstName: e.target.value }))} /> setForm(f => ({ ...f, lastName: e.target.value }))} />
setForm(f => ({ ...f, email: e.target.value }))} /> setForm(f => ({ ...f, phone: e.target.value }))} /> setForm(f => ({ ...f, address: e.target.value }))} />

Plan list filters to match this type

{filteredPlans.length === 0 && form.billingType && (

No active {form.billingType.toLowerCase()} plans available.

)}
); }