diff --git a/nextjs/src/app/course/[courseName]/calendar/calendarMonthUtils.ts b/nextjs/src/app/course/[courseName]/calendar/calendarMonthUtils.ts index 65ffdee..256b8a8 100644 --- a/nextjs/src/app/course/[courseName]/calendar/calendarMonthUtils.ts +++ b/nextjs/src/app/course/[courseName]/calendar/calendarMonthUtils.ts @@ -1,5 +1,3 @@ -"use client"; - import { dateToMarkdownString, getDateFromStringOrThrow, diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx index 8d454d4..68a00b4 100644 --- a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx +++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/EditLecture.tsx @@ -1,10 +1,53 @@ "use client"; import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { useState } from "react"; +import { + useLecturesByWeekQuery, + useLectureUpdateMutation, +} from "@/hooks/localCourse/lectureHooks"; +import { Lecture } from "@/models/local/lecture"; +import { + lectureToString, + parseLecture, +} from "@/services/fileStorage/utils/lectureUtils"; +import { useEffect, useState } from "react"; +import LecturePreview from "./LecturePreview"; export default function EditLecture({ lectureDay }: { lectureDay: string }) { - const [text, setText] = useState(""); + const { data: weeks } = useLecturesByWeekQuery(); + const updateLecture = useLectureUpdateMutation(); + const lecture = weeks + .flatMap(({ lectures }) => lectures.map((lecture) => lecture)) + .find((l) => l.date === lectureDay); + + const startingText = lecture ? lectureToString(lecture) : `Name: Name Here +Date: ${lectureDay} +--- +`; + + const [text, setText] = useState(startingText); + const [error, setError] = useState(""); + + useEffect(() => { + const delay = 500; + const handler = setTimeout(() => { + try { + const parsed = parseLecture(text); + if (!lecture || lectureToString(parsed) !== lectureToString(lecture)) { + console.log("updating lecture"); + updateLecture.mutate(parsed); + } + setError(""); + } catch (e: any) { + setError(e.toString()); + } + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [lecture, text, updateLecture]); + return (
@@ -12,8 +55,8 @@ export default function EditLecture({ lectureDay }: { lectureDay: string }) {
- {/*
{error && error}
*/} - {/* */} +
{error && error}
+ {lecture && }
diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx new file mode 100644 index 0000000..046a8a4 --- /dev/null +++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx @@ -0,0 +1,27 @@ +import { Lecture } from "@/models/local/lecture"; +import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; + +export default function LecturePreview({ lecture }: { lecture: Lecture }) { + return ( +
+
+
+
Name
+
{lecture.name}
+
+
+
Date
+
{lecture.date}
+
+
+
+
+
+
+ ); +} diff --git a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/page.tsx b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/page.tsx index 13c4d4d..08598b0 100644 --- a/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/page.tsx +++ b/nextjs/src/app/course/[courseName]/lecture/[lectureDay]/page.tsx @@ -1,5 +1,6 @@ import React from "react"; import EditLecture from "./EditLecture"; +import { getDateFromStringOrThrow, getDateOnlyMarkdownString } from "@/models/local/timeUtils"; export default function page({ params: { lectureDay }, @@ -8,5 +9,7 @@ export default function page({ }) { const decodedLectureDay = decodeURIComponent(lectureDay); console.log(decodedLectureDay); - return ; + const lectureDate = getDateFromStringOrThrow(decodedLectureDay, "lecture day in lecture page") + const lectureDayOnly = getDateOnlyMarkdownString(lectureDate) + return ; } diff --git a/nextjs/src/hooks/localCourse/lectureHooks.ts b/nextjs/src/hooks/localCourse/lectureHooks.ts index 4dc2d85..e920828 100644 --- a/nextjs/src/hooks/localCourse/lectureHooks.ts +++ b/nextjs/src/hooks/localCourse/lectureHooks.ts @@ -1,7 +1,16 @@ -import { useSuspenseQuery } from "@tanstack/react-query"; +import { + useMutation, + useQueryClient, + useSuspenseQuery, +} from "@tanstack/react-query"; import { lectureKeys } from "./lectureKeys"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; -import { getLectures } from "@/services/fileStorage/lectureFileStorageService"; +import { + getLectures, + updateLecture, +} from "@/services/fileStorage/lectureFileStorageService"; +import { Lecture } from "@/models/local/lecture"; +import { useLocalCourseSettingsQuery } from "./localCoursesHooks"; export const getLecturesQueryConfig = (courseName: string) => ({ @@ -9,7 +18,23 @@ export const getLecturesQueryConfig = (courseName: string) => queryFn: async () => await getLectures(courseName), } as const); -export const useLecturesQuery = () => { +export const useLecturesByWeekQuery = () => { const { courseName } = useCourseContext(); return useSuspenseQuery(getLecturesQueryConfig(courseName)); }; + +export const useLectureUpdateMutation = () => { + const { courseName } = useCourseContext(); + const { data: settings } = useLocalCourseSettingsQuery(); + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (lecture: Lecture) => { + await updateLecture(courseName, settings, lecture); + }, + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: lectureKeys.allLectures(courseName), + }); + }, + }); +}; diff --git a/nextjs/src/services/fileStorage/assignmentsFileStorageService.ts b/nextjs/src/services/fileStorage/assignmentsFileStorageService.ts index c10fb9e..cf39560 100644 --- a/nextjs/src/services/fileStorage/assignmentsFileStorageService.ts +++ b/nextjs/src/services/fileStorage/assignmentsFileStorageService.ts @@ -14,7 +14,8 @@ const getAssignmentNames = async (courseName: string, moduleName: string) => { console.log( `Error loading course by name, assignments folder does not exist in ${filePath}` ); - await fs.mkdir(filePath); + // await fs.mkdir(filePath); + return []; } const assignmentFiles = await fs.readdir(filePath); diff --git a/nextjs/src/services/fileStorage/lectureFileStorageService.ts b/nextjs/src/services/fileStorage/lectureFileStorageService.ts index 076941d..b3ee2dd 100644 --- a/nextjs/src/services/fileStorage/lectureFileStorageService.ts +++ b/nextjs/src/services/fileStorage/lectureFileStorageService.ts @@ -2,12 +2,18 @@ import path from "path"; import { basePath } from "./utils/fileSystemUtils"; import fs from "fs/promises"; +import { + lectureFolderName, + lectureToString, + parseLecture, +} from "./utils/lectureUtils"; import { Lecture } from "@/models/local/lecture"; -import { extractLabelValue } from "@/models/local/assignment/utils/markdownUtils"; -import { getDateOnlyMarkdownString } from "@/models/local/timeUtils"; +import { getDayOfWeek, LocalCourseSettings } from "@/models/local/localCourse"; +import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils"; +import { getDateFromStringOrThrow } from "@/models/local/timeUtils"; export async function getLectures(courseName: string) { - const courseLectureRoot = path.join(basePath, courseName, "lectures"); + const courseLectureRoot = path.join(basePath, courseName, lectureFolderName); if (!(await directoryExists(courseLectureRoot))) { return []; } @@ -39,30 +45,36 @@ export async function getLectures(courseName: string) { return lecturesByWeek; } -export function parseLecture(fileContent: string): Lecture { - try { - const settings = fileContent.split("---\n")[0]; - const name = extractLabelValue(settings, "Name"); - const date = extractLabelValue(settings, "Date"); +export async function updateLecture( + courseName: string, + courseSettings: LocalCourseSettings, + lecture: Lecture +) { + const courseLectureRoot = path.join(basePath, courseName, lectureFolderName); + const startDate = getDateFromStringOrThrow( + courseSettings.startDate, + "semester start date in update lecture" + ); + const lectureDate = getDateFromStringOrThrow( + lecture.date, + "lecture start date in update lecture" + ); + const weekNumber = getWeekNumber(startDate, lectureDate) + .toString() + .padStart(2, "0"); - const content = fileContent.split("---\n")[1].trim(); - - return { - name, - date, - content, - }; - } catch (error) { - console.error("Error parsing lecture", fileContent); - throw error; + const weekFolderName = `week-${weekNumber}`; + const weekPath = path.join(courseLectureRoot, weekFolderName); + if (!(await directoryExists(weekPath))) { + await fs.mkdir(weekPath, { recursive: true }); } -} -export function lectureToString(lecture: Lecture) { - return `Name: ${lecture.name} -Date: ${lecture.date} ---- -${lecture.content}`; + const lecturePath = path.join( + weekPath, + `${lectureDate.getDay()}-${getDayOfWeek(lectureDate)}.md` + ); + const lectureContents = lectureToString(lecture); + await fs.writeFile(lecturePath, lectureContents); } const directoryExists = async (path: string): Promise => { diff --git a/nextjs/src/services/fileStorage/moduleFileStorageService.ts b/nextjs/src/services/fileStorage/moduleFileStorageService.ts index f014017..ba6dc8a 100644 --- a/nextjs/src/services/fileStorage/moduleFileStorageService.ts +++ b/nextjs/src/services/fileStorage/moduleFileStorageService.ts @@ -1,6 +1,7 @@ import { promises as fs } from "fs"; import path from "path"; import { basePath } from "./utils/fileSystemUtils"; +import { lectureFolderName } from "./utils/lectureUtils"; export const moduleFileStorageService = { async getModuleNames(courseName: string) { @@ -14,9 +15,10 @@ export const moduleFileStorageService = { .map((dirent) => dirent.name); const modules = await Promise.all(modulePromises); - return modules - .filter((m) => m !== "lectures") - .sort((a, b) => a.localeCompare(b)); + const modulesWithoutLectures = modules.filter( + (m) => m !== lectureFolderName + ); + return modulesWithoutLectures.sort((a, b) => a.localeCompare(b)); }, async createModule(courseName: string, moduleName: string) { const courseDirectory = path.join(basePath, courseName); diff --git a/nextjs/src/services/fileStorage/utils/courseMarkdownLoader.ts b/nextjs/src/services/fileStorage/utils/courseMarkdownLoader.ts deleted file mode 100644 index be472b1..0000000 --- a/nextjs/src/services/fileStorage/utils/courseMarkdownLoader.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { - LocalAssignment, - localAssignmentMarkdown, -} from "@/models/local/assignment/localAssignment"; -import { - LocalCourse, - LocalCourseSettings, - localCourseYamlUtils, -} from "@/models/local/localCourse"; -import { LocalModule } from "@/models/local/localModules"; -import { - LocalCoursePage, - localPageMarkdownUtils, -} from "@/models/local/page/localCoursePage"; -import { - LocalQuiz, - localQuizMarkdownUtils, -} from "@/models/local/quiz/localQuiz"; -import { promises as fs } from "fs"; -import path from "path"; -import { directoryOrFileExists } from "./fileSystemUtils"; - -const basePath = process.env.STORAGE_DIRECTORY ?? "./storage"; - -export const courseMarkdownLoader = { - // async loadSavedCourses(): Promise { - // const courseDirectories = await fs.readdir(basePath, { - // withFileTypes: true, - // }); - // const coursePromises = courseDirectories - // .filter((dirent) => dirent.isDirectory()) - // .map(async (dirent) => { - // const coursePath = path.join(basePath, dirent.name); - // const settingsPath = path.join(coursePath, "settings.yml"); - // if (await directoryOrFileExists(settingsPath)) { - // return this.loadCourseByPath(coursePath); - // } - // return null; - // }); - - // const courses = (await Promise.all(coursePromises)).filter( - // (course) => course !== null - // ) as LocalCourse[]; - // return courses.sort((a, b) => - // a.settings.name.localeCompare(b.settings.name) - // ); - // }, - - // async loadCourseByPath(courseDirectory: string): Promise { - // if (!(await directoryOrFileExists(courseDirectory))) { - // const errorMessage = `Error loading course by name, could not find folder ${courseDirectory}`; - // console.log(errorMessage); - // throw new Error(errorMessage); - // } - - // const settings = await this.loadCourseSettings(courseDirectory); - // const modules = await this.loadCourseModules(courseDirectory); - - // return { - // settings, - // modules, - // }; - // }, - - // async loadCourseSettings( - // courseDirectory: string - // ): Promise { - // const settingsPath = path.join(courseDirectory, "settings.yml"); - // if (!(await directoryOrFileExists(settingsPath))) { - // const errorMessage = `Error loading course by name, settings file ${settingsPath}`; - // console.log(errorMessage); - // throw new Error(errorMessage); - // } - - // const settingsString = await fs.readFile(settingsPath, "utf-8"); - // const settings = localCourseYamlUtils.parseSettingYaml(settingsString); - - // const folderName = path.basename(courseDirectory); - // return { ...settings, name: folderName }; - // }, - - // async loadCourseModules(courseDirectory: string): Promise { - // const moduleDirectories = await fs.readdir(courseDirectory, { - // withFileTypes: true, - // }); - // const modulePromises = moduleDirectories - // .filter((dirent) => dirent.isDirectory()) - // .map((dirent) => - // this.loadModuleFromPath(path.join(courseDirectory, dirent.name)) - // ); - - // const modules = await Promise.all(modulePromises); - // return modules.sort((a, b) => a.name.localeCompare(b.name)); - // }, - - // async loadModuleFromPath(modulePath: string): Promise { - // const moduleName = path.basename(modulePath); - // const assignments = await this.loadAssignmentsFromPath(modulePath); - // const quizzes = await this.loadQuizzesFromPath(modulePath); - // const pages = await this.loadModulePagesFromPath(modulePath); - - // return { - // name: moduleName, - // assignments, - // quizzes, - // pages, - // }; - // }, - - // async loadAssignmentsFromPath( - // modulePath: string - // ): Promise { - // const assignmentsPath = path.join(modulePath, "assignments"); - // if (!(await directoryOrFileExists(assignmentsPath))) { - // console.log( - // `Error loading course by name, assignments folder does not exist in ${modulePath}` - // ); - // await fs.mkdir(assignmentsPath); - // } - - // const assignmentFiles = await fs.readdir(assignmentsPath); - // const assignmentPromises = assignmentFiles.map(async (file) => { - // const filePath = path.join(assignmentsPath, file); - // const rawFile = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localAssignmentMarkdown.parseMarkdown(rawFile); - // }); - - // return await Promise.all(assignmentPromises); - // }, - - // async loadQuizzesFromPath(modulePath: string): Promise { - // const quizzesPath = path.join(modulePath, "quizzes"); - // if (!(await directoryOrFileExists(quizzesPath))) { - // console.log( - // `Quizzes folder does not exist in ${modulePath}, creating now` - // ); - // await fs.mkdir(quizzesPath); - // } - - // const quizFiles = await fs.readdir(quizzesPath); - // const quizPromises = quizFiles.map(async (file) => { - // const filePath = path.join(quizzesPath, file); - // const rawQuiz = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localQuizMarkdownUtils.parseMarkdown(rawQuiz); - // }); - - // return await Promise.all(quizPromises); - // }, - - // async loadModulePagesFromPath( - // modulePath: string - // ): Promise { - // const pagesPath = path.join(modulePath, "pages"); - // if (!(await directoryOrFileExists(pagesPath))) { - // console.log(`Pages folder does not exist in ${modulePath}, creating now`); - // await fs.mkdir(pagesPath); - // } - - // const pageFiles = await fs.readdir(pagesPath); - // const pagePromises = pageFiles.map(async (file) => { - // const filePath = path.join(pagesPath, file); - // const rawPage = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localPageMarkdownUtils.parseMarkdown(rawPage); - // }); - - // return await Promise.all(pagePromises); - // }, -}; diff --git a/nextjs/src/services/fileStorage/utils/courseMarkdownSaver.ts b/nextjs/src/services/fileStorage/utils/courseMarkdownSaver.ts deleted file mode 100644 index cd24710..0000000 --- a/nextjs/src/services/fileStorage/utils/courseMarkdownSaver.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { localAssignmentMarkdown } from "@/models/local/assignment/localAssignment"; -import { LocalCourse, localCourseYamlUtils } from "@/models/local/localCourse"; -import { LocalModule } from "@/models/local/localModules"; -import { localPageMarkdownUtils } from "@/models/local/page/localCoursePage"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { promises as fs } from "fs"; -import path from "path"; - -const basePath = process.env.STORAGE_DIRECTORY ?? "./storage"; - -const directoryExists = async (directoryPath: string): Promise => { - try { - await fs.access(directoryPath); - return true; - } catch { - return false; - } -}; - -const saveSettings = async (course: LocalCourse, courseDirectory: string) => { - const settingsFilePath = path.join(courseDirectory, "settings.yml"); - const settingsYaml = localCourseYamlUtils.settingsToYaml(course.settings); - await fs.writeFile(settingsFilePath, settingsYaml); -}; - -// const saveModules = async ( -// course: LocalCourse, -// courseDirectory: string, -// previouslyStoredCourse?: LocalCourse -// ) => { -// for (const localModule of course.modules) { -// const moduleDirectory = path.join(courseDirectory, localModule.name); -// if (!(await directoryExists(moduleDirectory))) { -// await fs.mkdir(moduleDirectory, { recursive: true }); -// } - -// await saveQuizzes(course, localModule, previouslyStoredCourse); -// await saveAssignments(course, localModule, previouslyStoredCourse); -// await savePages(course, localModule, previouslyStoredCourse); -// } - -// const moduleNames = course.modules.map((m) => m.name); -// const moduleDirectories = await fs.readdir(courseDirectory, { -// withFileTypes: true, -// }); - -// for (const dirent of moduleDirectories) { -// if (dirent.isDirectory() && !moduleNames.includes(dirent.name)) { -// const moduleDirPath = path.join(courseDirectory, dirent.name); -// console.log( -// `Deleting extra module directory, it was probably renamed ${moduleDirPath}` -// ); -// await fs.rmdir(moduleDirPath, { recursive: true }); -// } -// } -// }; - -// const saveQuizzes = async ( -// course: LocalCourse, -// module: LocalModule, -// previouslyStoredCourse?: LocalCourse -// ) => { -// const quizzesDirectory = path.join( -// basePath, -// course.settings.name, -// module.name, -// "quizzes" -// ); -// if (!(await directoryExists(quizzesDirectory))) { -// await fs.mkdir(quizzesDirectory, { recursive: true }); -// } - -// for (const quiz of module.quizzes) { -// const previousModule = previouslyStoredCourse?.modules.find( -// (m) => m.name === module.name -// ); -// const previousQuiz = previousModule?.quizzes.find((q) => q === quiz); - -// if (!previousQuiz) { -// const markdownPath = path.join(quizzesDirectory, `${quiz.name}.md`); -// const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); -// console.log(`Saving quiz ${markdownPath}`); -// await fs.writeFile(markdownPath, quizMarkdown); -// } -// } - -// await removeOldQuizzes(quizzesDirectory, module); -// }; - -const saveAssignments = async ( - course: LocalCourse, - module: LocalModule, - previouslyStoredCourse?: LocalCourse -) => { - const assignmentsDirectory = path.join( - basePath, - course.settings.name, - module.name, - "assignments" - ); - if (!(await directoryExists(assignmentsDirectory))) { - await fs.mkdir(assignmentsDirectory, { recursive: true }); - } - - for (const assignment of module.assignments) { - const previousModule = previouslyStoredCourse?.modules.find( - (m) => m.name === module.name - ); - const previousAssignment = previousModule?.assignments.find( - (a) => a === assignment - ); - - if (!previousAssignment) { - const assignmentMarkdown = localAssignmentMarkdown.toMarkdown(assignment); - const filePath = path.join(assignmentsDirectory, `${assignment.name}.md`); - console.log(`Saving assignment ${filePath}`); - await fs.writeFile(filePath, assignmentMarkdown); - } - } - - await removeOldAssignments(assignmentsDirectory, module); -}; - -const savePages = async ( - course: LocalCourse, - module: LocalModule, - previouslyStoredCourse?: LocalCourse -) => { - const pagesDirectory = path.join( - basePath, - course.settings.name, - module.name, - "pages" - ); - if (!(await directoryExists(pagesDirectory))) { - await fs.mkdir(pagesDirectory, { recursive: true }); - } - - for (const page of module.pages) { - const previousModule = previouslyStoredCourse?.modules.find( - (m) => m.name === module.name - ); - const previousPage = previousModule?.pages.find((p) => p === page); - - if (!previousPage) { - const pageMarkdown = localPageMarkdownUtils.toMarkdown(page); - const filePath = path.join(pagesDirectory, `${page.name}.md`); - console.log(`Saving page ${filePath}`); - await fs.writeFile(filePath, pageMarkdown); - } - } - - await removeOldPages(pagesDirectory, module); -}; - -const removeOldQuizzes = async ( - quizzesDirectory: string, - module: LocalModule -) => { - const existingFiles = await fs.readdir(quizzesDirectory); - const quizFilesToDelete = existingFiles.filter((file) => { - const quizMarkdownPath = path.join( - quizzesDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.quizzes.some( - (quiz) => - path.join(quizzesDirectory, `${quiz.name}.md`) === quizMarkdownPath - ); - }); - - for (const file of quizFilesToDelete) { - console.log( - `Removing old quiz, it has probably been renamed ${path.join( - quizzesDirectory, - file - )}` - ); - await fs.unlink(path.join(quizzesDirectory, file)); - } -}; - -const removeOldAssignments = async ( - assignmentsDirectory: string, - module: LocalModule -) => { - const existingFiles = await fs.readdir(assignmentsDirectory); - const assignmentFilesToDelete = existingFiles.filter((file) => { - const assignmentMarkdownPath = path.join( - assignmentsDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.assignments.some( - (assignment) => - path.join(assignmentsDirectory, `${assignment.name}.md`) === - assignmentMarkdownPath - ); - }); - - for (const file of assignmentFilesToDelete) { - console.log( - `Removing old assignment, it has probably been renamed ${path.join( - assignmentsDirectory, - file - )}` - ); - await fs.unlink(path.join(assignmentsDirectory, file)); - } -}; - -const removeOldPages = async (pagesDirectory: string, module: LocalModule) => { - const existingFiles = await fs.readdir(pagesDirectory); - const pageFilesToDelete = existingFiles.filter((file) => { - const pageMarkdownPath = path.join( - pagesDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.pages.some( - (page) => - path.join(pagesDirectory, `${page.name}.md`) === pageMarkdownPath - ); - }); - - for (const file of pageFilesToDelete) { - console.log( - `Removing old page, it has probably been renamed ${path.join( - pagesDirectory, - file - )}` - ); - await fs.unlink(path.join(pagesDirectory, file)); - } -}; - -// export const courseMarkdownSaver = { -// async save(course: LocalCourse, previouslyStoredCourse?: LocalCourse) { -// const courseDirectory = path.join(basePath, course.settings.name); -// if (!(await directoryExists(courseDirectory))) { -// await fs.mkdir(courseDirectory, { recursive: true }); -// } - -// await saveSettings(course, courseDirectory); -// await saveModules(course, courseDirectory, previouslyStoredCourse); -// }, -// }; diff --git a/nextjs/src/services/fileStorage/utils/lectureUtils.ts b/nextjs/src/services/fileStorage/utils/lectureUtils.ts new file mode 100644 index 0000000..fb38761 --- /dev/null +++ b/nextjs/src/services/fileStorage/utils/lectureUtils.ts @@ -0,0 +1,30 @@ +import { extractLabelValue } from "@/models/local/assignment/utils/markdownUtils"; +import { Lecture } from "@/models/local/lecture"; + +export function parseLecture(fileContent: string): Lecture { + try { + const settings = fileContent.split("---\n")[0]; + const name = extractLabelValue(settings, "Name"); + const date = extractLabelValue(settings, "Date"); + + const content = fileContent.split("---\n")[1].trim(); + + return { + name, + date, + content, + }; + } catch (error) { + console.error("Error parsing lecture", fileContent); + throw error; + } +} + +export function lectureToString(lecture: Lecture) { + return `Name: ${lecture.name} +Date: ${lecture.date} +--- +${lecture.content}`; +} + +export const lectureFolderName = "00 - lectures" \ No newline at end of file diff --git a/nextjs/src/services/tests/lectureStorage.test.ts b/nextjs/src/services/tests/lectureStorage.test.ts index 6792023..18963dd 100644 --- a/nextjs/src/services/tests/lectureStorage.test.ts +++ b/nextjs/src/services/tests/lectureStorage.test.ts @@ -1,8 +1,6 @@ import { describe, expect, it } from "vitest"; -import { - lectureToString, - parseLecture, -} from "../fileStorage/lectureFileStorageService"; +import { lectureToString } from "../fileStorage/utils/lectureUtils"; +import { parseLecture } from "../fileStorage/utils/lectureUtils"; import { Lecture } from "@/models/local/lecture"; describe("can parse and stringify lectures", () => {