const API_BASE_URL = '/api' export interface Project { id: number project_name: string project_desc: string | null created_at: string | null } export interface ProjectCreateRequest { project_name: string project_desc?: string } export interface ProjectUpdateRequest { project_name?: string project_desc?: string } class ProjectService { /** * Get all projects the current user is a member of. */ async getMyProjects(): Promise { try { const response = await fetch(`${API_BASE_URL}/projects`, { method: 'GET', credentials: 'include', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const projects: Project[] = await response.json() return projects } catch (error) { console.error('Failed to fetch projects:', error) throw error } } /** * Get a specific project by ID. */ async getProject(projectId: number): Promise { try { const response = await fetch(`${API_BASE_URL}/projects/${projectId}`, { method: 'GET', credentials: 'include', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const project: Project = await response.json() return project } catch (error) { console.error('Failed to fetch project:', error) throw error } } /** * Create a new project. */ async createProject(data: ProjectCreateRequest): Promise { try { const response = await fetch(`${API_BASE_URL}/projects`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const project: Project = await response.json() return project } catch (error) { console.error('Failed to create project:', error) throw error } } /** * Update an existing project. */ async updateProject(projectId: number, data: ProjectUpdateRequest): Promise { try { const response = await fetch(`${API_BASE_URL}/projects/${projectId}`, { method: 'PUT', credentials: 'include', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const project: Project = await response.json() return project } catch (error) { console.error('Failed to update project:', error) throw error } } /** * Delete a project. */ async deleteProject(projectId: number): Promise { try { const response = await fetch(`${API_BASE_URL}/projects/${projectId}`, { method: 'DELETE', credentials: 'include', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } } catch (error) { console.error('Failed to delete project:', error) throw error } } /** * Add a member to a project. */ async addMember(projectId: number, userId: number): Promise { try { const response = await fetch(`${API_BASE_URL}/projects/${projectId}/members`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userId }), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } } catch (error) { console.error('Failed to add member:', error) throw error } } /** * Remove a member from a project. */ async removeMember(projectId: number, userId: number): Promise { try { const response = await fetch(`${API_BASE_URL}/projects/${projectId}/members/${userId}`, { method: 'DELETE', credentials: 'include', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } } catch (error) { console.error('Failed to remove member:', error) throw error } } } export const projectService = new ProjectService()