more trpc

This commit is contained in:
2024-11-11 13:53:57 -07:00
parent 5fa5a072bf
commit 1302e00429
26 changed files with 165 additions and 761 deletions

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
MAJOR_VERSION="2" MAJOR_VERSION="2"
MINOR_VERSION="1" MINOR_VERSION="2"
VERSION="$MAJOR_VERSION.$MINOR_VERSION" VERSION="$MAJOR_VERSION.$MINOR_VERSION"
docker build -t canvas_management:$VERSION . docker build -t canvas_management:$VERSION .

View File

@@ -18,6 +18,7 @@ import { DraggableItem } from "./draggingContext";
import { getNewLockDate } from "./getNewLockDate"; import { getNewLockDate } from "./getNewLockDate";
import { trpc } from "@/services/trpc/utils"; import { trpc } from "@/services/trpc/utils";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useCourseContext } from "../courseContext";
export function useItemDropOnDay({ export function useItemDropOnDay({
setIsDragging, setIsDragging,
@@ -33,6 +34,7 @@ export function useItemDropOnDay({
modal: { isOpen: boolean; openModal: () => void; closeModal: () => void }; modal: { isOpen: boolean; openModal: () => void; closeModal: () => void };
}) { }) {
const [settings] = useLocalCourseSettingsQuery(); const [settings] = useLocalCourseSettingsQuery();
const { courseName } = useCourseContext();
// const { data: weeks } = useLecturesByWeekQuery(); // const { data: weeks } = useLecturesByWeekQuery();
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({
courseName: settings.name, courseName: settings.name,
@@ -95,6 +97,8 @@ export function useItemDropOnDay({
...lecture, ...lecture,
date: getDateOnlyMarkdownString(dayAsDate), date: getDateOnlyMarkdownString(dayAsDate),
}, },
courseName,
settings,
}); });
setModalText(""); setModalText("");
setModalCallback(() => {}); setModalCallback(() => {});
@@ -110,6 +114,8 @@ export function useItemDropOnDay({
...lecture, ...lecture,
date: getDateOnlyMarkdownString(dayAsDate), date: getDateOnlyMarkdownString(dayAsDate),
}, },
courseName,
settings,
}); });
} }
} }

View File

