Added project separation logic
This commit is contained in:
120
frontend/src/context/ProjectContext.tsx
Normal file
120
frontend/src/context/ProjectContext.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import {
|
||||
createContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
type ReactNode,
|
||||
} from 'react'
|
||||
import { projectService, type Project } from '@/services'
|
||||
import { useAuth } from '@/hooks'
|
||||
|
||||
export interface ProjectContextType {
|
||||
projects: Project[]
|
||||
currentProject: Project | null
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
setCurrentProject: (project: Project | null) => void
|
||||
refreshProjects: () => Promise<void>
|
||||
createProject: (name: string, description?: string) => Promise<Project>
|
||||
}
|
||||
|
||||
export const ProjectContext = createContext<ProjectContextType | undefined>(undefined)
|
||||
|
||||
const STORAGE_KEY = 'selectedProjectId'
|
||||
|
||||
interface ProjectProviderProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function ProjectProvider({ children }: ProjectProviderProps) {
|
||||
const { isAuthenticated, isLoading: authLoading } = useAuth()
|
||||
const [projects, setProjects] = useState<Project[]>([])
|
||||
const [currentProject, setCurrentProjectState] = useState<Project | null>(null)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const setCurrentProject = useCallback((project: Project | null) => {
|
||||
setCurrentProjectState(project)
|
||||
if (project) {
|
||||
localStorage.setItem(STORAGE_KEY, project.id.toString())
|
||||
} else {
|
||||
localStorage.removeItem(STORAGE_KEY)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const refreshProjects = useCallback(async () => {
|
||||
if (!isAuthenticated) {
|
||||
setProjects([])
|
||||
setCurrentProjectState(null)
|
||||
setIsLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
const fetchedProjects = await projectService.getMyProjects()
|
||||
setProjects(fetchedProjects)
|
||||
|
||||
// Restore selected project from localStorage or select first available
|
||||
const savedProjectId = localStorage.getItem(STORAGE_KEY)
|
||||
if (savedProjectId) {
|
||||
const savedProject = fetchedProjects.find(
|
||||
(p) => p.id === parseInt(savedProjectId, 10)
|
||||
)
|
||||
if (savedProject) {
|
||||
setCurrentProjectState(savedProject)
|
||||
} else if (fetchedProjects.length > 0) {
|
||||
// Saved project no longer available, select first one
|
||||
setCurrentProject(fetchedProjects[0])
|
||||
}
|
||||
} else if (fetchedProjects.length > 0) {
|
||||
// No saved project, select first one
|
||||
setCurrentProject(fetchedProjects[0])
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch projects:', err)
|
||||
setError('Failed to load projects')
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [isAuthenticated, setCurrentProject])
|
||||
|
||||
const createProject = useCallback(async (name: string, description?: string): Promise<Project> => {
|
||||
const newProject = await projectService.createProject({
|
||||
project_name: name,
|
||||
project_desc: description,
|
||||
})
|
||||
|
||||
// Add to projects list
|
||||
setProjects((prev: Project[]) => [newProject, ...prev])
|
||||
|
||||
// If no current project, set this as current
|
||||
if (!currentProject) {
|
||||
setCurrentProject(newProject)
|
||||
}
|
||||
|
||||
return newProject
|
||||
}, [currentProject, setCurrentProject])
|
||||
|
||||
// Fetch projects when authentication status changes
|
||||
useEffect(() => {
|
||||
if (!authLoading) {
|
||||
refreshProjects()
|
||||
}
|
||||
}, [authLoading, isAuthenticated, refreshProjects])
|
||||
|
||||
const value: ProjectContextType = {
|
||||
projects,
|
||||
currentProject,
|
||||
isLoading,
|
||||
error,
|
||||
setCurrentProject,
|
||||
refreshProjects,
|
||||
createProject,
|
||||
}
|
||||
|
||||
return (
|
||||
<ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user