diff --git a/nextjs/src/hooks/localCourse/assignmentHooks.ts b/nextjs/src/hooks/localCourse/assignmentHooks.ts index 1c650ce..0bb57ec 100644 --- a/nextjs/src/hooks/localCourse/assignmentHooks.ts +++ b/nextjs/src/hooks/localCourse/assignmentHooks.ts @@ -1,5 +1,4 @@ "use client"; -import axios from "axios"; import { localCourseKeys } from "./localCourseKeys"; import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { @@ -10,79 +9,31 @@ import { } from "@tanstack/react-query"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { axiosClient } from "@/services/axiosUtils"; +import { + getAllItemsQueryConfig, + getItemQueryConfig, + useItemQuery, + useItemsQueries, +} from "./courseItemHooks"; export const getAllAssignmentsQueryConfig = ( courseName: string, moduleName: string -) => ({ - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Assignment"), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/assignments"; - const response = await axiosClient.get(url); - return response.data; - }, -}); - -const useAllAssignmentsQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getAllAssignmentsQueryConfig(courseName, moduleName)); -}; +) => getAllItemsQueryConfig(courseName, moduleName, "Assignment"); export const getAssignmentQueryConfig = ( courseName: string, moduleName: string, assignmentName: string -) => { - return { - queryKey: localCourseKeys.itemOfType( - courseName, - moduleName, - assignmentName, - "Assignment" - ), - queryFn: async () => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/assignments/" + - encodeURIComponent(assignmentName); - const response = await axiosClient.get(url); - return response.data; - }, - }; -}; +) => getItemQueryConfig(courseName, moduleName, assignmentName, "Assignment"); export const useAssignmentQuery = ( moduleName: string, assignmentName: string -) => { - const { courseName } = useCourseContext(); +) => useItemQuery(moduleName, assignmentName, "Assignment"); - return useSuspenseQuery( - getAssignmentQueryConfig(courseName, moduleName, assignmentName) - ); -}; - -export const useAssignmentsQueries = (moduleName: string) => { - const { data: allAssignments } = useAllAssignmentsQuery(moduleName); - const { courseName } = useCourseContext(); - return useSuspenseQueries({ - queries: allAssignments.map((assignment) => - getAssignmentQueryConfig(courseName, moduleName, assignment.name) - ), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; +export const useAssignmentsQueries = (moduleName: string) => + useItemsQueries(moduleName, "Assignment"); export const useUpdateAssignmentMutation = () => { const { courseName } = useCourseContext(); @@ -114,7 +65,7 @@ export const useUpdateAssignmentMutation = () => { ), }); queryClient.removeQueries({ - queryKey: localCourseKeys.allItemsOfType( + queryKey: localCourseKeys.allItemsOfType( courseName, previousModuleName, "Assignment" @@ -123,7 +74,7 @@ export const useUpdateAssignmentMutation = () => { } queryClient.setQueryData( - localCourseKeys.itemOfType( + localCourseKeys.itemOfType( courseName, moduleName, assignmentName, @@ -146,7 +97,11 @@ export const useUpdateAssignmentMutation = () => { }, onSuccess: async (_, { moduleName, assignmentName }) => { await queryClient.invalidateQueries({ - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Assignment"), + queryKey: localCourseKeys.allItemsOfType( + courseName, + moduleName, + "Assignment" + ), }); await queryClient.invalidateQueries({ queryKey: localCourseKeys.itemOfType( @@ -193,7 +148,11 @@ export const useCreateAssignmentMutation = () => { }, onSuccess: async (_, { moduleName, assignmentName }) => { await queryClient.invalidateQueries({ - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Assignment"), + queryKey: localCourseKeys.allItemsOfType( + courseName, + moduleName, + "Assignment" + ), }); await queryClient.invalidateQueries({ queryKey: localCourseKeys.itemOfType( @@ -227,7 +186,11 @@ export const useDeleteAssignmentMutation = () => { ), }); queryClient.removeQueries({ - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Assignment"), + queryKey: localCourseKeys.allItemsOfType( + courseName, + moduleName, + "Assignment" + ), }); const url = "/api/courses/" + @@ -240,7 +203,11 @@ export const useDeleteAssignmentMutation = () => { }, onSuccess: async (_, { moduleName, assignmentName }) => { queryClient.invalidateQueries({ - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Assignment"), + queryKey: localCourseKeys.allItemsOfType( + courseName, + moduleName, + "Assignment" + ), }); }, }); diff --git a/nextjs/src/hooks/localCourse/courseItemHooks.ts b/nextjs/src/hooks/localCourse/courseItemHooks.ts new file mode 100644 index 0000000..a78cf62 --- /dev/null +++ b/nextjs/src/hooks/localCourse/courseItemHooks.ts @@ -0,0 +1,89 @@ +import { axiosClient } from "@/services/axiosUtils"; +import { localCourseKeys } from "./localCourseKeys"; +import { + CourseItemReturnType, + CourseItemType, + typeToFolder, +} from "@/models/local/courseItemTypes"; +import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; +import { useSuspenseQueries, useSuspenseQuery } from "@tanstack/react-query"; + +export const getAllItemsQueryConfig = ( + courseName: string, + moduleName: string, + type: T +) => ({ + queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type), + queryFn: async (): Promise[]> => { + const url = + "/api/courses/" + + encodeURIComponent(courseName) + + "/modules/" + + encodeURIComponent(moduleName) + + "/" + + typeToFolder[type]; + const response = await axiosClient.get(url); + return response.data; + }, +}); + +export const getItemQueryConfig = ( + courseName: string, + moduleName: string, + name: string, + type: T +) => { + return { + queryKey: localCourseKeys.itemOfType(courseName, moduleName, name, type), + queryFn: async () => { + const url = + "/api/courses/" + + encodeURIComponent(courseName) + + "/modules/" + + encodeURIComponent(moduleName) + + "/" + + typeToFolder[type] + + "/" + + encodeURIComponent(name); + const response = await axiosClient.get>(url); + return response.data; + }, + }; +}; + +export const useItemQuery = ( + moduleName: string, + name: string, + type: T +) => { + const { courseName } = useCourseContext(); + return useSuspenseQuery( + getItemQueryConfig(courseName, moduleName, name, type) + ); +}; + +const useAllItemsQuery = ( + moduleName: string, + type: T +) => { + const { courseName } = useCourseContext(); + return useSuspenseQuery(getAllItemsQueryConfig(courseName, moduleName, type)); +}; + +export const useItemsQueries = ( + moduleName: string, + type: T +) => { + const { data: allItems } = useAllItemsQuery(moduleName, type); + const { courseName } = useCourseContext(); + return useSuspenseQueries({ + queries: allItems.map((item) => ({ + ...getItemQueryConfig(courseName, moduleName, item.name, type), + queryFn: () => item, + })), + combine: (results) => ({ + data: results.map((r) => r.data), + pending: results.some((r) => r.isPending), + }), + }); +}; diff --git a/nextjs/src/hooks/localCourse/pageHooks.ts b/nextjs/src/hooks/localCourse/pageHooks.ts index 3e29572..929d614 100644 --- a/nextjs/src/hooks/localCourse/pageHooks.ts +++ b/nextjs/src/hooks/localCourse/pageHooks.ts @@ -3,27 +3,19 @@ import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { useMutation, useQueryClient, - useSuspenseQueries, - useSuspenseQuery, } from "@tanstack/react-query"; import { localCourseKeys } from "./localCourseKeys"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { axiosClient } from "@/services/axiosUtils"; +import { + getAllItemsQueryConfig, + getItemQueryConfig, + useItemQuery, + useItemsQueries, +} from "./courseItemHooks"; export function getAllPagesQueryConfig(courseName: string, moduleName: string) { - return { - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Page"), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/pages"; - const response = await axiosClient.get(url); - return response.data; - }, - }; + return getAllItemsQueryConfig(courseName, moduleName, "Page"); } export function getPageQueryConfig( @@ -31,51 +23,14 @@ export function getPageQueryConfig( moduleName: string, pageName: string ) { - return { - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/pages/" + - encodeURIComponent(pageName); - try { - const response = await axiosClient.get(url); - return response.data; - } catch (e) { - console.log("error getting page", e, url); - throw e; - } - }, - }; + return getItemQueryConfig(courseName, moduleName, pageName, "Page"); } -export const usePageQuery = (moduleName: string, pageName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getPageQueryConfig(courseName, moduleName, pageName)); -}; +export const usePageQuery = (moduleName: string, pageName: string) => + useItemQuery(moduleName, pageName, "Page"); -const useAllPagesQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getAllPagesQueryConfig(courseName, moduleName)); -}; - -export const usePagesQueries = (moduleName: string) => { - const { courseName } = useCourseContext(); - const { data: allPages } = useAllPagesQuery(moduleName); - return useSuspenseQueries({ - queries: allPages.map((page) => ({ - ...getPageQueryConfig(courseName, moduleName, page.name), - queryFn: () => page, - })), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; +export const usePagesQueries = (moduleName: string) => + useItemsQueries(moduleName, "Page"); export const useUpdatePageMutation = () => { const { courseName } = useCourseContext(); @@ -108,7 +63,12 @@ export const useUpdatePageMutation = () => { ), }); queryClient.removeQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); } queryClient.setQueryData( @@ -130,10 +90,20 @@ export const useUpdatePageMutation = () => { }, onSuccess: async (_, { moduleName, pageName }) => { await queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); await queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); }, }); @@ -167,10 +137,20 @@ export const useCreatePageMutation = () => { }, onSuccess: (_, { moduleName, pageName }) => { queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); }, }); @@ -188,10 +168,20 @@ export const useDeletePageMutation = () => { pageName: string; }) => { queryClient.removeQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); queryClient.removeQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); const url = "/api/courses/" + @@ -204,10 +194,20 @@ export const useDeletePageMutation = () => { }, onSuccess: async (_, { moduleName, pageName }) => { await queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); await queryClient.invalidateQueries({ - queryKey: localCourseKeys.itemOfType(courseName, moduleName, pageName, "Page"), + queryKey: localCourseKeys.itemOfType( + courseName, + moduleName, + pageName, + "Page" + ), }); }, }); diff --git a/nextjs/src/hooks/localCourse/quizHooks.ts b/nextjs/src/hooks/localCourse/quizHooks.ts index bee99af..f7abbe2 100644 --- a/nextjs/src/hooks/localCourse/quizHooks.ts +++ b/nextjs/src/hooks/localCourse/quizHooks.ts @@ -3,82 +3,38 @@ import { LocalQuiz } from "@/models/local/quiz/localQuiz"; import { useMutation, useQueryClient, - useSuspenseQueries, - useSuspenseQuery, } from "@tanstack/react-query"; import { localCourseKeys } from "./localCourseKeys"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { axiosClient } from "@/services/axiosUtils"; +import { + getAllItemsQueryConfig, + getItemQueryConfig, + useItemQuery, + useItemsQueries, +} from "./courseItemHooks"; export function getAllQuizzesQueryConfig( courseName: string, moduleName: string ) { - return { - queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Quiz"), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/quizzes"; - const response = await axiosClient.get(url); - return response.data; - }, - }; + return getAllItemsQueryConfig(courseName, moduleName, "Quiz"); } -export const useQuizQuery = (moduleName: string, quizName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getQuizQueryConfig(courseName, moduleName, quizName)); -}; - -const useAllQuizzesQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getAllQuizzesQueryConfig(courseName, moduleName)); -}; -export const useQuizzesQueries = (moduleName: string) => { - const { courseName } = useCourseContext(); - const { data: allQuizzes } = useAllQuizzesQuery(moduleName); - return useSuspenseQueries({ - queries: allQuizzes.map((quiz) => ({ - ...getQuizQueryConfig(courseName, moduleName, quiz.name), - queryFn: () => quiz, - })), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; - export function getQuizQueryConfig( courseName: string, moduleName: string, quizName: string ) { - return { - queryKey: localCourseKeys.itemOfType( - courseName, - moduleName, - quizName, - "Quiz" - ), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/quizzes/" + - encodeURIComponent(quizName); - const response = await axiosClient.get(url); - return response.data; - }, - }; + return getItemQueryConfig(courseName, moduleName, quizName, "Quiz"); } +export const useQuizQuery = (moduleName: string, quizName: string) => + useItemQuery(moduleName, quizName, "Quiz"); + +export const useQuizzesQueries = (moduleName: string) => + useItemsQueries(moduleName, "Quiz"); + export const useUpdateQuizMutation = () => { const { courseName } = useCourseContext(); const queryClient = useQueryClient();