diff --git a/nextjs/build.sh b/nextjs/build.sh
index c5e2989..d6a3ca2 100755
--- a/nextjs/build.sh
+++ b/nextjs/build.sh
@@ -1,7 +1,7 @@
#!/bin/bash
MAJOR_VERSION="2"
-MINOR_VERSION="1"
+MINOR_VERSION="2"
VERSION="$MAJOR_VERSION.$MINOR_VERSION"
docker build -t canvas_management:$VERSION .
diff --git a/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts b/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts
index 26ca5a2..027284b 100644
--- a/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts
+++ b/nextjs/src/app/course/[courseName]/context/drag/useItemDropOnDay.ts
@@ -18,6 +18,7 @@ import { DraggableItem } from "./draggingContext";
import { getNewLockDate } from "./getNewLockDate";
import { trpc } from "@/services/trpc/utils";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
+import { useCourseContext } from "../courseContext";
export function useItemDropOnDay({
setIsDragging,
@@ -33,6 +34,7 @@ export function useItemDropOnDay({
modal: { isOpen: boolean; openModal: () => void; closeModal: () => void };
}) {
const [settings] = useLocalCourseSettingsQuery();
+ const { courseName } = useCourseContext();
// const { data: weeks } = useLecturesByWeekQuery();
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({
courseName: settings.name,
@@ -95,6 +97,8 @@ export function useItemDropOnDay({
...lecture,
date: getDateOnlyMarkdownString(dayAsDate),
},
+ courseName,
+ settings,
});
setModalText("");
setModalCallback(() => {});
@@ -110,6 +114,8 @@ export function useItemDropOnDay({
...lecture,
date: getDateOnlyMarkdownString(dayAsDate),
},
+ courseName,
+ settings,
});
}
}
diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx
index fba74a7..1c1a746 100644
--- a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx
+++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx
@@ -1,9 +1,7 @@
"use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor";
-import {
- useLectureUpdateMutation,
-} from "@/hooks/localCourse/lectureHooks";
+import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
import {
lectureToString,
parseLecture,
@@ -14,10 +12,11 @@ import EditLectureTitle from "./EditLectureTitle";
import LectureButtons from "./LectureButtons";
import { trpc } from "@/services/trpc/utils";
import { useCourseContext } from "../../context/courseContext";
+import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
export default function EditLecture({ lectureDay }: { lectureDay: string }) {
- // const { data: weeks } = useLecturesByWeekQuery();
const { courseName } = useCourseContext();
+ const [settings] = useLocalCourseSettingsQuery();
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
const updateLecture = useLectureUpdateMutation();
@@ -42,7 +41,7 @@ Date: ${lectureDay}
const parsed = parseLecture(text);
if (!lecture || lectureToString(parsed) !== lectureToString(lecture)) {
console.log("updating lecture");
- updateLecture.mutate({ lecture: parsed });
+ updateLecture.mutate({ lecture: parsed, settings, courseName });
}
setError("");
} catch (e: any) {
diff --git a/nextjs/src/app/course/[courseName]/modules/CreateModule.tsx b/nextjs/src/app/course/[courseName]/modules/CreateModule.tsx
index f738b1d..b9ac7a1 100644
--- a/nextjs/src/app/course/[courseName]/modules/CreateModule.tsx
+++ b/nextjs/src/app/course/[courseName]/modules/CreateModule.tsx
@@ -2,8 +2,10 @@ import { Expandable } from "@/components/Expandable";
import TextInput from "@/components/form/TextInput";
import { useCreateModuleMutation } from "@/hooks/localCourse/localCourseModuleHooks";
import React, { useState } from "react";
+import { useCourseContext } from "../context/courseContext";
export default function CreateModule() {
+ const { courseName } = useCourseContext();
const createModule = useCreateModuleMutation();
const [moduleName, setModuleName] = useState("");
return (
@@ -19,7 +21,7 @@ export default function CreateModule() {
onSubmit={async (e) => {
e.preventDefault();
if (moduleName) {
- await createModule.mutateAsync(moduleName);
+ await createModule.mutateAsync({ moduleName, courseName });
setModuleName("");
}
}}
diff --git a/nextjs/src/app/course/[courseName]/modules/ModuleList.tsx b/nextjs/src/app/course/[courseName]/modules/ModuleList.tsx
index 8bba203..e438ffc 100644
--- a/nextjs/src/app/course/[courseName]/modules/ModuleList.tsx
+++ b/nextjs/src/app/course/[courseName]/modules/ModuleList.tsx
@@ -4,7 +4,7 @@ import ExpandableModule from "./ExpandableModule";
import CreateModule from "./CreateModule";
export default function ModuleList() {
- const { data: moduleNames } = useModuleNamesQuery();
+ const [moduleNames] = useModuleNamesQuery();
return (
{/* {moduleNames.map((m) => (
diff --git a/nextjs/src/app/course/[courseName]/modules/NewItemForm.tsx b/nextjs/src/app/course/[courseName]/modules/NewItemForm.tsx
index 3220d8f..e4628c7 100644
--- a/nextjs/src/app/course/[courseName]/modules/NewItemForm.tsx
+++ b/nextjs/src/app/course/[courseName]/modules/NewItemForm.tsx
@@ -28,7 +28,7 @@ export default function NewItemForm({
}) {
const [settings] = useLocalCourseSettingsQuery();
const { courseName } = useCourseContext();
- const { data: modules } = useModuleNamesQuery();
+ const [modules] = useModuleNamesQuery();
const [type, setType] = useState<"Assignment" | "Quiz" | "Page">(
"Assignment"
);
diff --git a/nextjs/src/app/layout.tsx b/nextjs/src/app/layout.tsx
index 5509364..782c845 100644
--- a/nextjs/src/app/layout.tsx
+++ b/nextjs/src/app/layout.tsx
@@ -56,33 +56,36 @@ async function DataHydration({
},
},
});
- // const allSettings = await fileStorageService.settings.getAllCoursesSettings();
- // await Promise.all(
- // allSettings.map(async (settings) => {
- // const courseName = settings.name;
- // const moduleNames = await fileStorageService.modules.getModuleNames(
- // courseName
- // );
- // await Promise.all(
- // moduleNames.map(
- // async (moduleName) =>
- // await trpcHelper.assignment.getAllAssignments.fetch({
- // courseName,
- // moduleName,
- // })
- // )
- // );
- // })
- // );
- // await Promise.all(
- // allSettings.map(
- // async (settings) =>
- // await trpcHelper.lectures.getLectures.fetch({
- // courseName: settings.name,
- // })
- // )
- // );
+ const allSettings = await fileStorageService.settings.getAllCoursesSettings();
+ // assignments
+ await Promise.all(
+ allSettings.map(async (settings) => {
+ const courseName = settings.name;
+ const moduleNames = await fileStorageService.modules.getModuleNames(
+ courseName
+ );
+ await Promise.all(
+ moduleNames.map(
+ async (moduleName) =>
+ await trpcHelper.assignment.getAllAssignments.fetch({
+ courseName,
+ moduleName,
+ })
+ )
+ );
+ })
+ );
+
+ // lectures
+ await Promise.all(
+ allSettings.map(
+ async (settings) =>
+ await trpcHelper.lectures.getLectures.fetch({
+ courseName: settings.name,
+ })
+ )
+ );
// await hydrateCourses(trpcHelper.queryClient);
diff --git a/nextjs/src/app/providers.tsx b/nextjs/src/app/providers.tsx
index e39a1c6..2ef622e 100644
--- a/nextjs/src/app/providers.tsx
+++ b/nextjs/src/app/providers.tsx
@@ -1,5 +1,5 @@
"use client";
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { QueryClientProvider } from "@tanstack/react-query";
import { ReactNode } from "react";
import { getQueryClient } from "./providersQueryClientUtils";
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
diff --git a/nextjs/src/hooks/localCourse/assignmentHooks.ts b/nextjs/src/hooks/localCourse/assignmentHooks.ts
index 36971b0..5f68633 100644
--- a/nextjs/src/hooks/localCourse/assignmentHooks.ts
+++ b/nextjs/src/hooks/localCourse/assignmentHooks.ts
@@ -48,7 +48,7 @@ export const useUpdateAssignmentMutation = () => {
export const useCreateAssignmentMutation = () => {
const utils = trpc.useUtils();
return trpc.assignment.createAssignment.useMutation({
- onSuccess: (_, { courseName, moduleName, assignmentName }) => {
+ onSuccess: (_, { courseName, moduleName }) => {
utils.assignment.getAllAssignments.invalidate({ courseName, moduleName });
},
});
diff --git a/nextjs/src/hooks/localCourse/courseItemHooks.ts b/nextjs/src/hooks/localCourse/courseItemHooks.ts
deleted file mode 100644
index 0ebd0b3..0000000
--- a/nextjs/src/hooks/localCourse/courseItemHooks.ts
+++ /dev/null
@@ -1,233 +0,0 @@
-// import { localCourseKeys } from "./localCourseKeys";
-// import {
-// CourseItemReturnType,
-// CourseItemType,
-// } from "@/models/local/courseItemTypes";
-// import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
-// import {
-// useMutation,
-// useQueryClient,
-// useSuspenseQueries,
-// useSuspenseQuery,
-// } from "@tanstack/react-query";
-// // import {
-// // createItemOnServer,
-// // deleteItemOnServer,
-// // getAllItemsFromServer,
-// // getItemFromServer,
-// // updateItemOnServer,
-// // } from "./courseItemServerActions";
-
-// export const getAllItemsQueryConfig = (
-// courseName: string,
-// moduleName: string,
-// type: T
-// ) => ({
-// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
-// queryFn: async (): Promise[]> => {
-// return await getAllItemsFromServer({
-// courseName,
-// moduleName,
-// type,
-// });
-// },
-// });
-
-// export const getItemQueryConfig = (
-// courseName: string,
-// moduleName: string,
-// name: string,
-// type: T
-// ) => {
-// return {
-// queryKey: localCourseKeys.itemOfType(courseName, moduleName, name, type),
-// queryFn: async () => {
-// return await getItemFromServer({
-// moduleName,
-// courseName,
-// itemName: name,
-// type,
-// });
-// },
-// };
-// };
-
-// 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),
-// })),
-// combine: (results) => ({
-// data: results.map((r) => r.data),
-// pending: results.some((r) => r.isPending),
-// }),
-// });
-// };
-
-// export const useUpdateItemMutation = (type: T) => {
-// const { courseName } = useCourseContext();
-// const queryClient = useQueryClient();
-// return useMutation({
-// mutationFn: async ({
-// item,
-// moduleName,
-// previousModuleName,
-// previousItemName,
-// itemName,
-// }: {
-// item: CourseItemReturnType;
-// moduleName: string;
-// previousModuleName: string;
-// previousItemName: string;
-// itemName: string;
-// }) => {
-// if (previousItemName !== item.name || previousModuleName !== moduleName) {
-// queryClient.removeQueries({
-// queryKey: localCourseKeys.itemOfType(
-// courseName,
-// previousModuleName,
-// previousItemName,
-// type
-// ),
-// });
-// queryClient.removeQueries({
-// queryKey: localCourseKeys.allItemsOfType(
-// courseName,
-// previousModuleName,
-// type
-// ),
-// });
-// }
-
-// queryClient.setQueryData(
-// localCourseKeys.itemOfType(courseName, moduleName, itemName, type),
-// item
-// );
-// await updateItemOnServer({
-// courseName,
-// moduleName,
-// item,
-// type,
-// previousItemName,
-// previousModuleName,
-// itemName,
-// });
-// },
-// onSuccess: async (_, { moduleName, itemName }) => {
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.itemOfType(
-// courseName,
-// moduleName,
-// itemName,
-// type
-// ),
-// refetchType: "all",
-// });
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
-// refetchType: "all",
-// });
-// },
-// });
-// };
-
-// export const useCreateItemMutation = (type: T) => {
-// const { courseName } = useCourseContext();
-// const queryClient = useQueryClient();
-// return useMutation({
-// mutationFn: async ({
-// item,
-// moduleName,
-// itemName,
-// }: {
-// item: CourseItemReturnType;
-// moduleName: string;
-// itemName: string;
-// }) => {
-// queryClient.setQueryData(
-// localCourseKeys.itemOfType(courseName, moduleName, itemName, type),
-// item
-// );
-// await createItemOnServer({
-// courseName,
-// moduleName,
-// item,
-// type,
-// itemName,
-// });
-// },
-// onSuccess: async (_, { moduleName, itemName }) => {
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.itemOfType(
-// courseName,
-// moduleName,
-// itemName,
-// type
-// ),
-// });
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
-// });
-// },
-// });
-// };
-
-// export const useDeleteItemMutation = (type: T) => {
-// const { courseName } = useCourseContext();
-// const queryClient = useQueryClient();
-// return useMutation({
-// mutationFn: async ({
-// moduleName,
-// itemName,
-// }: {
-// moduleName: string;
-// itemName: string;
-// }) => {
-// await deleteItemOnServer({
-// courseName,
-// itemName,
-// moduleName,
-// type,
-// });
-// },
-// onSuccess: async (_, { moduleName, itemName }) => {
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
-// // refetchType: "all",
-// });
-// await queryClient.invalidateQueries({
-// queryKey: localCourseKeys.itemOfType(
-// courseName,
-// moduleName,
-// itemName,
-// type
-// ),
-// refetchType: "none",
-// });
-// },
-// });
-// };
diff --git a/nextjs/src/hooks/localCourse/courseItemServerActions.ts b/nextjs/src/hooks/localCourse/courseItemServerActions.ts
deleted file mode 100644
index c38f403..0000000
--- a/nextjs/src/hooks/localCourse/courseItemServerActions.ts
+++ /dev/null
@@ -1,237 +0,0 @@
-// "use server";
-
-// import { ItemInDay } from "@/app/course/[courseName]/calendar/day/ItemInDay";
-// import { LocalAssignment } from "@/models/local/assignment/localAssignment";
-// import {
-// CourseItemReturnType,
-// CourseItemType,
-// } from "@/models/local/courseItemTypes";
-// import { LocalCoursePage } from "@/models/local/page/localCoursePage";
-// import { LocalQuiz } from "@/models/local/quiz/localQuiz";
-// import { fileStorageService } from "@/services/fileStorage/fileStorageService";
-
-// export async function getAllItemsFromServer({
-// courseName,
-// moduleName,
-// type,
-// }: {
-// courseName: string;
-// moduleName: string;
-// type: T;
-// }): Promise[]> {
-// if (type === "Assignment") {
-// const assignments = await fileStorageService.assignments.getAssignments(
-// courseName,
-// moduleName
-// );
-// return assignments as CourseItemReturnType[];
-// }
-// if (type === "Quiz") {
-// const quizzes = await fileStorageService.quizzes.getQuizzes(
-// courseName,
-// moduleName
-// );
-// return quizzes as CourseItemReturnType[];
-// }
-// if (type === "Page") {
-// const pages = await fileStorageService.pages.getPages(
-// courseName,
-// moduleName
-// );
-// return pages as CourseItemReturnType[];
-// }
-
-// throw Error(`cannot get item from server, invalid type: ${type}`)
-// }
-
-// export async function getItemFromServer({
-// courseName,
-// moduleName,
-// type,
-// itemName,
-// }: {
-// courseName: string;
-// moduleName: string;
-// type: T;
-// itemName: string;
-// }): Promise> {
-// if (type === "Assignment") {
-// const assignment = await fileStorageService.assignments.getAssignment(
-// courseName,
-// moduleName,
-// itemName
-// );
-// return assignment as CourseItemReturnType;
-// }
-// if (type === "Assignment") {
-// const quiz = await fileStorageService.quizzes.getQuiz(
-// courseName,
-// moduleName,
-// itemName
-// );
-// return quiz as CourseItemReturnType;
-// }
-// const page = await fileStorageService.pages.getPage(
-// courseName,
-// moduleName,
-// itemName
-// );
-// return page as CourseItemReturnType;
-// }
-
-// export async function createItemOnServer({
-// courseName,
-// moduleName,
-// type,
-// item,
-// itemName,
-// }: {
-// courseName: string;
-// moduleName: string;
-// type: T;
-// item: CourseItemReturnType;
-// itemName: string;
-// }) {
-// if (type === "Assignment") {
-// const assignment = item as LocalAssignment;
-// await fileStorageService.assignments.updateOrCreateAssignment({
-// courseName,
-// moduleName,
-// assignmentName: itemName,
-// assignment,
-// });
-// }
-// if (type === "Quiz") {
-// const quiz = item as LocalQuiz;
-// await fileStorageService.quizzes.updateQuiz(
-// courseName,
-// moduleName,
-// itemName,
-// quiz
-// );
-// }
-// if (type === "Page") {
-// const page = item as LocalCoursePage;
-// await fileStorageService.pages.updatePage(
-// courseName,
-// moduleName,
-// itemName,
-// page
-// );
-// }
-// }
-
-// export async function updateItemOnServer({
-// item,
-// courseName,
-// moduleName,
-// previousModuleName,
-// previousItemName,
-// itemName,
-// type,
-// }: {
-// item: CourseItemReturnType;
-// courseName: string;
-// moduleName: string;
-// previousModuleName: string;
-// previousItemName: string;
-// itemName: string;
-// type: T;
-// }) {
-// if (type === "Assignment") {
-// const assignment = item as LocalAssignment;
-// await fileStorageService.assignments.updateOrCreateAssignment({
-// courseName,
-// moduleName,
-// assignmentName: itemName,
-// assignment,
-// });
-
-// if (
-// assignment.name !== previousItemName ||
-// moduleName !== previousModuleName
-// ) {
-// fileStorageService.assignments.delete({
-// courseName,
-// moduleName: previousModuleName,
-// assignmentName: previousItemName,
-// });
-// }
-// }
-// if (type === "Quiz") {
-// const quiz = item as LocalQuiz;
-// await fileStorageService.quizzes.updateQuiz(
-// courseName,
-// moduleName,
-// itemName,
-// quiz
-// );
-
-// if (
-// previousModuleName &&
-// previousItemName &&
-// (quiz.name !== previousItemName || moduleName !== previousModuleName)
-// ) {
-// fileStorageService.quizzes.delete({
-// courseName,
-// moduleName: previousModuleName,
-// quizName: previousItemName,
-// });
-// }
-// }
-// if (type === "Page") {
-// const page = item as LocalCoursePage;
-// await fileStorageService.pages.updatePage(
-// courseName,
-// moduleName,
-// itemName,
-// page
-// );
-
-// if (
-// previousModuleName &&
-// previousItemName &&
-// (page.name !== previousItemName || moduleName !== previousModuleName)
-// ) {
-// fileStorageService.pages.delete({
-// courseName,
-// moduleName: previousModuleName,
-// pageName: previousItemName,
-// });
-// }
-// }
-// }
-
-// export async function deleteItemOnServer({
-// courseName,
-// moduleName,
-// itemName,
-// type,
-// }: {
-// courseName: string;
-// moduleName: string;
-// itemName: string;
-// type: T;
-// }) {
-// if (type === "Assignment") {
-// await fileStorageService.assignments.delete({
-// courseName,
-// moduleName,
-// assignmentName: itemName,
-// });
-// }
-// if (type === "Quiz") {
-// await fileStorageService.quizzes.delete({
-// courseName,
-// moduleName,
-// quizName: itemName,
-// });
-// }
-// if (type === "Page") {
-// await fileStorageService.pages.delete({
-// courseName,
-// moduleName,
-// pageName: itemName,
-// });
-// }
-// }
diff --git a/nextjs/src/hooks/localCourse/lectureHooks.ts b/nextjs/src/hooks/localCourse/lectureHooks.ts
index 67bddf8..84a6d50 100644
--- a/nextjs/src/hooks/localCourse/lectureHooks.ts
+++ b/nextjs/src/hooks/localCourse/lectureHooks.ts
@@ -1,51 +1,10 @@
-import {
- useMutation,
- useQueryClient,
- useSuspenseQuery,
-} from "@tanstack/react-query";
-import { lectureKeys } from "./lectureKeys";
-import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
-import {
- deleteLecture,
- getLectures,
- updateLecture,
-} from "@/services/fileStorage/lectureFileStorageService";
-import { Lecture } from "@/models/local/lecture";
-import { useLocalCourseSettingsQuery } from "./localCoursesHooks";
-
-// export const getLecturesQueryConfig = (courseName: string) =>
-// ({
-// queryKey: lectureKeys.allLectures(courseName),
-// queryFn: async () => await getLectures(courseName),
-// } as const);
-
-// export const useLecturesByWeekQuery = () => {
-// const { courseName } = useCourseContext();
-// return useSuspenseQuery(getLecturesQueryConfig(courseName));
-// };
+import { trpc } from "@/services/trpc/utils";
export const useLectureUpdateMutation = () => {
- const { courseName } = useCourseContext();
- const [settings] = useLocalCourseSettingsQuery();
- const queryClient = useQueryClient();
- return useMutation({
- mutationFn: async ({
- lecture,
- previousDay,
- }: {
- lecture: Lecture;
- previousDay?: string;
- }) => {
- await updateLecture(courseName, settings, lecture);
-
- if (previousDay && previousDay !== lecture.date) {
- await deleteLecture(courseName, settings, previousDay);
- }
- },
+ const utils = trpc.useUtils();
+ return trpc.lectures.updateLecture.useMutation({
onSuccess: () => {
- queryClient.invalidateQueries({
- queryKey: lectureKeys.allLectures(courseName),
- });
+ utils.lectures.getLectures.invalidate();
},
});
};
diff --git a/nextjs/src/hooks/localCourse/lectureKeys.ts b/nextjs/src/hooks/localCourse/lectureKeys.ts
deleted file mode 100644
index e865898..0000000
--- a/nextjs/src/hooks/localCourse/lectureKeys.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const lectureKeys = {
- allLectures: (courseName: string) => ["lectures", courseName] as const
-}
\ No newline at end of file
diff --git a/nextjs/src/hooks/localCourse/localCourseKeys.ts b/nextjs/src/hooks/localCourse/localCourseKeys.ts
deleted file mode 100644
index 8b3c4d7..0000000
--- a/nextjs/src/hooks/localCourse/localCourseKeys.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { CourseItemType, typeToFolder } from "@/models/local/courseItemTypes";
-
-export const localCourseKeys = {
- allCoursesSettings: ["all courses settings"] as const,
- allCoursesNames: ["all courses names"] as const,
- settings: (courseName: string) =>
- ["course details", courseName, "settings"] as const,
- moduleNames: (courseName: string) =>
- [
- "course details",
- courseName,
- "modules",
- { type: "names" } as const,
- ] as const,
- allItemsOfType: (
- courseName: string,
- moduleName: string,
- type: CourseItemType
- ) =>
- [
- "course details",
- courseName,
- "modules",
- moduleName,
- typeToFolder[type],
- { type: "all" },
- ] as const,
- itemOfType: (
- courseName: string,
- moduleName: string,
- name: string,
- type: CourseItemType
- ) =>
- [
- "course details",
- courseName,
- "modules",
- moduleName,
- typeToFolder[type],
- name,
- ] as const,
-};
diff --git a/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts b/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts
index c8c356c..615d393 100644
--- a/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts
+++ b/nextjs/src/hooks/localCourse/localCourseModuleHooks.ts
@@ -1,38 +1,19 @@
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
-import {
- useMutation,
- useQueryClient,
- useSuspenseQuery,
-} from "@tanstack/react-query";
-import { localCourseKeys } from "./localCourseKeys";
-import {
- createModuleOnServer,
- getModuleNamesFromServer,
-} from "./localCourseModuleServerActions";
import { trpc } from "@/services/trpc/utils";
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
export const useModuleNamesQuery = () => {
const { courseName } = useCourseContext();
- return useSuspenseQuery({
- queryKey: localCourseKeys.moduleNames(courseName),
- queryFn: async (): Promise => {
- return await getModuleNamesFromServer({ courseName });
- },
- });
+ return trpc.module.getModuleNames.useSuspenseQuery({ courseName });
};
export const useCreateModuleMutation = () => {
const { courseName } = useCourseContext();
- const queryClient = useQueryClient();
- return useMutation({
- mutationFn: async (moduleName: string) => {
- await createModuleOnServer({ courseName, moduleName });
- },
+ const utils = trpc.useUtils();
+
+ return trpc.module.createModule.useMutation({
onSuccess: () => {
- queryClient.invalidateQueries({
- queryKey: localCourseKeys.moduleNames(courseName),
- });
+ utils.module.getModuleNames.invalidate({ courseName });
},
});
};
@@ -41,67 +22,39 @@ export const useAllCourseDataQuery = (): {
assignmentsAndModules: {
moduleName: string;
assignment: LocalAssignment;
-}[];
+ }[];
quizzesAndModules: any[];
pagesAndModules: any[];
} => {
const { courseName } = useCourseContext();
- const { data: moduleNames } = useModuleNamesQuery();
-
+ const [moduleNames] = useModuleNamesQuery();
const [assignments] = trpc.useSuspenseQueries((t) =>
moduleNames.map((moduleName) =>
t.assignment.getAllAssignments({ courseName, moduleName })
)
);
+ const [quizzes] = trpc.useSuspenseQueries((t) =>
+ moduleNames.map((moduleName) =>
+ t.quiz.getAllQuizzes({ courseName, moduleName })
+ )
+ );
+
+ const [pages] = trpc.useSuspenseQueries((t) =>
+ moduleNames.map((moduleName) =>
+ t.page.getAllPages({ courseName, moduleName })
+ )
+ );
+
const assignmentsAndModules = moduleNames.flatMap((moduleName, index) => {
return assignments[index].map((assignment) => ({ moduleName, assignment }));
});
+ const quizzesAndModules = moduleNames.flatMap((moduleName, index) => {
+ return quizzes[index].map((quiz) => ({ moduleName, quiz }));
+ });
+ const pagesAndModules = moduleNames.flatMap((moduleName, index) => {
+ return pages[index].map((page) => ({ moduleName, page }));
+ });
- // const { data: assignmentsAndModules } = useSuspenseQueries({
- // queries: moduleNames.map((moduleName) =>
- // getAllAssignmentsQueryConfig(courseName, moduleName)
- // ),
- // combine: (results) => ({
- // data: results.flatMap((r, i) =>
- // r.data.map((assignment) => ({
- // moduleName: moduleNames[i],
- // assignment,
- // }))
- // ),
- // pending: results.some((r) => r.isPending),
- // }),
- // });
-
- // const { data: quizzesAndModules } = useSuspenseQueries({
- // queries: moduleNames.map((moduleName) =>
- // getAllItemsQueryConfig(courseName, moduleName, "Quiz")
- // ),
- // combine: (results) => ({
- // data: results.flatMap((r, i) =>
- // r.data.map((quiz) => ({
- // moduleName: moduleNames[i],
- // quiz,
- // }))
- // ),
- // pending: results.some((r) => r.isPending),
- // }),
- // });
-
- // const { data: pagesAndModules } = useSuspenseQueries({
- // queries: moduleNames.map((moduleName) =>
- // getAllItemsQueryConfig(courseName, moduleName, "Page")
- // ),
- // combine: (results) => ({
- // data: results.flatMap((r, i) =>
- // r.data.map((page) => ({
- // moduleName: moduleNames[i],
- // page,
- // }))
- // ),
- // pending: results.some((r) => r.isPending),
- // }),
- // });
-
- return { assignmentsAndModules, quizzesAndModules: [], pagesAndModules: [] };
+ return { assignmentsAndModules, quizzesAndModules, pagesAndModules };
};
diff --git a/nextjs/src/hooks/localCourse/localCourseModuleServerActions.ts b/nextjs/src/hooks/localCourse/localCourseModuleServerActions.ts
deleted file mode 100644
index 48926d3..0000000
--- a/nextjs/src/hooks/localCourse/localCourseModuleServerActions.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-"use server";
-
-import { fileStorageService } from "@/services/fileStorage/fileStorageService";
-
-export async function getModuleNamesFromServer({
- courseName,
-}: {
- courseName: string;
-}) {
- return await fileStorageService.modules.getModuleNames(courseName);
-}
-
-export async function createModuleOnServer({
- courseName,
- moduleName,
-}: {
- courseName: string;
- moduleName: string;
-}) {
- await fileStorageService.modules.createModule(courseName, moduleName);
-}
diff --git a/nextjs/src/hooks/localCourse/localCoursesHooks.ts b/nextjs/src/hooks/localCourse/localCoursesHooks.ts
index a2821d6..ab1f84a 100644
--- a/nextjs/src/hooks/localCourse/localCoursesHooks.ts
+++ b/nextjs/src/hooks/localCourse/localCoursesHooks.ts
@@ -5,11 +5,9 @@ import { trpc } from "@/services/trpc/utils";
export const useLocalCoursesSettingsQuery = () =>
trpc.settings.allCoursesSettings.useSuspenseQuery();
-
export const useLocalCourseSettingsQuery = () => {
const { courseName } = useCourseContext();
return trpc.settings.courseSettings.useSuspenseQuery({ courseName });
-
};
export const useCreateLocalCourseMutation = () => {
@@ -17,6 +15,7 @@ export const useCreateLocalCourseMutation = () => {
return trpc.settings.createCourse.useMutation({
onSuccess: () => {
utils.settings.allCoursesSettings.invalidate();
+ utils.directories.getEmptyDirectories.invalidate();
},
});
};
diff --git a/nextjs/src/hooks/localCourse/localCoursesServerActions.ts b/nextjs/src/hooks/localCourse/localCoursesServerActions.ts
deleted file mode 100644
index 8e153fa..0000000
--- a/nextjs/src/hooks/localCourse/localCoursesServerActions.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-"use server";
-import {
- LocalCourseSettings,
-} from "@/models/local/localCourseSettings";
-import { fileStorageService } from "@/services/fileStorage/fileStorageService";
-
-export async function getCourseSettingsFromServer({
- courseName,
-}: {
- courseName: string;
-}) {
- return await fileStorageService.settings.getCourseSettings(courseName);
-}
-export async function getAllCoursesSettingsFromServer() {
- return await fileStorageService.settings.getAllCoursesSettings();
-}
-
-// export async function createCourseOnServer({
-// course,
-// }: {
-// course: LocalCourse;
-// }) {
-// await fileStorageService.settings.updateCourseSettings(
-// course.settings.name,
-// course.settings
-// );
-// }
-
-// export async function updateCourseSettingsOnServer({
-// courseName,
-// settings,
-// }: {
-// courseName: string;
-// settings: LocalCourseSettings;
-// }) {
-// await fileStorageService.settings.updateCourseSettings(courseName, settings);
-// }
diff --git a/nextjs/src/hooks/localCourse/storageDirectoryHooks.ts b/nextjs/src/hooks/localCourse/storageDirectoryHooks.ts
index 339045e..0ce8b9c 100644
--- a/nextjs/src/hooks/localCourse/storageDirectoryHooks.ts
+++ b/nextjs/src/hooks/localCourse/storageDirectoryHooks.ts
@@ -1,19 +1,8 @@
-import { axiosClient } from "@/services/axiosUtils";
-import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
-import { getEmptyDirectories } from "./storageDirectoryServerActions";
+import { trpc } from "@/services/trpc/utils";
export const directoryKeys = {
emptyFolders: ["empty folders"] as const,
};
export const useEmptyDirectoriesQuery = () =>
- useQuery({
- queryKey: directoryKeys.emptyFolders,
- queryFn: async () => await getEmptyDirectories(),
- // queryFn: getEmptyDirectories,
- // async () => {
- // const url = "/api/directories/empty";
- // const { data } = await axiosClient.get(url);
- // return data;
- // },
- });
+ trpc.directories.getEmptyDirectories.useSuspenseQuery();
diff --git a/nextjs/src/hooks/localCourse/storageDirectoryServerActions.ts b/nextjs/src/hooks/localCourse/storageDirectoryServerActions.ts
deleted file mode 100644
index 544dbc5..0000000
--- a/nextjs/src/hooks/localCourse/storageDirectoryServerActions.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-"use server"
-
-import { fileStorageService } from "@/services/fileStorage/fileStorageService"
-
-export async function getEmptyDirectories() {
- return await fileStorageService.getEmptyDirectories()
-}
\ No newline at end of file
diff --git a/nextjs/src/models/local/lecture.ts b/nextjs/src/models/local/lecture.ts
index e5d7517..4e44dc8 100644
--- a/nextjs/src/models/local/lecture.ts
+++ b/nextjs/src/models/local/lecture.ts
@@ -1,5 +1,13 @@
+import { z } from "zod";
+
export interface Lecture {
name: string
date: string
content: string
-}
\ No newline at end of file
+}
+
+export const zodLecture = z.object({
+ name: z.string(),
+ date: z.string(),
+ content: z.string(),
+});
diff --git a/nextjs/src/services/fileStorage/lectureFileStorageService.ts b/nextjs/src/services/fileStorage/lectureFileStorageService.ts
index fe73863..09e1ca7 100644
--- a/nextjs/src/services/fileStorage/lectureFileStorageService.ts
+++ b/nextjs/src/services/fileStorage/lectureFileStorageService.ts
@@ -1,4 +1,4 @@
-"use server";
+
import path from "path";
import { basePath } from "./utils/fileSystemUtils";
import fs from "fs/promises";
diff --git a/nextjs/src/services/trpc/router/app.ts b/nextjs/src/services/trpc/router/app.ts
index 166bc3d..4e59a68 100644
--- a/nextjs/src/services/trpc/router/app.ts
+++ b/nextjs/src/services/trpc/router/app.ts
@@ -2,7 +2,9 @@ import { createTrpcContext } from "../context";
import publicProcedure from "../procedures/public";
import { createCallerFactory, router } from "../trpc";
import { assignmentRouter } from "./assignmentRouter";
+import { directoriesRouter } from "./directoriesRouter";
import { lectureRouter } from "./lectureRouter";
+import { moduleRouter } from "./moduleRouter";
import { pageRouter } from "./pageRouter";
import { quizRouter } from "./quizRouter";
import { settingsRouter } from "./settingsRouter";
@@ -22,6 +24,8 @@ export const trpcAppRouter = router({
settings: settingsRouter,
quiz: quizRouter,
page: pageRouter,
+ module: moduleRouter,
+ directories: directoriesRouter,
});
export const createCaller = createCallerFactory(trpcAppRouter);
diff --git a/nextjs/src/services/trpc/router/directoriesRouter.ts b/nextjs/src/services/trpc/router/directoriesRouter.ts
new file mode 100644
index 0000000..10f111a
--- /dev/null
+++ b/nextjs/src/services/trpc/router/directoriesRouter.ts
@@ -0,0 +1,11 @@
+import publicProcedure from "../procedures/public";
+import { z } from "zod";
+import { router } from "../trpc";
+import { fileStorageService } from "@/services/fileStorage/fileStorageService";
+import { zodLocalAssignment } from "@/models/local/assignment/localAssignment";
+
+export const directoriesRouter = router({
+ getEmptyDirectories: publicProcedure.query(async () => {
+ return await fileStorageService.getEmptyDirectories()
+ })
+})
\ No newline at end of file
diff --git a/nextjs/src/services/trpc/router/lectureRouter.ts b/nextjs/src/services/trpc/router/lectureRouter.ts
index 8f33bc9..931b6a4 100644
--- a/nextjs/src/services/trpc/router/lectureRouter.ts
+++ b/nextjs/src/services/trpc/router/lectureRouter.ts
@@ -1,15 +1,40 @@
import { z } from "zod";
import publicProcedure from "../procedures/public";
import { router } from "../trpc";
-import { getLectures } from "@/services/fileStorage/lectureFileStorageService";
-
+import {
+ deleteLecture,
+ getLectures,
+ updateLecture,
+} from "@/services/fileStorage/lectureFileStorageService";
+import { zodLecture } from "@/models/local/lecture";
+import { zodLocalCourseSettings } from "@/models/local/localCourseSettings";
export const lectureRouter = router({
getLectures: publicProcedure
- .input(z.object({
- courseName: z.string()
- }))
- .query(async ({input: {courseName}}) => {
- return await getLectures(courseName)
- })
-})
\ No newline at end of file
+ .input(
+ z.object({
+ courseName: z.string(),
+ })
+ )
+ .query(async ({ input: { courseName } }) => {
+ return await getLectures(courseName);
+ }),
+ updateLecture: publicProcedure
+ .input(
+ z.object({
+ courseName: z.string(),
+ lecture: zodLecture,
+ previousDay: z.string().optional(),
+ settings: zodLocalCourseSettings,
+ })
+ )
+ .mutation(
+ async ({ input: { courseName, settings, lecture, previousDay } }) => {
+ await updateLecture(courseName, settings, lecture);
+
+ if (previousDay && previousDay !== lecture.date) {
+ await deleteLecture(courseName, settings, previousDay);
+ }
+ }
+ ),
+});
diff --git a/nextjs/src/services/trpc/router/moduleRouter.ts b/nextjs/src/services/trpc/router/moduleRouter.ts
new file mode 100644
index 0000000..544ef6d
--- /dev/null
+++ b/nextjs/src/services/trpc/router/moduleRouter.ts
@@ -0,0 +1,26 @@
+import { z } from "zod";
+import publicProcedure from "../procedures/public";
+import { router } from "../trpc";
+import { fileStorageService } from "@/services/fileStorage/fileStorageService";
+
+export const moduleRouter = router({
+ getModuleNames: publicProcedure
+ .input(
+ z.object({
+ courseName: z.string(),
+ })
+ )
+ .query(async ({ input: { courseName } }) => {
+ return await fileStorageService.modules.getModuleNames(courseName);
+ }),
+ createModule: publicProcedure
+ .input(
+ z.object({
+ courseName: z.string(),
+ moduleName: z.string(),
+ })
+ )
+ .mutation(async ({ input: { courseName, moduleName } }) => {
+ await fileStorageService.modules.createModule(courseName, moduleName);
+ }),
+});