import type { ReactNode} from 'react'; import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; import type { MantineColorScheme} from '@mantine/core'; import { useMantineColorScheme } from '@mantine/core'; import { notifications } from '@mantine/notifications'; import { getLastWorkspaceName, getWorkspace, updateWorkspace, updateLastWorkspaceName, deleteWorkspace, listWorkspaces, } from '@/api/workspace'; import type { Workspace} from '@/types/workspace'; import { DEFAULT_WORKSPACE_SETTINGS } from '@/types/workspace'; interface WorkspaceContextType { currentWorkspace: Workspace | null; workspaces: Workspace[]; settings: Workspace | typeof DEFAULT_WORKSPACE_SETTINGS; updateSettings: (newSettings: Partial) => Promise; loading: boolean; colorScheme: MantineColorScheme; updateColorScheme: (newTheme: MantineColorScheme) => void; switchWorkspace: (workspaceName: string) => Promise; deleteCurrentWorkspace: () => Promise; } const WorkspaceContext = createContext(null); interface WorkspaceProviderProps { children: ReactNode; } export const WorkspaceProvider: React.FC = ({ children, }) => { const [currentWorkspace, setCurrentWorkspace] = useState( null ); const [workspaces, setWorkspaces] = useState([]); const [loading, setLoading] = useState(true); const { colorScheme, setColorScheme } = useMantineColorScheme(); const loadWorkspaces = useCallback(async (): Promise => { try { const workspaceList = await listWorkspaces(); setWorkspaces(workspaceList); return workspaceList; } catch (error) { console.error('Failed to load workspaces:', error); notifications.show({ title: 'Error', message: 'Failed to load workspaces list', color: 'red', }); return []; } }, []); const loadWorkspaceData = useCallback( async (workspaceName: string): Promise => { try { const workspace = await getWorkspace(workspaceName); setCurrentWorkspace(workspace); setColorScheme(workspace.theme as MantineColorScheme); } catch (error) { console.error('Failed to load workspace data:', error); notifications.show({ title: 'Error', message: 'Failed to load workspace data', color: 'red', }); } }, [] ); const loadFirstAvailableWorkspace = useCallback(async (): Promise => { try { const allWorkspaces = await listWorkspaces(); if (allWorkspaces.length > 0) { const firstWorkspace = allWorkspaces[0]; if (!firstWorkspace) throw new Error('No workspaces available'); await updateLastWorkspaceName(firstWorkspace.name); await loadWorkspaceData(firstWorkspace.name); } } catch (error) { console.error('Failed to load first available workspace:', error); notifications.show({ title: 'Error', message: 'Failed to load workspace', color: 'red', }); } }, []); useEffect(() => { const initializeWorkspace = async (): Promise => { try { const lastWorkspaceName = await getLastWorkspaceName(); if (lastWorkspaceName) { await loadWorkspaceData(lastWorkspaceName); } else { await loadFirstAvailableWorkspace(); } await loadWorkspaces(); } catch (error) { console.error('Failed to initialize workspace:', error); await loadFirstAvailableWorkspace(); } finally { setLoading(false); } }; initializeWorkspace(); }, []); const switchWorkspace = useCallback( async (workspaceName: string): Promise => { try { setLoading(true); await updateLastWorkspaceName(workspaceName); await loadWorkspaceData(workspaceName); await loadWorkspaces(); } catch (error) { console.error('Failed to switch workspace:', error); notifications.show({ title: 'Error', message: 'Failed to switch workspace', color: 'red', }); } finally { setLoading(false); } }, [] ); const deleteCurrentWorkspace = useCallback(async (): Promise => { if (!currentWorkspace) return; try { const allWorkspaces = await loadWorkspaces(); if (allWorkspaces.length <= 1) { notifications.show({ title: 'Error', message: 'Cannot delete the last workspace. At least one workspace must exist.', color: 'red', }); return; } // Delete workspace and get the next workspace ID const nextWorkspaceName: string = await deleteWorkspace( currentWorkspace.name ); // Load the new workspace data await loadWorkspaceData(nextWorkspaceName); notifications.show({ title: 'Success', message: 'Workspace deleted successfully', color: 'green', }); await loadWorkspaces(); } catch (error) { console.error('Failed to delete workspace:', error); notifications.show({ title: 'Error', message: 'Failed to delete workspace', color: 'red', }); } }, [currentWorkspace]); const updateSettings = useCallback( async (newSettings: Partial): Promise => { if (!currentWorkspace) return; try { const updatedWorkspace = { ...currentWorkspace, ...newSettings, }; const response = await updateWorkspace( currentWorkspace.name, updatedWorkspace ); setCurrentWorkspace(response); setColorScheme(response.theme); await loadWorkspaces(); } catch (error) { console.error('Failed to save settings:', error); throw error; } }, [currentWorkspace, setColorScheme] ); const updateColorScheme = useCallback( (newTheme: MantineColorScheme): void => { setColorScheme(newTheme); }, [setColorScheme] ); const value: WorkspaceContextType = { currentWorkspace, workspaces, settings: currentWorkspace || DEFAULT_WORKSPACE_SETTINGS, updateSettings, loading, colorScheme, updateColorScheme, switchWorkspace, deleteCurrentWorkspace, }; return ( {children} ); }; export const useWorkspace = (): WorkspaceContextType => { const context = useContext(WorkspaceContext); if (!context) { throw new Error('useWorkspace must be used within a WorkspaceProvider'); } return context; };