150 lines
4.5 KiB
TypeScript
150 lines
4.5 KiB
TypeScript
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import type { UseQueryResult, UseMutationResult } from '@tanstack/react-query';
|
|
import { apiClient } from '@/lib/api';
|
|
import type { PaginatedResponse } from '@life-manager/shared';
|
|
import type {
|
|
LearningPath, Lesson, LessonProgress, ReviewLog,
|
|
LearningDueResponse, LearningPathStats,
|
|
CreateLearningPathDto, UpdateLearningPathDto,
|
|
RecordReviewDto,
|
|
LearningPathFilters, LessonFilters,
|
|
} from '@life-manager/shared';
|
|
|
|
export function useLearningPaths(
|
|
params?: LearningPathFilters,
|
|
): UseQueryResult<PaginatedResponse<LearningPath>> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'paths', params],
|
|
queryFn: () =>
|
|
apiClient
|
|
.get<PaginatedResponse<LearningPath>>('/learning/paths', { params })
|
|
.then((r) => r.data),
|
|
});
|
|
}
|
|
|
|
export function useLearningPath(id: string): UseQueryResult<LearningPath> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'paths', id],
|
|
queryFn: () =>
|
|
apiClient.get<LearningPath>(`/learning/paths/${id}`).then((r) => r.data),
|
|
enabled: !!id,
|
|
});
|
|
}
|
|
|
|
export function useLearningPathStats(id: string): UseQueryResult<LearningPathStats> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'paths', id, 'stats'],
|
|
queryFn: () =>
|
|
apiClient.get<LearningPathStats>(`/learning/paths/${id}/stats`).then((r) => r.data),
|
|
enabled: !!id,
|
|
});
|
|
}
|
|
|
|
export function useAllPathStats(): UseQueryResult<LearningPathStats[]> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'stats'],
|
|
queryFn: () =>
|
|
apiClient.get<LearningPathStats[]>('/learning/stats').then((r) => r.data),
|
|
});
|
|
}
|
|
|
|
export function useLearningDue(limit?: number): UseQueryResult<LearningDueResponse> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'due', limit],
|
|
queryFn: () =>
|
|
apiClient
|
|
.get<LearningDueResponse>('/learning/due', { params: limit ? { limit } : undefined })
|
|
.then((r) => r.data),
|
|
refetchInterval: 60_000,
|
|
});
|
|
}
|
|
|
|
export function usePathLessons(
|
|
pathId: string,
|
|
params?: LessonFilters,
|
|
): UseQueryResult<PaginatedResponse<Lesson>> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'paths', pathId, 'lessons', params],
|
|
queryFn: () =>
|
|
apiClient
|
|
.get<PaginatedResponse<Lesson>>(`/learning/paths/${pathId}/lessons`, { params })
|
|
.then((r) => r.data),
|
|
enabled: !!pathId,
|
|
});
|
|
}
|
|
|
|
export function useLesson(id: string): UseQueryResult<Lesson> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'lessons', id],
|
|
queryFn: () =>
|
|
apiClient.get<Lesson>(`/learning/lessons/${id}`).then((r) => r.data),
|
|
enabled: !!id,
|
|
});
|
|
}
|
|
|
|
export function useCreateLearningPath(): UseMutationResult<
|
|
LearningPath,
|
|
Error,
|
|
CreateLearningPathDto
|
|
> {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (data: CreateLearningPathDto) =>
|
|
apiClient.post<LearningPath>('/learning/paths', data).then((r) => r.data),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ['learning'] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useUpdateLearningPath(): UseMutationResult<
|
|
LearningPath,
|
|
Error,
|
|
{ id: string; data: UpdateLearningPathDto }
|
|
> {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: ({ id, data }: { id: string; data: UpdateLearningPathDto }) =>
|
|
apiClient.patch<LearningPath>(`/learning/paths/${id}`, data).then((r) => r.data),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ['learning'] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useDeleteLearningPath(): UseMutationResult<unknown, Error, string> {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiClient.delete(`/learning/paths/${id}`).then((r) => r.data),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ['learning'] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useRecordReview(): UseMutationResult<
|
|
LessonProgress,
|
|
Error,
|
|
{ lessonId: string; data: RecordReviewDto }
|
|
> {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: ({ lessonId, data }: { lessonId: string; data: RecordReviewDto }) =>
|
|
apiClient
|
|
.post<LessonProgress>(`/learning/lessons/${lessonId}/review`, data)
|
|
.then((r) => r.data),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ['learning'] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useReviewHistory(lessonId: string): UseQueryResult<ReviewLog[]> {
|
|
return useQuery({
|
|
queryKey: ['learning', 'lessons', lessonId, 'reviews'],
|
|
queryFn: () =>
|
|
apiClient.get<ReviewLog[]>(`/learning/lessons/${lessonId}/reviews`).then((r) => r.data),
|
|
enabled: !!lessonId,
|
|
});
|
|
}
|