diff --git a/packages/dashboard/src/components/dashboard/project/_use-project-data.ts b/packages/dashboard/src/components/dashboard/project/_use-project-data.ts index db20247..4eadad2 100644 --- a/packages/dashboard/src/components/dashboard/project/_use-project-data.ts +++ b/packages/dashboard/src/components/dashboard/project/_use-project-data.ts @@ -22,8 +22,8 @@ interface UseProjectDataResult { export function useProjectData(slug: string | null): UseProjectDataResult { const [project, setProject] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); + const [loading, setLoading] = useState(() => Boolean(slug)); + const [error, setError] = useState(() => (slug ? null : "not-found")); const [conversations, setConversations] = useState([]); const [convsLoading, setConvsLoading] = useState(false); @@ -37,7 +37,13 @@ export function useProjectData(slug: string | null): UseProjectDataResult { // stale response from a previous slug overwriting the current project's // data on rapid navigation, and avoids setState after unmount (#318). const load = useCallback(() => { - if (!slug) return () => {}; + if (!slug) { + setProject(null); + setConversations([]); + setLoading(false); + setError("not-found"); + return () => {}; + } setLoading(true); setError(null); let active = true; diff --git a/packages/dashboard/src/components/dashboard/project/project-content.tsx b/packages/dashboard/src/components/dashboard/project/project-content.tsx index 77e80f7..5f88f17 100644 --- a/packages/dashboard/src/components/dashboard/project/project-content.tsx +++ b/packages/dashboard/src/components/dashboard/project/project-content.tsx @@ -110,7 +110,9 @@ function ProjectContent() { conversations, ); - // Early returns after all hooks + // Early returns after all hooks. Missing `?slug=` is a not-found, not a + // load — otherwise loading stays true and this page spins forever (#407). + if (!slug) return <_ProjectErrorState kind="not-found" onRetry={retry} />; if (loading) return <_ProjectLoadingState />; if (!project) return <_ProjectErrorState kind={error} onRetry={retry} />;