"use client"; import React, { createContext, useCallback, useContext, useEffect, useState } from "react"; import { useSession } from "next-auth/react"; import { config, NETWORK_NAME, setMapWorkspace, setNetworkName, setMapExtent } from "@/config/config"; import { ProjectSelector } from "@/components/project/ProjectSelector"; import { apiFetch } from "@/lib/apiFetch"; import { useProjectStore } from "@/store/projectStore"; interface ProjectContextType { workspace: string; networkName: string; extent: number[]; } const ProjectContext = createContext(undefined); export const ProjectProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const { status } = useSession(); const [isConfigured, setIsConfigured] = useState(false); const setCurrentProjectId = useProjectStore( (state) => state.setCurrentProjectId, ); const [currentProject, setCurrentProject] = useState({ workspace: config.MAP_WORKSPACE, networkName: NETWORK_NAME || "tjwater", extent: config.MAP_EXTENT, }); const applyConfig = useCallback(async ( projectId: string, ws: string, net: string, extent: number[], ) => { const resolvedProjectId = projectId || net || ws; setMapWorkspace(ws); setNetworkName(net); setMapExtent(extent); localStorage.setItem("NEXT_PUBLIC_MAP_EXTENT", extent.join(",")); // Reset extent cache localStorage.removeItem(`${ws}_map_view`); setCurrentProject({ workspace: ws, networkName: net, extent: extent }); setCurrentProjectId(resolvedProjectId); // Save to localStorage localStorage.setItem("NEXT_PUBLIC_MAP_WORKSPACE", ws); localStorage.setItem("NEXT_PUBLIC_NETWORK_NAME", net); setIsConfigured(true); try { const response = await apiFetch( `${config.BACKEND_URL}/openproject/?network=${net}`, { method: "POST", }, ); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json(); const bbox = Array.isArray(data?.map_extent?.bbox) ? data.map_extent.bbox.map((value: number) => Number(value)) : null; if (bbox && bbox.length === 4) { setMapExtent(bbox); localStorage.setItem("NEXT_PUBLIC_MAP_EXTENT", bbox.join(",")); localStorage.removeItem(`${ws}_map_view`); setCurrentProject((prev) => ({ ...prev, extent: bbox })); } } catch (error) { console.error("Failed to open project:", error); } }, [setCurrentProjectId]); useEffect(() => { // Check localStorage const savedWorkspace = localStorage.getItem("NEXT_PUBLIC_MAP_WORKSPACE"); const savedNetwork = localStorage.getItem("NEXT_PUBLIC_NETWORK_NAME"); const savedExtent = localStorage.getItem("NEXT_PUBLIC_MAP_EXTENT"); const savedProjectId = localStorage.getItem("active_project"); // If we have saved config, use it. if (savedWorkspace && savedNetwork) { applyConfig( savedProjectId || savedNetwork || savedWorkspace, savedWorkspace, savedNetwork, savedExtent ? savedExtent.split(",").map(Number) : config.MAP_EXTENT, ); } }, [applyConfig]); // Only show selector if authenticated and not configured if (status === "authenticated" && !isConfigured) { return ( applyConfig(projectId, ws, net, extent) } /> ); } return ( {children} ); }; export const useProject = () => useContext(ProjectContext);