"use client"; import { useState, useEffect } from "react"; import { useQuery } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ProjectCard } from "@/components/projects/ProjectCard"; import { NewProjectDialog } from "@/components/projects/NewProjectDialog"; import { Plus, Search, Loader2 } from "lucide-react"; export default function ProjectsPage() { const [search, setSearch] = useState(""); const [showNew, setShowNew] = useState(false); const { data, isLoading, isError } = useQuery({ queryKey: ["projects", search], queryFn: async () => { const res = await fetch(`/api/projects?q=${encodeURIComponent(search)}`); if (!res.ok) throw new Error("Failed to fetch projects"); return res.json() as Promise<{ projects: any[] }>; }, staleTime: 30_000, }); const { data: clientsData } = useQuery({ queryKey: ["clients"], queryFn: async () => { const res = await fetch("/api/clients"); if (!res.ok) return { clients: [] }; return res.json() as Promise<{ clients: { id: string; company: string }[] }>; }, staleTime: 60_000, }); const projects = data?.projects ?? []; const clients = clientsData?.clients ?? []; const SCROLL_KEY = 'projects-scroll'; useEffect(() => { if (!isLoading) { const saved = sessionStorage.getItem(SCROLL_KEY); if (saved) { sessionStorage.removeItem(SCROLL_KEY); requestAnimationFrame(() => window.scrollTo(0, parseInt(saved, 10))); } } }, [isLoading]); const saveScroll = () => sessionStorage.setItem(SCROLL_KEY, String(window.scrollY)); return (

Projects

{projects.length} project{projects.length !== 1 ? "s" : ""}

{/* Search */}
setSearch(e.target.value)} className="pl-9" />
{/* Grid */} {isLoading ? (
) : isError ? (

Could not load projects.

Check server logs and database connectivity, then refresh.

) : projects.length === 0 ? (

No projects found.

) : (
{projects.map((project) => (
))}
)} setShowNew(false)} clients={clients} />
); }