feat(frontend): Implement Phase 1 - ProjectManagement API Client & Hooks
Add complete API integration for ProjectManagement module: - Epics, Stories, Tasks API clients - React Query hooks for all entities - Updated type definitions to match backend API - API test page for connection verification Changes: - Update lib/api/config.ts: Add all ProjectManagement endpoints - Update types/project.ts: Match backend API models (Epic, Story, Task) - Create lib/api/pm.ts: API clients for Epics, Stories, Tasks - Create lib/hooks/use-epics.ts: React Query hooks for Epic CRUD - Create lib/hooks/use-stories.ts: React Query hooks for Story CRUD - Create lib/hooks/use-tasks.ts: React Query hooks for Task CRUD - Create app/(dashboard)/api-test/page.tsx: API connection test page Features: - Full CRUD operations for Epics, Stories, Tasks - Status change and assignment operations - Optimistic updates for better UX - Error handling with toast notifications - Query invalidation for cache consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
109
lib/api/pm.ts
Normal file
109
lib/api/pm.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { api } from './client';
|
||||
import type {
|
||||
Epic,
|
||||
CreateEpicDto,
|
||||
UpdateEpicDto,
|
||||
Story,
|
||||
CreateStoryDto,
|
||||
UpdateStoryDto,
|
||||
Task,
|
||||
CreateTaskDto,
|
||||
UpdateTaskDto,
|
||||
WorkItemStatus,
|
||||
} from '@/types/project';
|
||||
|
||||
// ==================== Epics API ====================
|
||||
export const epicsApi = {
|
||||
list: async (projectId?: string): Promise<Epic[]> => {
|
||||
const params = projectId ? { projectId } : undefined;
|
||||
return api.get('/api/v1/epics', { params });
|
||||
},
|
||||
|
||||
get: async (id: string): Promise<Epic> => {
|
||||
return api.get(`/api/v1/epics/${id}`);
|
||||
},
|
||||
|
||||
create: async (data: CreateEpicDto): Promise<Epic> => {
|
||||
return api.post('/api/v1/epics', data);
|
||||
},
|
||||
|
||||
update: async (id: string, data: UpdateEpicDto): Promise<Epic> => {
|
||||
return api.put(`/api/v1/epics/${id}`, data);
|
||||
},
|
||||
|
||||
delete: async (id: string): Promise<void> => {
|
||||
return api.delete(`/api/v1/epics/${id}`);
|
||||
},
|
||||
|
||||
changeStatus: async (id: string, status: WorkItemStatus): Promise<Epic> => {
|
||||
return api.put(`/api/v1/epics/${id}/status`, { status });
|
||||
},
|
||||
|
||||
assign: async (id: string, assigneeId: string): Promise<Epic> => {
|
||||
return api.put(`/api/v1/epics/${id}/assign`, { assigneeId });
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== Stories API ====================
|
||||
export const storiesApi = {
|
||||
list: async (epicId?: string): Promise<Story[]> => {
|
||||
const params = epicId ? { epicId } : undefined;
|
||||
return api.get('/api/v1/stories', { params });
|
||||
},
|
||||
|
||||
get: async (id: string): Promise<Story> => {
|
||||
return api.get(`/api/v1/stories/${id}`);
|
||||
},
|
||||
|
||||
create: async (data: CreateStoryDto): Promise<Story> => {
|
||||
return api.post('/api/v1/stories', data);
|
||||
},
|
||||
|
||||
update: async (id: string, data: UpdateStoryDto): Promise<Story> => {
|
||||
return api.put(`/api/v1/stories/${id}`, data);
|
||||
},
|
||||
|
||||
delete: async (id: string): Promise<void> => {
|
||||
return api.delete(`/api/v1/stories/${id}`);
|
||||
},
|
||||
|
||||
changeStatus: async (id: string, status: WorkItemStatus): Promise<Story> => {
|
||||
return api.put(`/api/v1/stories/${id}/status`, { status });
|
||||
},
|
||||
|
||||
assign: async (id: string, assigneeId: string): Promise<Story> => {
|
||||
return api.put(`/api/v1/stories/${id}/assign`, { assigneeId });
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== Tasks API ====================
|
||||
export const tasksApi = {
|
||||
list: async (storyId?: string): Promise<Task[]> => {
|
||||
const params = storyId ? { storyId } : undefined;
|
||||
return api.get('/api/v1/tasks', { params });
|
||||
},
|
||||
|
||||
get: async (id: string): Promise<Task> => {
|
||||
return api.get(`/api/v1/tasks/${id}`);
|
||||
},
|
||||
|
||||
create: async (data: CreateTaskDto): Promise<Task> => {
|
||||
return api.post('/api/v1/tasks', data);
|
||||
},
|
||||
|
||||
update: async (id: string, data: UpdateTaskDto): Promise<Task> => {
|
||||
return api.put(`/api/v1/tasks/${id}`, data);
|
||||
},
|
||||
|
||||
delete: async (id: string): Promise<void> => {
|
||||
return api.delete(`/api/v1/tasks/${id}`);
|
||||
},
|
||||
|
||||
changeStatus: async (id: string, status: WorkItemStatus): Promise<Task> => {
|
||||
return api.put(`/api/v1/tasks/${id}/status`, { status });
|
||||
},
|
||||
|
||||
assign: async (id: string, assigneeId: string): Promise<Task> => {
|
||||
return api.put(`/api/v1/tasks/${id}/assign`, { assigneeId });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user