File size: 1,745 Bytes
c9a1ce7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import { useCallback, useEffect, useState } from "react";
import type { ReactNode } from "react";
import { fetchProjects } from "./api";
import {
  DEFAULT_PROJECT_ID,
  PROJECT_STORAGE_KEY,
  ProjectContext,
  readStoredProject,
} from "./project";
import type { ProjectContextValue } from "./project";
import type { Project } from "./types";

// Fetches the project list once at mount and holds the open project in context. The open project is
// seeded from localStorage (default "endometrial") so a reload keeps it; switching persists the choice.
export function ProjectProvider({ children }: { children: ReactNode }) {
  const [projectId, setProjectIdState] = useState<string>(readStoredProject);
  const [projects, setProjects] = useState<Project[]>([]);
  const [defaultProject, setDefaultProject] = useState<string>(DEFAULT_PROJECT_ID);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const setProjectId = useCallback((id: string) => {
    localStorage.setItem(PROJECT_STORAGE_KEY, id);
    setProjectIdState(id);
  }, []);

  const refresh = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await fetchProjects();
      setProjects(data.projects);
      setDefaultProject(data.default);
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  const value: ProjectContextValue = {
    projectId,
    setProjectId,
    projects,
    defaultProject,
    loading,
    error,
    refresh,
  };

  return <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>;
}