File size: 1,331 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
import { useEffect, useState } from "react";
import type { ReactNode } from "react";
import { fetchFields } from "./api";
import { ChecklistFieldsContext, EMPTY_CHECKLIST_FIELDS } from "./checklistFields";
import type { ChecklistFields } from "./checklistFields";

// Fetched once at app mount and held in context: the list is small, static for
// the life of the backend process, and every screen needs it (issue #37).
export function ChecklistFieldsProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<ChecklistFields>(EMPTY_CHECKLIST_FIELDS);

  useEffect(() => {
    let cancelled = false;
    fetchFields()
      .then((fields) => {
        if (cancelled) return;
        setState({
          fields,
          names: fields.map((f) => f.name),
          labels: Object.fromEntries(fields.map((f) => [f.name, f.label])),
          loading: false,
          error: null,
        });
      })
      .catch((err) => {
        if (cancelled) return;
        setState({
          ...EMPTY_CHECKLIST_FIELDS,
          loading: false,
          error: err instanceof Error ? err.message : String(err),
        });
      });
    return () => {
      cancelled = true;
    };
  }, []);

  return (
    <ChecklistFieldsContext.Provider value={state}>{children}</ChecklistFieldsContext.Provider>
  );
}