import { type ReactElement } from 'react'; import { useNavigate } from 'react-router-dom'; import { ProjectCard } from '@/components/projects/project-card'; import { StaleDataNotice, UnavailableDataNotice } from '@/components/freshness/freshness-notices'; import { api } from '@/lib/api'; import type { Project } from '@/lib/types'; import { useFreshCollection, describeFailure } from '@/lib/freshness/use-fresh-collection'; import { validateProjectCollection } from '@/lib/freshness/validators'; export function ProjectsPage(): ReactElement { const navigate = useNavigate(); const projects = useFreshCollection({ source: 'gateway:/api/projects', fetcher: (signal) => api('/api/projects', { signal }), validate: validateProjectCollection, // Projects carry workspace identity (userId) that is only knowable from // the payload itself, so a restored entry cannot be scope-checked before // display. Conservative choice: no last-known restore for this surface; // cross-workspace switching is still invalidated at verification time. }); const retry = (): void => { void projects.revalidate(); }; return (

Projects

{projects.freshness === 'stale' && projects.snapshot ? (
) : null} {projects.freshness === 'unknown' ? (

Loading projects...

) : projects.freshness === 'unavailable' ? ( ) : projects.data !== null && projects.data.length === 0 ? (

No projects yet

Projects will appear here when created via the gateway API

) : (
{(projects.data ?? []).map((project) => ( navigate(`/projects/${selectedProject.id}`)} /> ))}
)}
); }