@@ -1,9 +1,7 @@
"use client"; "use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor"; import { MonacoEditor } from "@/components/editor/MonacoEditor";
import { import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
useLectureUpdateMutation,
} from "@/hooks/localCourse/lectureHooks";
import { import {
lectureToString, lectureToString,
parseLecture, parseLecture,
@@ -14,10 +12,11 @@ import EditLectureTitle from "./EditLectureTitle";
import LectureButtons from "./LectureButtons"; import LectureButtons from "./LectureButtons";
import { trpc } from "@/services/trpc/utils"; import { trpc } from "@/services/trpc/utils";
import { useCourseContext } from "../../context/courseContext"; import { useCourseContext } from "../../context/courseContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
export default function EditLecture({ lectureDay }: { lectureDay: string }) { export default function EditLecture({ lectureDay }: { lectureDay: string }) {
// const { data: weeks } = useLecturesByWeekQuery();
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const [settings] = useLocalCourseSettingsQuery();
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName }); const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
const updateLecture = useLectureUpdateMutation(); const updateLecture = useLectureUpdateMutation();
@@ -42,7 +41,7 @@ Date: ${lectureDay}
const parsed = parseLecture(text); const parsed = parseLecture(text);
if (!lecture || lectureToString(parsed) !== lectureToString(lecture)) { if (!lecture || lectureToString(parsed) !== lectureToString(lecture)) {
console.log("updating lecture"); console.log("updating lecture");
updateLecture.mutate({ lecture: parsed }); updateLecture.mutate({ lecture: parsed, settings, courseName });
} }
setError(""); setError("");
} catch (e: any) { } catch (e: any) {

View File

@@ -2,8 +2,10 @@ import { Expandable } from "@/components/Expandable";
import TextInput from "@/components/form/TextInput"; import TextInput from "@/components/form/TextInput";
import { useCreateModuleMutation } from "@/hooks/localCourse/localCourseModuleHooks"; import { useCreateModuleMutation } from "@/hooks/localCourse/localCourseModuleHooks";
import React, { useState } from "react"; import React, { useState } from "react";
import { useCourseContext } from "../context/courseContext";
export default function CreateModule() { export default function CreateModule() {
const { courseName } = useCourseContext();
const createModule = useCreateModuleMutation(); const createModule = useCreateModuleMutation();
const [moduleName, setModuleName] = useState(""); const [moduleName, setModuleName] = useState("");
return ( return (
@@ -19,7 +21,7 @@ export default function CreateModule() {
onSubmit={async (e) => { onSubmit={async (e) => {
e.preventDefault(); e.preventDefault();
if (moduleName) { if (moduleName) {
await createModule.mutateAsync(moduleName); await createModule.mutateAsync({ moduleName, courseName });
setModuleName(""); setModuleName("");
} }
}} }}

View File

@@ -4,7 +4,7 @@ import ExpandableModule from "./ExpandableModule";
import CreateModule from "./CreateModule"; import CreateModule from "./CreateModule";
export default function ModuleList() { export default function ModuleList() {
const { data: moduleNames } = useModuleNamesQuery(); const [moduleNames] = useModuleNamesQuery();
return ( return (
<div> <div>
{/* {moduleNames.map((m) => ( {/* {moduleNames.map((m) => (

View File

@@ -28,7 +28,7 @@ export default function NewItemForm({
}) { }) {
const [settings] = useLocalCourseSettingsQuery(); const [settings] = useLocalCourseSettingsQuery();
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const { data: modules } = useModuleNamesQuery(); const [modules] = useModuleNamesQuery();
const [type, setType] = useState<"Assignment" | "Quiz" | "Page">( const [type, setType] = useState<"Assignment" | "Quiz" | "Page">(
"Assignment" "Assignment"
); );

View File

@@ -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( const allSettings = await fileStorageService.settings.getAllCoursesSettings();
// allSettings.map( // assignments
// async (settings) => await Promise.all(
// await trpcHelper.lectures.getLectures.fetch({ allSettings.map(async (settings) => {
// courseName: settings.name, 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); // await hydrateCourses(trpcHelper.queryClient);

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { QueryClientProvider } from "@tanstack/react-query";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { getQueryClient } from "./providersQueryClientUtils"; import { getQueryClient } from "./providersQueryClientUtils";
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling"; import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";

View File

@@ -48,7 +48,7 @@ export const useUpdateAssignmentMutation = () => {
export const useCreateAssignmentMutation = () => { export const useCreateAssignmentMutation = () => {
const utils = trpc.useUtils(); const utils = trpc.useUtils();
return trpc.assignment.createAssignment.useMutation({ return trpc.assignment.createAssignment.useMutation({
onSuccess: (_, { courseName, moduleName, assignmentName }) => { onSuccess: (_, { courseName, moduleName }) => {
utils.assignment.getAllAssignments.invalidate({ courseName, moduleName }); utils.assignment.getAllAssignments.invalidate({ courseName, moduleName });
}, },
}); });

View File

@@ -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 = <T extends CourseItemType>(
// courseName: string,
// moduleName: string,
// type: T
// ) => ({
// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, type),
// queryFn: async (): Promise<CourseItemReturnType<T>[]> => {
// return await getAllItemsFromServer({
// courseName,
// moduleName,
// type,
// });
// },
// });
// export const getItemQueryConfig = <T extends CourseItemType>(
// 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 = <T extends CourseItemType>(
// moduleName: string,
// name: string,
// type: T
// ) => {
// const { courseName } = useCourseContext();
// return useSuspenseQuery(
// getItemQueryConfig(courseName, moduleName, name, type)
// );
// };
// const useAllItemsQuery = <T extends CourseItemType>(
// moduleName: string,
// type: T
// ) => {
// const { courseName } = useCourseContext();
// return useSuspenseQuery(getAllItemsQueryConfig(courseName, moduleName, type));
// };
// export const useItemsQueries = <T extends CourseItemType>(
// 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 = <T extends CourseItemType>(type: T) => {
// const { courseName } = useCourseContext();
// const queryClient = useQueryClient();
// return useMutation({
// mutationFn: async ({
// item,
// moduleName,
// previousModuleName,
// previousItemName,
// itemName,
// }: {
// item: CourseItemReturnType<T>;
// 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 = <T extends CourseItemType>(type: T) => {
// const { courseName } = useCourseContext();
// const queryClient = useQueryClient();
// return useMutation({
// mutationFn: async ({
// item,
// moduleName,
// itemName,
// }: {
// item: CourseItemReturnType<T>;
// 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 = <T extends CourseItemType>(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",
// });
// },
// });
// };

View File

@@ -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<T extends CourseItemType>({
// courseName,
// moduleName,
// type,
// }: {
// courseName: string;
// moduleName: string;
// type: T;
// }): Promise<CourseItemReturnType<T>[]> {
// if (type === "Assignment") {
// const assignments = await fileStorageService.assignments.getAssignments(
// courseName,
// moduleName
// );
// return assignments as CourseItemReturnType<T>[];
// }
// if (type === "Quiz") {
// const quizzes = await fileStorageService.quizzes.getQuizzes(
// courseName,
// moduleName
// );
// return quizzes as CourseItemReturnType<T>[];
// }
// if (type === "Page") {
// const pages = await fileStorageService.pages.getPages(
// courseName,
// moduleName
// );
// return pages as CourseItemReturnType<T>[];
// }
// throw Error(`cannot get item from server, invalid type: ${type}`)
// }
// export async function getItemFromServer<T extends CourseItemType>({
// courseName,
// moduleName,
// type,
// itemName,
// }: {
// courseName: string;
// moduleName: string;
// type: T;
// itemName: string;
// }): Promise<CourseItemReturnType<T>> {
// if (type === "Assignment") {
// const assignment = await fileStorageService.assignments.getAssignment(
// courseName,
// moduleName,
// itemName
// );
// return assignment as CourseItemReturnType<T>;
// }
// if (type === "Assignment") {
// const quiz = await fileStorageService.quizzes.getQuiz(
// courseName,
// moduleName,
// itemName
// );
// return quiz as CourseItemReturnType<T>;
// }
// const page = await fileStorageService.pages.getPage(
// courseName,
// moduleName,
// itemName
// );
// return page as CourseItemReturnType<T>;
// }
// export async function createItemOnServer<T extends CourseItemType>({
// courseName,
// moduleName,
// type,
// item,
// itemName,
// }: {
// courseName: string;
// moduleName: string;
// type: T;
// item: CourseItemReturnType<T>;
// 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<T extends CourseItemType>({
// item,
// courseName,
// moduleName,
// previousModuleName,
// previousItemName,
// itemName,
// type,
// }: {
// item: CourseItemReturnType<T>;
// 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<T extends CourseItemType>({
// 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,
// });
// }
// }

View File

@@ -1,51 +1,10 @@
import { import { trpc } from "@/services/trpc/utils";
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));
// };
export const useLectureUpdateMutation = () => { export const useLectureUpdateMutation = () => {
const { courseName } = useCourseContext(); const utils = trpc.useUtils();
const [settings] = useLocalCourseSettingsQuery(); return trpc.lectures.updateLecture.useMutation({
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);
}
},
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ utils.lectures.getLectures.invalidate();
queryKey: lectureKeys.allLectures(courseName),
});
}, },
}); });
}; };

View File

@@ -1,3 +0,0 @@
export const lectureKeys = {
allLectures: (courseName: string) => ["lectures", courseName] as const
}

View File

@@ -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,
};

View File

@@ -1,38 +1,19 @@
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; 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 { trpc } from "@/services/trpc/utils";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/models/local/assignment/localAssignment";
export const useModuleNamesQuery = () => { export const useModuleNamesQuery = () => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return useSuspenseQuery({ return trpc.module.getModuleNames.useSuspenseQuery({ courseName });
queryKey: localCourseKeys.moduleNames(courseName),
queryFn: async (): Promise<string[]> => {
return await getModuleNamesFromServer({ courseName });
},
});
}; };
export const useCreateModuleMutation = () => { export const useCreateModuleMutation = () => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const queryClient = useQueryClient(); const utils = trpc.useUtils();
return useMutation({
mutationFn: async (moduleName: string) => { return trpc.module.createModule.useMutation({
await createModuleOnServer({ courseName, moduleName });
},
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ utils.module.getModuleNames.invalidate({ courseName });
queryKey: localCourseKeys.moduleNames(courseName),
});
}, },
}); });
}; };
@@ -41,67 +22,39 @@ export const useAllCourseDataQuery = (): {
assignmentsAndModules: { assignmentsAndModules: {
moduleName: string; moduleName: string;
assignment: LocalAssignment; assignment: LocalAssignment;
}[]; }[];
quizzesAndModules: any[]; quizzesAndModules: any[];
pagesAndModules: any[]; pagesAndModules: any[];
} => { } => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const { data: moduleNames } = useModuleNamesQuery(); const [moduleNames] = useModuleNamesQuery();
const [assignments] = trpc.useSuspenseQueries((t) => const [assignments] = trpc.useSuspenseQueries((t) =>
moduleNames.map((moduleName) => moduleNames.map((moduleName) =>
t.assignment.getAllAssignments({ courseName, 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) => { const assignmentsAndModules = moduleNames.flatMap((moduleName, index) => {
return assignments[index].map((assignment) => ({ moduleName, assignment })); 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({ return { assignmentsAndModules, quizzesAndModules, pagesAndModules };
// 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: [] };
}; };

View File

@@ -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);
}

View File

@@ -5,11 +5,9 @@ import { trpc } from "@/services/trpc/utils";
export const useLocalCoursesSettingsQuery = () => export const useLocalCoursesSettingsQuery = () =>
trpc.settings.allCoursesSettings.useSuspenseQuery(); trpc.settings.allCoursesSettings.useSuspenseQuery();
export const useLocalCourseSettingsQuery = () => { export const useLocalCourseSettingsQuery = () => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return trpc.settings.courseSettings.useSuspenseQuery({ courseName }); return trpc.settings.courseSettings.useSuspenseQuery({ courseName });
}; };
export const useCreateLocalCourseMutation = () => { export const useCreateLocalCourseMutation = () => {
@@ -17,6 +15,7 @@ export const useCreateLocalCourseMutation = () => {
return trpc.settings.createCourse.useMutation({ return trpc.settings.createCourse.useMutation({
onSuccess: () => { onSuccess: () => {
utils.settings.allCoursesSettings.invalidate(); utils.settings.allCoursesSettings.invalidate();
utils.directories.getEmptyDirectories.invalidate();
}, },
}); });
}; };

View File

@@ -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);
// }

View File

@@ -1,19 +1,8 @@
import { axiosClient } from "@/services/axiosUtils"; import { trpc } from "@/services/trpc/utils";
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
import { getEmptyDirectories } from "./storageDirectoryServerActions";
export const directoryKeys = { export const directoryKeys = {
emptyFolders: ["empty folders"] as const, emptyFolders: ["empty folders"] as const,
}; };
export const useEmptyDirectoriesQuery = () => export const useEmptyDirectoriesQuery = () =>
useQuery({ trpc.directories.getEmptyDirectories.useSuspenseQuery();
queryKey: directoryKeys.emptyFolders,
queryFn: async () => await getEmptyDirectories(),
// queryFn: getEmptyDirectories,
// async () => {
// const url = "/api/directories/empty";
// const { data } = await axiosClient.get<string[]>(url);
// return data;
// },
});

View File

@@ -1,7 +0,0 @@
"use server"
import { fileStorageService } from "@/services/fileStorage/fileStorageService"
export async function getEmptyDirectories() {
return await fileStorageService.getEmptyDirectories()
}

View File

@@ -1,5 +1,13 @@
import { z } from "zod";
export interface Lecture { export interface Lecture {
name: string name: string
date: string date: string
content: string content: string
} }
export const zodLecture = z.object({
name: z.string(),
date: z.string(),
content: z.string(),
});

View File

@@ -1,4 +1,4 @@
"use server";
import path from "path"; import path from "path";
import { basePath } from "./utils/fileSystemUtils"; import { basePath } from "./utils/fileSystemUtils";
import fs from "fs/promises"; import fs from "fs/promises";

View File

@@ -2,7 +2,9 @@ import { createTrpcContext } from "../context";
import publicProcedure from "../procedures/public"; import publicProcedure from "../procedures/public";
import { createCallerFactory, router } from "../trpc"; import { createCallerFactory, router } from "../trpc";
import { assignmentRouter } from "./assignmentRouter"; import { assignmentRouter } from "./assignmentRouter";
import { directoriesRouter } from "./directoriesRouter";
import { lectureRouter } from "./lectureRouter"; import { lectureRouter } from "./lectureRouter";
import { moduleRouter } from "./moduleRouter";
import { pageRouter } from "./pageRouter"; import { pageRouter } from "./pageRouter";
import { quizRouter } from "./quizRouter"; import { quizRouter } from "./quizRouter";
import { settingsRouter } from "./settingsRouter"; import { settingsRouter } from "./settingsRouter";
@@ -22,6 +24,8 @@ export const trpcAppRouter = router({
settings: settingsRouter, settings: settingsRouter,
quiz: quizRouter, quiz: quizRouter,
page: pageRouter, page: pageRouter,
module: moduleRouter,
directories: directoriesRouter,
}); });
export const createCaller = createCallerFactory(trpcAppRouter); export const createCaller = createCallerFactory(trpcAppRouter);

View File

@@ -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()
})
})

View File

@@ -1,15 +1,40 @@
import { z } from "zod"; import { z } from "zod";
import publicProcedure from "../procedures/public"; import publicProcedure from "../procedures/public";
import { router } from "../trpc"; 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({ export const lectureRouter = router({
getLectures: publicProcedure getLectures: publicProcedure
.input(z.object({ .input(
courseName: z.string() z.object({
})) courseName: z.string(),
.query(async ({input: {courseName}}) => { })
return await getLectures(courseName) )
}) .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);
}
}
),
});

View File

@@ -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);
}),
});