import type {Project} from '@plunk/db'; import {createContext, type ReactNode, useContext, useEffect, useState} from 'react'; import {useSWRConfig} from 'swr'; import {useProjects} from '../hooks/useProject'; interface ActiveProjectContextValue { activeProject: Project | null; setActiveProject: (project: Project) => void; updateActiveProject: (project: Project) => void; availableProjects: Project[]; isLoading: boolean; } const ActiveProjectContext = createContext(undefined); export function ActiveProjectProvider({children}: {children: ReactNode}) { const {data: projects, isLoading} = useProjects(); const {mutate} = useSWRConfig(); // State is null until projects load, but localStorage is read synchronously by network.ts // This ensures consistent behavior: either all calls use stored ID, or all fall back to projects[0] const [activeProject, setActiveProjectState] = useState(null); // Initialize active project from localStorage or use first project useEffect(() => { if (!projects || projects.length === 0) return; const storedProjectId = localStorage.getItem('activeProjectId'); if (storedProjectId) { // Find the stored project in available projects const project = projects.find(p => p.id === storedProjectId); if (project) { // eslint-disable-next-line react-hooks/set-state-in-effect setActiveProjectState(project); } else if (projects[0]) { // Stored project not found (user might have been removed), use first project setActiveProjectState(projects[0]); localStorage.setItem('activeProjectId', projects[0].id); } } else if (projects[0]) { // No stored project, initialize with first one setActiveProjectState(projects[0]); localStorage.setItem('activeProjectId', projects[0].id); } }, [projects]); const setActiveProject = (project: Project) => { setActiveProjectState(project); localStorage.setItem('activeProjectId', project.id); // Invalidate all SWR cache to refetch data for new project void mutate(() => true, undefined, {revalidate: true}); }; // Updates the active project's data in-place without invalidating the SWR cache. // Use this when saving settings for the current project, not when switching projects. const updateActiveProject = (project: Project) => { setActiveProjectState(project); }; const value: ActiveProjectContextValue = { activeProject, setActiveProject, updateActiveProject, availableProjects: projects ?? [], isLoading, }; return {children}; } export function useActiveProject() { const context = useContext(ActiveProjectContext); if (context === undefined) { throw new Error('useActiveProject must be used within an ActiveProjectProvider'); } return context; }