Initial commit
This commit is contained in:
27
lib/hooks/use-kanban.ts
Normal file
27
lib/hooks/use-kanban.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { projectsApi } from '@/lib/api/projects';
|
||||
import type { KanbanBoard } from '@/types/kanban';
|
||||
import { api } from '@/lib/api/client';
|
||||
|
||||
export function useKanbanBoard(projectId: string) {
|
||||
return useQuery<KanbanBoard>({
|
||||
queryKey: ['projects', projectId, 'kanban'],
|
||||
queryFn: () => projectsApi.getKanban(projectId),
|
||||
enabled: !!projectId,
|
||||
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateTaskStatus() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ taskId, newStatus }: { taskId: string; newStatus: string }) =>
|
||||
api.patch(`/tasks/${taskId}/status`, { status: newStatus }),
|
||||
onSuccess: (_, { taskId }) => {
|
||||
// Invalidate kanban board queries to refetch
|
||||
queryClient.invalidateQueries({ queryKey: ['kanban'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['tasks', taskId] });
|
||||
},
|
||||
});
|
||||
}
|
||||
79
lib/hooks/use-projects.ts
Normal file
79
lib/hooks/use-projects.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { projectsApi } from '@/lib/api/projects';
|
||||
import type { Project, CreateProjectDto, UpdateProjectDto } from '@/types/project';
|
||||
|
||||
export function useProjects(page = 1, pageSize = 20) {
|
||||
return useQuery<Project[]>({
|
||||
queryKey: ['projects', page, pageSize],
|
||||
queryFn: () => projectsApi.getAll(page, pageSize),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
}
|
||||
|
||||
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] });
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user