// Path: Frontend/src/components/app-shell/data/app-shell.context.tsx import { createContext, createMemo, createSignal, onMount, useContext, type JSX, } from "solid-js"; import { resolveAPIBase } from "../../../lib/api"; import { buildActiveDepartment, buildActiveProject, buildActiveServer, buildActiveUserProfile, buildDepartmentItems, buildProjectItems, buildRailItems, buildWorkspaceTree, } from "./app-shell.builders"; import type { AppShellContextValue, AppShellPayload } from "./app-shell.types"; import { normalizeAppShellPayload } from "./app-shell.types"; const AppShellContext = createContext(); export const AppShellDataProvider = (props: { children: JSX.Element }): JSX.Element => { const [status, setStatus] = createSignal<"idle" | "loading" | "success" | "error">("idle"); const [error, setError] = createSignal(""); const [payload, setPayload] = createSignal(null); const load = async (): Promise => { setStatus("loading"); setError(""); try { const response = await fetch(`${resolveAPIBase()}/app-shell`, { headers: { Accept: "application/json", }, }); const body = (await response.json()) as { data?: AppShellPayload; error?: { message?: string } | string; message?: string; }; const errorMessage = typeof body.message === "string" ? body.message : typeof body.error === "string" ? body.error : body.error?.message; if (!response.ok || !body.data) { throw new Error(errorMessage || "Failed to load app shell state."); } setPayload(normalizeAppShellPayload(body.data)); setStatus("success"); } catch (loadError) { setStatus("error"); setError(loadError instanceof Error ? loadError.message : "Failed to load app shell state."); } }; onMount(() => { void load(); }); const value: AppShellContextValue = { status, error, installation: createMemo(() => payload()?.installation), railItems: createMemo(() => buildRailItems(payload())), activeServer: createMemo(() => buildActiveServer(payload())), activeProject: createMemo(() => buildActiveProject(payload())), activeDepartment: createMemo(() => buildActiveDepartment(payload())), projectItems: createMemo(() => buildProjectItems(payload())), departmentItems: createMemo(() => buildDepartmentItems(payload())), workspaceTree: createMemo(() => buildWorkspaceTree(payload())), activeUserProfile: createMemo(() => buildActiveUserProfile(payload())), reload: load, }; return {props.children}; }; export const useAppShellData = (): AppShellContextValue => { const context = useContext(AppShellContext); if (!context) { throw new Error("useAppShellData must be used within AppShellDataProvider"); } return context; };