Files
ColaFlow-Web/lib/hooks/use-projects.ts
Yaojia Wang bb3a93bfdc refactor(frontend): Replace console.log with logger utility - Sprint 3 Story 1
Replace all console.log/warn/error statements with unified logger utility.

Changes:
- Replaced console in lib/hooks/use-stories.ts
- Replaced console in lib/signalr/SignalRContext.tsx
- Replaced console in lib/hooks/useProjectHub.ts
- Replaced console in lib/hooks/use-tasks.ts
- Replaced console in lib/hooks/useNotificationHub.ts
- Replaced console in lib/hooks/use-projects.ts
- Replaced console in app/(dashboard)/projects/[id]/kanban/page.tsx

Logger respects NODE_ENV (debug disabled in production).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 19:47:33 +01:00

92 lines
2.8 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { projectsApi } from '@/lib/api/projects';
import type { Project, CreateProjectDto, UpdateProjectDto } from '@/types/project';
import { logger } from '@/lib/utils/logger';
export function useProjects(page = 1, pageSize = 20) {
return useQuery<Project[]>({
queryKey: ['projects', page, pageSize],
queryFn: async () => {
logger.debug('[useProjects] Fetching projects...', { page, pageSize });
try {
const result = await projectsApi.getAll(page, pageSize);
logger.debug('[useProjects] Fetch successful:', result);
return result;
} catch (error) {
logger.error('[useProjects] Fetch failed:', error);
throw error;
}
},
staleTime: 5 * 60 * 1000, // 5 minutes
retry: 1, // Only retry once to fail faster
});
}
export function useProject(id: string) {
return useQuery<Project>({
queryKey: ['projects', id],
queryFn: () => projectsApi.getById(id),
enabled: !!id,
});
}
export function useCreateProject() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateProjectDto) => projectsApi.create(data),
onSuccess: (newProject) => {
// Invalidate and refetch projects list
queryClient.invalidateQueries({ queryKey: ['projects'] });
// Optimistically update cache
queryClient.setQueryData<Project[]>(['projects'], (old) =>
old ? [...old, newProject] : [newProject]
);
},
});
}
export function useUpdateProject(id: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: UpdateProjectDto) => projectsApi.update(id, data),
onMutate: async (updatedData) => {
// Optimistic update
await queryClient.cancelQueries({ queryKey: ['projects', id] });
const previousProject = queryClient.getQueryData<Project>(['projects', id]);
queryClient.setQueryData<Project>(['projects', id], (old) => ({
...old!,
...updatedData,
}));
return { previousProject };
},
onError: (err, variables, context) => {
// Rollback on error
if (context?.previousProject) {
queryClient.setQueryData(['projects', id], context.previousProject);
}
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['projects', id] });
queryClient.invalidateQueries({ queryKey: ['projects'] });
},
});
}
export function useDeleteProject() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => projectsApi.delete(id),
onSuccess: (_, id) => {
queryClient.invalidateQueries({ queryKey: ['projects'] });
queryClient.removeQueries({ queryKey: ['projects', id] });
},
});
}