1st approach for projects, items, db structure

This commit is contained in:
Jurgis Sakalauskas
2025-10-13 14:04:22 +03:00
parent ad2cf25bfd
commit afc3da3e65
45 changed files with 4743 additions and 117 deletions
+100
View File
@@ -0,0 +1,100 @@
import {
createProject,
fetchProject,
fetchProjects,
updateProject,
type CreateProjectPayload,
type Project,
type ProjectsListResponse,
type UpdateProjectPayload
} from '../api/projects';
import {
createItem,
fetchProjectItems,
type CreateItemPayload,
type ProjectItemsResponse
} from '../api/items';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
const DEFAULT_LIMIT = 50;
export const projectsKeys = {
all: ['projects'] as const,
list: () => [...projectsKeys.all, 'list'] as const,
detail: (projectId: string) =>
[...projectsKeys.all, 'detail', projectId] as const,
items: (projectId: string) =>
[...projectsKeys.detail(projectId), 'items'] as const
};
export const useProjectsQuery = () =>
useQuery<ProjectsListResponse>({
queryKey: projectsKeys.list(),
queryFn: ({ signal }) => fetchProjects({ limit: DEFAULT_LIMIT, offset: 0, signal })
});
export const useProjectQuery = (projectId: string | undefined) =>
useQuery<Project>({
queryKey: projectId ? projectsKeys.detail(projectId) : ['project', 'missing'],
enabled: Boolean(projectId),
queryFn: ({ signal }) => fetchProject(projectId!, { signal })
});
export const useProjectItemsQuery = (projectId: string | undefined) =>
useQuery<ProjectItemsResponse>({
queryKey: projectId ? projectsKeys.items(projectId) : ['project', 'items', 'missing'],
enabled: Boolean(projectId),
queryFn: ({ signal }) =>
fetchProjectItems(projectId!, { limit: DEFAULT_LIMIT, offset: 0, signal })
});
export const useCreateProjectMutation = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (payload: CreateProjectPayload) => createProject(payload),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: projectsKeys.list() });
}
});
};
export const useUpdateProjectMutation = (projectId: string | undefined) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (payload: UpdateProjectPayload) => {
if (!projectId) {
throw new Error('projectId is required to update a project');
}
return updateProject(projectId, payload);
},
onSuccess: () => {
if (!projectId) {
return;
}
queryClient.invalidateQueries({ queryKey: projectsKeys.detail(projectId) });
queryClient.invalidateQueries({ queryKey: projectsKeys.list() });
}
});
};
export const useCreateItemMutation = (projectId: string | undefined) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (payload: CreateItemPayload) => {
if (!projectId) {
throw new Error('projectId is required to create an item');
}
return createItem(projectId, payload);
},
onSuccess: () => {
if (!projectId) {
return;
}
queryClient.invalidateQueries({ queryKey: projectsKeys.items(projectId) });
queryClient.invalidateQueries({ queryKey: projectsKeys.detail(projectId) });
}
});
};