'use client'; import React, { useEffect, useMemo, useState } from 'react'; import DashboardLayout from '../adminDashboard/dashlayout'; import SiteCard from '@/components/dashboards/SiteCard'; type CrmProject = { name: string; // e.g. PROJ-0008 (siteId) project_name: string; status?: string | null; modified?: string | null; customer?: string | null; project_type?: string | null; custom_address?: string | null; custom_email?: string | null; custom_mobile_phone_no?: string | null; }; const API = process.env.NEXT_PUBLIC_FASTAPI_URL; const SitesPage = () => { const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(true); const [err, setErr] = useState(null); const [q, setQ] = useState(''); // search filter // pagination const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(6); // tweak as you like useEffect(() => { let cancelled = false; const run = async () => { setLoading(true); setErr(null); try { const res = await fetch(`${API}/crm/projects?limit=0`); if (!res.ok) throw new Error(await res.text()); const json = await res.json(); const data: CrmProject[] = json?.data ?? []; if (!cancelled) setProjects(data); } catch (e: any) { if (!cancelled) setErr(e?.message ?? 'Failed to load CRM projects'); } finally { if (!cancelled) setLoading(false); } }; run(); return () => { cancelled = true; }; }, []); // Reset to first page whenever search or pageSize changes useEffect(() => { setPage(1); }, [q, pageSize]); const filtered = useMemo(() => { if (!q.trim()) return projects; const needle = q.toLowerCase(); return projects.filter(p => (p.project_name || '').toLowerCase().includes(needle) || (p.name || '').toLowerCase().includes(needle) || (p.customer || '').toLowerCase().includes(needle) ); }, [projects, q]); const total = filtered.length; const totalPages = Math.max(1, Math.ceil(total / pageSize)); const safePage = Math.min(page, totalPages); const startIdx = (safePage - 1) * pageSize; const endIdx = Math.min(startIdx + pageSize, total); const pageItems = filtered.slice(startIdx, endIdx); const goPrev = () => setPage(p => Math.max(1, p - 1)); const goNext = () => setPage(p => Math.min(totalPages, p + 1)); return (

All Sites Overview

setQ(e.target.value)} placeholder="Search by name / ID / customer" className="w-64 max-w-full px-3 py-2 rounded-md border dark:border-gray-700 bg-white dark:bg-gray-900 dark:text-white" />
{loading && (
Loading CRM projects…
)} {err && (
Error: {err}
)} {!loading && !err && total === 0 && (
No sites found.
)} {!loading && !err && total > 0 && ( <> {/* Pagination header */}
Showing {startIdx + 1}{endIdx} of {total}
Page {safePage} / {totalPages}
{/* Cards */}
{pageItems.map(p => ( ))}
{/* Pagination footer mirrors header for convenience */}
Showing {startIdx + 1}{endIdx} of {total}
Page {safePage} / {totalPages}
)}
); }; export default SitesPage;