life-manager/codebase/features/projects/frontend/useProjects.ts
Claude Code 3deeccbd93 feat(projects-scope): Add research pages, backend entities, custom hooks, and routine integration
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-03-17 17:51:07 -07:00

214 lines
5.8 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/lib/api';
import type {
Sprint,
ContentCalendarItem,
ContentBatch,
Outfit,
CreateSprintDto,
UpdateSprintDto,
CreateContentDto,
UpdateContentDto,
CreateContentBatchDto,
UpdateContentBatchDto,
CreateOutfitDto,
UpdateOutfitDto,
SprintFilters,
ContentFilters,
ContentBatchFilters,
OutfitFilters,
PaginatedResponse,
} from '@life-platform/shared';
export function useSprints(params?: SprintFilters) {
return useQuery({
queryKey: ['projects', 'sprints', params],
queryFn: () =>
apiClient
.get<PaginatedResponse<Sprint>>('/projects/sprints', { params })
.then((r) => r.data),
});
}
export function useSprint(id: string) {
return useQuery({
queryKey: ['projects', 'sprints', id],
queryFn: () =>
apiClient.get<Sprint>(`/projects/sprints/${id}`).then((r) => r.data),
enabled: !!id,
});
}
export function useCreateSprint() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: CreateSprintDto) =>
apiClient.post<Sprint>('/projects/sprints', data).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'sprints'] });
},
});
}
export function useUpdateSprint() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateSprintDto }) =>
apiClient.patch<Sprint>(`/projects/sprints/${id}`, data).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'sprints'] });
},
});
}
export function useDeleteSprint() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) =>
apiClient.delete(`/projects/sprints/${id}`).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'sprints'] });
},
});
}
export function useContentCalendar(params?: ContentFilters) {
return useQuery({
queryKey: ['projects', 'content', params],
queryFn: () =>
apiClient
.get<PaginatedResponse<ContentCalendarItem>>('/projects/content', { params })
.then((r) => r.data),
});
}
export function useCreateContent() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: CreateContentDto) =>
apiClient
.post<ContentCalendarItem>('/projects/content', data)
.then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content'] });
},
});
}
export function useUpdateContent() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateContentDto }) =>
apiClient
.patch<ContentCalendarItem>(`/projects/content/${id}`, data)
.then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content'] });
},
});
}
export function useDeleteContent() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) =>
apiClient.delete(`/projects/content/${id}`).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content'] });
},
});
}
// --- Content Batches ---
export function useContentBatches(params?: ContentBatchFilters) {
return useQuery({
queryKey: ['projects', 'content-batches', params],
queryFn: () =>
apiClient
.get<PaginatedResponse<ContentBatch>>('/projects/content-batches', { params })
.then((r) => r.data),
});
}
export function useCreateBatch() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: CreateContentBatchDto) =>
apiClient
.post<ContentBatch>('/projects/content-batches', data)
.then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content-batches'] });
},
});
}
export function useUpdateBatch() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateContentBatchDto }) =>
apiClient
.patch<ContentBatch>(`/projects/content-batches/${id}`, data)
.then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content-batches'] });
},
});
}
export function useDeleteBatch() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) =>
apiClient.delete(`/projects/content-batches/${id}`).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'content-batches'] });
},
});
}
// --- Outfits ---
export function useOutfits(params?: OutfitFilters) {
return useQuery({
queryKey: ['projects', 'outfits', params],
queryFn: () =>
apiClient
.get<PaginatedResponse<Outfit>>('/projects/outfits', { params })
.then((r) => r.data),
});
}
export function useCreateOutfit() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: CreateOutfitDto) =>
apiClient.post<Outfit>('/projects/outfits', data).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'outfits'] });
},
});
}
export function useUpdateOutfit() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: UpdateOutfitDto }) =>
apiClient.patch<Outfit>(`/projects/outfits/${id}`, data).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'outfits'] });
},
});
}
export function useDeleteOutfit() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) =>
apiClient.delete(`/projects/outfits/${id}`).then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['projects', 'outfits'] });
},
});
}