// Projects index page — filterable grid. function Projects({ navigate, initialFilter = "all" }) { const data = window.DS_DATA; const [filter, setFilter] = useState(initialFilter); const [sort, setSort] = useState("year-desc"); const [view, setView] = useState("grid"); useEffect(() => { setFilter(initialFilter); }, [initialFilter]); const filtered = useMemo(() => { let list = data.projects; if (filter !== "all") list = list.filter((p) => p.sector === filter); if (sort === "year-desc") list = [...list].sort((a, b) => b.year - a.year); if (sort === "year-asc") list = [...list].sort((a, b) => a.year - b.year); if (sort === "az") list = [...list].sort((a, b) => a.name.localeCompare(b.name)); return list; }, [filter, sort, data.projects]); const chips = [ { id: "all", label: "All", count: data.projects.length }, ...data.sectors.map((s) => ({ id: s.id, label: s.label, count: data.projects.filter((p) => p.sector === s.id).length })), ]; return (
Portfolio

{filter === "all" ? "Selected work — every sector, attributed." : (data.sectors.find((s) => s.id === filter)?.label || "All") + " portfolio."}

{filter === "all" ? "A working portfolio of recent named builds across hospitality, commercial, residential, healthcare, wellness and tower construction. Each card opens a structured case study." : data.sectors.find((s) => s.id === filter)?.blurb}


{/* Filter + sort bar */}
{chips.map((c) => ( ))}
View
Sort

{view === "grid" ? (
{filtered.map((p) => ( navigate({ name: "project", id: p.id })} /> ))}
) : ( )} {filtered.length === 0 ? (
No projects under this filter.
) : null}
); } function ProjectIndexTable({ projects, navigate }) { return (
No. Project Sector Location Scope Year
{projects.map((p, i) => ( ))}
); } Object.assign(window, { Projects });