more refactoring by feature

This commit is contained in:
2025-07-23 09:46:35 -06:00
parent d5a40e52d9
commit 3e371247d6
92 changed files with 159 additions and 158 deletions

View File

@@ -1,5 +1,5 @@
"use client";
import { useLocalCoursesSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCoursesSettingsQuery } from "@/features/local/course/localCoursesHooks";
import {
getDateKey,
getTermName,

View File

@@ -11,17 +11,14 @@ import { useCanvasTermsQuery } from "@/hooks/canvas/canvasHooks";
import {
useCreateLocalCourseMutation,
useLocalCoursesSettingsQuery,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import {
DayOfWeek,
LocalCourseSettings,
} from "@/models/local/localCourseSettings";
import { getCourseUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation";
import React, { Dispatch, SetStateAction, useMemo, useState } from "react";
import { DayOfWeek, LocalCourseSettings } from "@/features/local/course/localCourseSettings";
const sampleCompose = `services:
canvas_manager:

View File

@@ -17,7 +17,7 @@ import {
canvasQuizKeys,
useCanvasQuizzesQuery,
} from "@/hooks/canvas/canvasQuizHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { useQueryClient } from "@tanstack/react-query";
import Link from "next/link";

View File

@@ -1,6 +1,6 @@
"use client";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import Link from "next/link";
import { useCourseContext } from "./context/courseContext";
import { getCourseSettingsUrl } from "@/services/urlUtils";

View File

@@ -1,12 +1,12 @@
"use client";
import { CalendarMonthModel, getWeekNumber } from "./calendarMonthUtils";
import { DayOfWeek } from "@/models/local/localCourseSettings";
import { Expandable } from "@/components/Expandable";
import { CalendarWeek } from "./CalendarWeek";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import UpChevron from "@/components/icons/UpChevron";
import DownChevron from "@/components/icons/DownChevron";
import { DayOfWeek } from "@/features/local/course/localCourseSettings";
export const CalendarMonth = ({ month }: { month: CalendarMonthModel }) => {
// const weekInMilliseconds = 604_800_000;

View File

@@ -1,5 +1,5 @@
"use client";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import { getWeekNumber } from "./calendarMonthUtils";
import Day from "./day/Day";

View File

@@ -2,7 +2,7 @@
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import { getMonthsBetweenDates } from "./calendarMonthUtils";
import { CalendarMonth } from "./CalendarMonth";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { useEffect, useMemo, useRef } from "react";
import CalendarItemsContextProvider from "../context/CalendarItemsContextProvider";

View File

@@ -4,11 +4,11 @@ import {
getDateOnlyMarkdownString,
} from "@/models/local/utils/timeUtils";
import { useDraggingContext } from "../../context/drag/draggingContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { getDayOfWeek } from "@/models/local/localCourseSettings";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { ItemInDay } from "./ItemInDay";
import { useTodaysItems } from "./useTodaysItems";
import { DayTitle } from "./DayTitle";
import { getDayOfWeek } from "@/features/local/course/localCourseSettings";
export default function Day({ day, month }: { day: string; month: number }) {
const dayAsDate = getDateFromStringOrThrow(

View File

@@ -6,7 +6,7 @@ import NewItemForm from "../../modules/NewItemForm";
import { DraggableItem } from "../../context/drag/draggingContext";
import { useDragStyleContext } from "../../context/drag/dragStyleContext";
import { getLectureForDay } from "@/models/local/utils/lectureUtils";
import { useLecturesSuspenseQuery } from "@/hooks/localCourse/lectureHooks";
import { useLecturesSuspenseQuery } from "@/features/local/lectures/lectureHooks";
import ClientOnly from "@/components/ClientOnly";
import { Tooltip } from "@/components/Tooltip";
import { useRef, useState } from "react";

View File

@@ -1,4 +1,4 @@
import { IModuleItem } from "@/models/local/IModuleItem";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
import { getModuleItemUrl } from "@/services/urlUtils";
import Link from "next/link";
import { ReactNode, useRef, useState } from "react";

View File

@@ -3,7 +3,6 @@ import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment";
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel";
import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import {
dateToMarkdownString,
getDateFromStringOrThrow,
@@ -13,6 +12,7 @@ import { htmlIsCloseEnough } from "@/services/utils/htmlIsCloseEnough";
import { ReactNode } from "react";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const getStatus = ({
item,

View File

@@ -10,7 +10,7 @@ import {
import { ReactNode } from "react";
import { useCalendarItemsContext } from "../../context/calendarItemsContext";
import { getStatus } from "./getStatus";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";

View File

@@ -8,7 +8,7 @@ import {
useCourseQuizzesByModuleByDateQuery,
useCourseAssignmentsByModuleByDateQuery,
useCoursePagesByModuleByDateQuery,
} from "@/hooks/localCourse/localCourseModuleHooks";
} from "@/features/local/modules/localCourseModuleHooks";
export default function CalendarItemsContextProvider({
children,

View File

@@ -1,5 +1,5 @@
"use client";
import { IModuleItem } from "@/models/local/IModuleItem";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
import { createContext, useContext, DragEvent } from "react";
export interface DraggableItem {

View File

@@ -2,11 +2,11 @@
import {
useLecturesSuspenseQuery,
useLectureUpdateMutation,
} from "@/hooks/localCourse/lectureHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/lectures/lectureHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { useUpdatePageMutation } from "@/features/local/pages/pageHooks";
import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { Lecture } from "@/models/local/lecture";
import { Lecture } from "@/features/local/lectures/lectureModel";
import { getLectureForDay } from "@/models/local/utils/lectureUtils";
import {
getDateFromStringOrThrow,
@@ -16,7 +16,7 @@ import {
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
import { DraggableItem } from "./draggingContext";
import { getNewLockDate } from "./getNewLockDate";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useUpdateQuizMutation } from "@/features/local/quizzes/quizHooks";
import { useCourseContext } from "../courseContext";
import { useUpdateAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";

View File

@@ -4,7 +4,7 @@ import { LocalAssignment } from "@/features/local/assignments/models/localAssign
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
import { DraggableItem } from "./draggingContext";
import { useCourseContext } from "../courseContext";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useUpdateQuizMutation } from "@/features/local/quizzes/quizHooks";
import { useUpdateAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";

View File

@@ -3,7 +3,7 @@ import { MonacoEditor } from "@/components/editor/MonacoEditor";
import {
useLecturesSuspenseQuery,
useLectureUpdateMutation,
} from "@/hooks/localCourse/lectureHooks";
} from "@/features/local/lectures/lectureHooks";
import {
lectureToString,
parseLecture,
@@ -13,8 +13,8 @@ import LecturePreview from "./LecturePreview";
import EditLectureTitle from "./EditLectureTitle";
import LectureButtons from "./LectureButtons";
import { useCourseContext } from "../../context/courseContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { Lecture } from "@/models/local/lecture";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { Lecture } from "@/features/local/lectures/lectureModel";
import { useAuthoritativeUpdates } from "../../utils/useAuthoritativeUpdates";
import { EditLayout } from "@/components/EditLayout";

View File

@@ -1,10 +1,10 @@
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { getDayOfWeek } from "@/models/local/localCourseSettings";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { getDateFromString } from "@/models/local/utils/timeUtils";
import { getLectureWeekName } from "@/services/fileStorage/utils/lectureUtils";
import { getCourseUrl, getLecturePreviewUrl } from "@/services/urlUtils";
import { useCourseContext } from "../../context/courseContext";
import Link from "next/link";
import { getDayOfWeek } from "@/features/local/course/localCourseSettings";
export default function EditLectureTitle({
lectureDay,

View File

@@ -6,8 +6,8 @@ import { getCourseUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useCourseContext } from "../../context/courseContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useDeleteLectureMutation } from "@/hooks/localCourse/lectureHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { useDeleteLectureMutation } from "@/features/local/lectures/lectureHooks";
import Link from "next/link";
export default function LectureButtons({ lectureDay }: { lectureDay: string }) {

View File

@@ -1,5 +1,5 @@
import MarkdownDisplay from "@/components/MarkdownDisplay";
import { Lecture } from "@/models/local/lecture";
import { Lecture } from "@/features/local/lectures/lectureModel";
export default function LecturePreview({ lecture }: { lecture: Lecture }) {
return (

View File

@@ -4,7 +4,7 @@ import LecturePreview from "../LecturePreview";
import { getCourseUrl, getLectureUrl } from "@/services/urlUtils";
import { useCourseContext } from "../../../context/courseContext";
import Link from "next/link";
import { useLecturesSuspenseQuery } from "@/hooks/localCourse/lectureHooks";
import { useLecturesSuspenseQuery } from "@/features/local/lectures/lectureHooks";
export default function LecturePreviewPage({
lectureDay,

View File

@@ -1,6 +1,6 @@
import { Expandable } from "@/components/Expandable";
import TextInput from "@/components/form/TextInput";
import { useCreateModuleMutation } from "@/hooks/localCourse/localCourseModuleHooks";
import { useCreateModuleMutation } from "@/features/local/modules/localCourseModuleHooks";
import React, { useState } from "react";
import { useCourseContext } from "../context/courseContext";

View File

@@ -1,6 +1,6 @@
"use client";
import { usePagesQueries } from "@/features/local/pages/pageHooks";
import { IModuleItem } from "@/models/local/IModuleItem";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
import {
getDateFromString,
getDateFromStringOrThrow,
@@ -21,7 +21,7 @@ import { getModuleItemUrl } from "@/services/urlUtils";
import { useCourseContext } from "../context/courseContext";
import { Expandable } from "../../../../components/Expandable";
import { useDragStyleContext } from "../context/drag/dragStyleContext";
import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks";
import { useQuizzesQueries } from "@/features/local/quizzes/quizHooks";
import { useTRPC } from "@/services/serverFunctions/trpcClient";
import { useSuspenseQueries } from "@tanstack/react-query";
import { useAssignmentNamesQuery } from "@/features/local/assignments/assignmentHooks";

View File

@@ -1,5 +1,5 @@
"use client";
import { useModuleNamesQuery } from "@/hooks/localCourse/localCourseModuleHooks";
import { useModuleNamesQuery } from "@/features/local/modules/localCourseModuleHooks";
import ExpandableModule from "./ExpandableModule";
import CreateModule from "./CreateModule";

View File

@@ -3,14 +3,14 @@ import ButtonSelect from "@/components/ButtonSelect";
import SelectInput from "@/components/form/SelectInput";
import TextInput from "@/components/form/TextInput";
import { Spinner } from "@/components/Spinner";
import { useModuleNamesQuery } from "@/hooks/localCourse/localCourseModuleHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useModuleNamesQuery } from "@/features/local/modules/localCourseModuleHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { useCreatePageMutation } from "@/features/local/pages/pageHooks";
import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import React, { useState } from "react";
import { useCourseContext } from "../context/courseContext";
import { useCreateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useCreateQuizMutation } from "@/features/local/quizzes/quizHooks";
import {
getDateFromString,
dateToMarkdownString,

View File

@@ -1,14 +1,17 @@
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import Modal, { useModal } from "@/components/Modal";
import { Spinner } from "@/components/Spinner";
import { useAssignmentQuery, useDeleteAssignmentMutation } from "@/features/local/assignments/assignmentHooks";
import {
useAssignmentQuery,
useDeleteAssignmentMutation,
} from "@/features/local/assignments/assignmentHooks";
import {
useCanvasAssignmentsQuery,
useAddAssignmentToCanvasMutation,
useDeleteAssignmentFromCanvasMutation,
useUpdateAssignmentInCanvasMutation,
} from "@/hooks/canvas/canvasAssignmentHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
import { getCourseUrl } from "@/services/urlUtils";
import Link from "next/link";

View File

@@ -7,7 +7,7 @@ import {
import { useEffect, useState } from "react";
import AssignmentPreview from "./AssignmentPreview";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import ClientOnly from "@/components/ClientOnly";
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
import { useRouter } from "next/navigation";

View File

@@ -1,6 +1,6 @@
"use client";
import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export function getAssignmentHelpString(settings: LocalCourseSettings) {
const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- ");

View File

@@ -2,7 +2,7 @@
import { MonacoEditor } from "@/components/editor/MonacoEditor";
import { useEffect, useState } from "react";
import PagePreview from "./PagePreview";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import EditPageButtons from "./EditPageButtons";
import ClientOnly from "@/components/ClientOnly";
import { useRouter } from "next/navigation";

View File

@@ -7,7 +7,7 @@ import {
useDeleteCanvasPageMutation,
useUpdateCanvasPageMutation,
} from "@/hooks/canvas/canvasPageHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import {
useDeletePageMutation,
usePageQuery,

View File

@@ -10,14 +10,14 @@ import { useCourseContext } from "@/app/course/[courseName]/context/courseContex
import {
useQuizQuery,
useUpdateQuizMutation,
} from "@/hooks/localCourse/quizHooks";
} from "@/features/local/quizzes/quizHooks";
import { useAuthoritativeUpdates } from "../../../../utils/useAuthoritativeUpdates";
import { extractLabelValue } from "@/features/local/assignments/models/utils/markdownUtils";
import EditQuizHeader from "./EditQuizHeader";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { EditLayout } from "@/components/EditLayout";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
const helpString = (settings: LocalCourseSettings) => {
const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- ");

View File

@@ -6,11 +6,11 @@ import {
useAddQuizToCanvasMutation,
useDeleteQuizFromCanvasMutation,
} from "@/hooks/canvas/canvasQuizHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import {
useDeleteQuizMutation,
useQuizQuery,
} from "@/hooks/localCourse/quizHooks";
} from "@/features/local/quizzes/quizHooks";
import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
import { getCourseUrl } from "@/services/urlUtils";
import Link from "next/link";

View File

@@ -1,7 +1,10 @@
import CheckIcon from "@/components/icons/CheckIcon";
import MarkdownDisplay from "@/components/MarkdownDisplay";
import { LocalQuizQuestion, QuestionType } from "@/features/local/quizzes/models/localQuizQuestion";
import { useQuizQuery } from "@/hooks/localCourse/quizHooks";
import {
LocalQuizQuestion,
QuestionType,
} from "@/features/local/quizzes/models/localQuizQuestion";
import { useQuizQuery } from "@/features/local/quizzes/quizHooks";
import { escapeMatchingText } from "@/services/utils/questionHtmlUtils";
export default function QuizPreview({

View File

@@ -5,7 +5,7 @@ import { Spinner } from "@/components/Spinner";
import {
useQuizQuery,
useUpdateQuizMutation,
} from "@/hooks/localCourse/quizHooks";
} from "@/features/local/quizzes/quizHooks";
import { getModuleItemUrl } from "@/services/urlUtils";
import { useRouter } from "next/navigation";
import { useState } from "react";

View File

@@ -3,7 +3,7 @@
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import { useEffect, useState } from "react";
import TextInput from "../../../../components/form/TextInput";

View File

@@ -4,7 +4,7 @@ import { Spinner } from "@/components/Spinner";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import React from "react";
export default function DaysOfWeekSettings() {

View File

@@ -3,7 +3,7 @@
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { TimePicker } from "../../../../components/TimePicker";
import { useState } from "react";
import DefaultLockOffset from "./DefaultLockOffset";

View File

@@ -3,7 +3,7 @@ import TextInput from "@/components/form/TextInput";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { useState, useEffect } from "react";
import { settingsBox } from "./sharedSettings";

View File

@@ -4,7 +4,7 @@ import TextInput from "@/components/form/TextInput";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { useEffect, useState } from "react";
export default function DefaultLockOffset() {

View File

@@ -1,5 +1,5 @@
"use client";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { settingsBox } from "./sharedSettings";
import { useCourseStudentsQuery } from "@/hooks/canvas/canvasCourseHooks";
import { Spinner } from "@/components/Spinner";

View File

@@ -5,7 +5,7 @@ import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling"
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import { getDateFromString } from "@/models/local/utils/timeUtils";
import { useEffect, useState } from "react";
import {

View File

@@ -1,5 +1,5 @@
"use client";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { getCourseUrl } from "@/services/urlUtils";
import Link from "next/link";
import React from "react";

View File

@@ -1,5 +1,5 @@
"use client";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { getDateOnlyMarkdownString } from "@/models/local/utils/timeUtils";
import React from "react";
import { settingsBox } from "./sharedSettings";

View File

@@ -3,7 +3,7 @@ import SelectInput from "@/components/form/SelectInput";
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
import {
AssignmentSubmissionType,
AssignmentSubmissionTypeList,

View File

@@ -3,7 +3,7 @@
import { getLecturePreviewUrl } from "@/services/urlUtils";
import Link from "next/link";
import { useCourseContext } from "../course/[courseName]/context/courseContext";
import { useLecturesSuspenseQuery as useLecturesQuery } from "@/hooks/localCourse/lectureHooks";
import { useLecturesSuspenseQuery as useLecturesQuery } from "@/features/local/lectures/lectureHooks";
import { getLectureForDay } from "@/models/local/utils/lectureUtils";
import { getDateOnlyMarkdownString } from "@/models/local/utils/timeUtils";

View File

@@ -1,6 +1,6 @@
"use client";
import { useLocalCoursesSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCoursesSettingsQuery } from "@/features/local/course/localCoursesHooks";
import OneCourseLectures from "./OneCourseLectures";
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
import CourseContextProvider from "../course/[courseName]/context/CourseContextProvider";

View File

@@ -1,7 +1,7 @@
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "@/features/local/course/localCoursesHooks";
import { SuspenseAndErrorHandling } from "./SuspenseAndErrorHandling";
import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export default function MarkdownDisplay({
markdown,

View File

@@ -1,5 +1,5 @@
"use client";
import { SimpleTimeOnly } from "@/models/local/localCourseSettings";
import { SimpleTimeOnly } from "@/features/local/course/localCourseSettings";
import { FC } from "react";
export const TimePicker: FC<{

View File

@@ -1,4 +1,4 @@
import { DayOfWeek } from "@/models/local/localCourseSettings";
import { DayOfWeek } from "@/features/local/course/localCourseSettings";
export function DayOfWeekInput({
selectedDays,

View File

@@ -14,7 +14,7 @@ import {
import {
useLocalCourseSettingsQuery,
useUpdateLocalCourseSettingsMutation,
} from "@/hooks/localCourse/localCoursesHooks";
} from "@/features/local/course/localCoursesHooks";
export const useAssignmentQuery = (
moduleName: string,

View File

@@ -4,10 +4,10 @@ import {
} from "@/features/local/assignments/models/localAssignment";
import { assignmentMarkdownSerializer } from "@/features/local/assignments/models/utils/assignmentMarkdownSerializer";
import path from "path";
import { directoryOrFileExists } from "./utils/fileSystemUtils";
import { promises as fs } from "fs";
import { courseItemFileStorageService } from "./courseItemFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { courseItemFileStorageService } from "@/features/local/course/courseItemFileStorageService";
import { getCoursePathByName } from "@/services/fileStorage/globalSettingsFileStorageService";
import { directoryOrFileExists } from "@/services/fileStorage/utils/fileSystemUtils";
const getAssignmentNames = async (courseName: string, moduleName: string) => {
const courseDirectory = await getCoursePathByName(courseName);

View File

@@ -1,4 +1,4 @@
import { IModuleItem } from "../../../../models/local/IModuleItem";
import { IModuleItem } from "../../modules/IModuleItem";
import {
AssignmentSubmissionType,
zodAssignmentSubmissionType,

View File

@@ -1,5 +1,5 @@
import path from "path";
import { directoryOrFileExists } from "./utils/fileSystemUtils";
import { directoryOrFileExists } from "../../../services/fileStorage/utils/fileSystemUtils";
import fs from "fs/promises";
import {
LocalAssignment,
@@ -10,13 +10,16 @@ import {
CourseItemReturnType,
CourseItemType,
typeToFolder,
} from "@/models/local/courseItemTypes";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
} from "@/features/local/course/courseItemTypes";
import { getCoursePathByName } from "../../../services/fileStorage/globalSettingsFileStorageService";
import {
localPageMarkdownUtils,
LocalCoursePage,
} from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz, localQuizMarkdownUtils } from "@/features/local/quizzes/models/localQuiz";
import {
LocalQuiz,
localQuizMarkdownUtils,
} from "@/features/local/quizzes/models/localQuiz";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";
const getItemFileNames = async (

View File

@@ -1,5 +1,5 @@
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalAssignment } from "../../features/local/assignments/models/localAssignment";
import { LocalAssignment } from "../assignments/models/localAssignment";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export type CourseItemType = "Assignment" | "Quiz" | "Page";

View File

@@ -1,13 +1,13 @@
import { z } from "zod";
import { parse, stringify } from "yaml";
import {
AssignmentSubmissionType,
zodAssignmentSubmissionType,
} from "../../features/local/assignments/models/assignmentSubmissionType";
} from "../assignments/models/assignmentSubmissionType";
import {
LocalAssignmentGroup,
zodLocalAssignmentGroup,
} from "../../features/local/assignments/models/localAssignmentGroup";
import { parse, stringify } from "yaml";
} from "../assignments/models/localAssignmentGroup";
export interface SimpleTimeOnly {
hour: number;

View File

@@ -1,16 +1,19 @@
import {
LocalCourseSettings,
localCourseYamlUtils,
} from "@/models/local/localCourseSettings";
import { promises as fs } from "fs";
import path from "path";
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
import {
basePath,
directoryOrFileExists,
} from "../../../services/fileStorage/utils/fileSystemUtils";
import { AssignmentSubmissionType } from "@/features/local/assignments/models/assignmentSubmissionType";
import {
getCoursePathByName,
getGlobalSettings,
} from "./globalSettingsFileStorageService";
} from "../../../services/fileStorage/globalSettingsFileStorageService";
import { GlobalSettingsCourse } from "@/models/local/globalSettings";
import {
LocalCourseSettings,
localCourseYamlUtils,
} from "@/features/local/course/localCourseSettings";
const getCourseSettings = async (
course: GlobalSettingsCourse

View File

@@ -1,19 +1,15 @@
import path from "path";
import fs from "fs/promises";
import {
getLectureWeekName,
lectureFolderName,
lectureToString,
parseLecture,
} from "./utils/lectureUtils";
import { Lecture } from "@/models/local/lecture";
import {
getDayOfWeek,
LocalCourseSettings,
} from "@/models/local/localCourseSettings";
import { Lecture } from "@/features/local/lectures/lectureModel";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { getCoursePathByName } from "@/services/fileStorage/globalSettingsFileStorageService";
import {
lectureFolderName,
parseLecture,
getLectureWeekName,
lectureToString,
} from "@/services/fileStorage/utils/lectureUtils";
import { LocalCourseSettings, getDayOfWeek } from "../course/localCourseSettings";
export async function getLectures(courseName: string) {
const courseDirectory = await getCoursePathByName(courseName);
@@ -105,7 +101,7 @@ export async function deleteLecture(
await fs.access(lecturePath); // throws error if no file
await fs.unlink(lecturePath);
console.log(`File deleted: ${lecturePath}`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
if (error?.code === "ENOENT") {
console.log(`Cannot delete lecture, file does not exist: ${lecturePath}`);

View File

@@ -1,13 +1,13 @@
import { z } from "zod";
import publicProcedure from "../procedures/public";
import { router } from "../trpcSetup";
import publicProcedure from "../../../services/serverFunctions/procedures/public";
import { router } from "../../../services/serverFunctions/trpcSetup";
import { zodLecture } from "@/features/local/lectures/lectureModel";
import {
deleteLecture,
getLectures,
updateLecture,
} from "@/services/fileStorage/lectureFileStorageService";
import { zodLecture } from "@/models/local/lecture";
import { zodLocalCourseSettings } from "@/models/local/localCourseSettings";
deleteLecture,
} from "./lectureFileStorageService";
import { zodLocalCourseSettings } from "../course/localCourseSettings";
export const lectureRouter = router({
getLectures: publicProcedure

View File

@@ -1,7 +1,7 @@
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalAssignment } from "../../features/local/assignments/models/localAssignment";
import { LocalAssignment } from "../assignments/models/localAssignment";
import { IModuleItem } from "./IModuleItem";
import { getDateFromString } from "./utils/timeUtils";
import { getDateFromString } from "../../../models/local/utils/timeUtils";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
export interface LocalModule {

View File

@@ -1,6 +1,6 @@
import { promises as fs } from "fs";
import { lectureFolderName } from "./utils/lectureUtils";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { lectureFolderName } from "../../../services/fileStorage/utils/lectureUtils";
import { getCoursePathByName } from "../../../services/fileStorage/globalSettingsFileStorageService";
export const moduleFileStorageService = {
async getModuleNames(courseName: string) {

View File

@@ -1,7 +1,7 @@
import { z } from "zod";
import publicProcedure from "../procedures/public";
import { router } from "../trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { router } from "@/services/serverFunctions/trpcSetup";
import publicProcedure from "@/services/serverFunctions/procedures/public";
export const moduleRouter = router({
getModuleNames: publicProcedure

View File

@@ -1,4 +1,4 @@
import { IModuleItem } from "@/models/local/IModuleItem";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
import { verifyDateOrThrow } from "@/models/local/utils/timeUtils";
import { z } from "zod";
import { extractLabelValue } from "../assignments/models/utils/markdownUtils";

View File

@@ -1,6 +1,6 @@
import { promises as fs } from "fs";
import path from "path";
import { courseItemFileStorageService } from "../../../services/fileStorage/courseItemFileStorageService";
import { courseItemFileStorageService } from "../course/courseItemFileStorageService";
import { getCoursePathByName } from "../../../services/fileStorage/globalSettingsFileStorageService";
import {
LocalCoursePage,

View File

@@ -1,7 +1,7 @@
import { z } from "zod";
import { LocalQuizQuestion, zodLocalQuizQuestion } from "./localQuizQuestion";
import { quizMarkdownUtils } from "./utils/quizMarkdownUtils";
import { IModuleItem } from "@/models/local/IModuleItem";
import { IModuleItem } from "@/features/local/modules/IModuleItem";
export interface LocalQuiz extends IModuleItem {
name: string;

View File

@@ -1,7 +1,7 @@
import path from "path";
import { promises as fs } from "fs";
import { courseItemFileStorageService } from "./courseItemFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { courseItemFileStorageService } from "../course/courseItemFileStorageService";
import { getCoursePathByName } from "../../../services/fileStorage/globalSettingsFileStorageService";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { quizMarkdownUtils } from "@/features/local/quizzes/models/utils/quizMarkdownUtils";

View File

@@ -1,6 +1,6 @@
import publicProcedure from "../procedures/public";
import publicProcedure from "../../../services/serverFunctions/procedures/public";
import { z } from "zod";
import { router } from "../trpcSetup";
import { router } from "../../../services/serverFunctions/trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { zodLocalQuiz } from "@/features/local/quizzes/models/localQuiz";

View File

@@ -1,6 +1,6 @@
import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "../../features/local/course/localCoursesHooks";
import { LocalAssignment } from "@/features/local/assignments/models/localAssignment";
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
import {

View File

@@ -1,11 +1,11 @@
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { LocalAssignmentGroup } from "@/features/local/assignments/models/localAssignmentGroup";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
import { canvasService } from "@/services/canvas/canvasService";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useUpdateLocalCourseSettingsMutation } from "../localCourse/localCoursesHooks";
import { useUpdateLocalCourseSettingsMutation } from "../../features/local/course/localCoursesHooks";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const canvasCourseKeys = {
courseDetails: (canavasId: number) =>

View File

@@ -1,6 +1,6 @@
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "../../features/local/course/localCoursesHooks";
export const canvasCourseModuleKeys = {
modules: (canvasId: number) => ["canvas", canvasId, "module list"] as const,

View File

@@ -1,5 +1,5 @@
import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "../../features/local/course/localCoursesHooks";
import { canvasNavigationService } from "@/services/canvas/canvasNavigationService";
export const canvasCourseTabKeys = {

View File

@@ -1,7 +1,7 @@
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { canvasPageService } from "@/services/canvas/canvasPageService";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "../../features/local/course/localCoursesHooks";
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
import {
useCanvasModulesQuery,

View File

@@ -1,5 +1,5 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
import { useLocalCourseSettingsQuery } from "../../features/local/course/localCoursesHooks";
import { canvasQuizService } from "@/services/canvas/canvasQuizService";
import {
useAddCanvasModuleMutation,

View File

@@ -6,7 +6,7 @@ import {
prepPageForNewSemester,
prepQuizForNewSemester,
} from "../utils/semesterTransferUtils";
import { Lecture } from "../lecture";
import { Lecture } from "../../../features/local/lectures/lectureModel";
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";

View File

@@ -1,9 +1,11 @@
import { Lecture } from "../lecture";
import { Lecture } from "../../../features/local/lectures/lectureModel";
import { getDateOnlyMarkdownString } from "./timeUtils";
export function getLectureForDay(weeks: { weekName: string; lectures: Lecture[]; }[], dayAsDate: Date) {
export function getLectureForDay(
weeks: { weekName: string; lectures: Lecture[] }[],
dayAsDate: Date
) {
return weeks
.flatMap((w) => w.lectures)
.find((l) => l.date == getDateOnlyMarkdownString(dayAsDate));
}

View File

@@ -1,6 +1,6 @@
import { LocalCoursePage } from "@/features/local/pages/localCoursePageModels";
import { LocalAssignment } from "../../../features/local/assignments/models/localAssignment";
import { Lecture } from "../lecture";
import { Lecture } from "../../../features/local/lectures/lectureModel";
import { dateToMarkdownString, getDateFromStringOrThrow } from "./timeUtils";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";

View File

@@ -1,4 +1,4 @@
import { LocalCourseSettings } from "../localCourseSettings";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
const _getDateFromAMPM = (
datePart: string,

View File

@@ -7,7 +7,7 @@ import { CanvasRubricCreationResponse } from "@/models/canvas/assignments/canvas
import { assignmentPoints } from "@/features/local/assignments/models/utils/assignmentPointsUtils";
import { getDateFromString } from "@/models/local/utils/timeUtils";
import { getRubricCriterion } from "./canvasRubricUtils";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const canvasAssignmentService = {
async getAll(courseId: number): Promise<CanvasAssignment[]> {

View File

@@ -4,7 +4,7 @@ import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { axiosClient } from "../axiosUtils";
import { rateLimitAwareDelete } from "./canvasWebRequestor";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const canvasPageService = {
async getAll(courseId: number): Promise<CanvasPage[]> {

View File

@@ -5,10 +5,10 @@ import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
import { canvasAssignmentService } from "./canvasAssignmentService";
import { CanvasQuizQuestion } from "@/models/canvas/quizzes/canvasQuizQuestionModel";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import { escapeMatchingText } from "../utils/questionHtmlUtils";
import { LocalQuiz } from "@/features/local/quizzes/models/localQuiz";
import { LocalQuizQuestion, QuestionType } from "@/features/local/quizzes/models/localQuizQuestion";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const getAnswers = (
question: LocalQuizQuestion,

View File

@@ -1,12 +1,12 @@
import { promises as fs } from "fs";
import path from "path";
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
import { assignmentsFileStorageService } from "./assignmentsFileStorageService";
import { quizFileStorageService } from "./quizFileStorageService";
import { quizFileStorageService } from "../../features/local/quizzes/quizFileStorageService";
import { pageFileStorageService } from "../../features/local/pages/pageFileStorageService";
import { moduleFileStorageService } from "./moduleFileStorageService";
import { settingsFileStorageService } from "./settingsFileStorageService";
import { moduleFileStorageService } from "../../features/local/modules/moduleFileStorageService";
import { settingsFileStorageService } from "../../features/local/course/settingsFileStorageService";
import { getCoursePathByName } from "./globalSettingsFileStorageService";
import { assignmentsFileStorageService } from "@/features/local/assignments/assignmentsFileStorageService";
export const fileStorageService = {
settings: settingsFileStorageService,

View File

@@ -1,6 +1,6 @@
import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils";
import { extractLabelValue } from "@/features/local/assignments/models/utils/markdownUtils";
import { Lecture } from "@/models/local/lecture";
import { Lecture } from "@/features/local/lectures/lectureModel";
import { getDateFromStringOrThrow } from "@/models/local/utils/timeUtils";
export function parseLecture(fileContent: string): Lecture {

View File

@@ -1,8 +1,8 @@
"use client";
import { marked } from "marked";
import DOMPurify from "isomorphic-dompurify";
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
import markedKatex from "marked-katex-extension";
import { LocalCourseSettings } from "@/features/local/course/localCourseSettings";
const mermaidExtension = {
name: "mermaid",

View File

@@ -4,11 +4,11 @@ import { assignmentRouter } from "../../../features/local/assignments/assignment
import { canvasFileRouter } from "./canvasFileRouter";
import { directoriesRouter } from "./directoriesRouter";
import { globalSettingsRouter } from "./globalSettingsRouter";
import { lectureRouter } from "./lectureRouter";
import { moduleRouter } from "./moduleRouter";
import { lectureRouter } from "../../../features/local/lectures/lectureRouter";
import { pageRouter } from "../../../features/local/pages/pageRouter";
import { quizRouter } from "./quizRouter";
import { quizRouter } from "../../../features/local/quizzes/quizRouter";
import { settingsRouter } from "./settingsRouter";
import { moduleRouter } from "@/features/local/modules/moduleRouter";
export const trpcAppRouter = router({
assignment: assignmentRouter,

View File

@@ -2,11 +2,6 @@ import publicProcedure from "../procedures/public";
import { z } from "zod";
import { router } from "../trpcSetup";
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { zodLocalCourseSettings } from "@/models/local/localCourseSettings";
import {
getLectures,
updateLecture,
} from "@/services/fileStorage/lectureFileStorageService";
import {
prepAssignmentForNewSemester,
prepLectureForNewSemester,
@@ -17,6 +12,8 @@ import {
getGlobalSettings,
updateGlobalSettings,
} from "@/services/fileStorage/globalSettingsFileStorageService";
import { getLectures, updateLecture } from "@/features/local/lectures/lectureFileStorageService";
import { zodLocalCourseSettings } from "@/features/local/course/localCourseSettings";
export const settingsRouter = router({
allCoursesSettings: publicProcedure.query(async () => {

View File

@@ -1,10 +1,7 @@
import { describe, it, expect, beforeEach } from "vitest";
import { promises as fs } from "fs";
import {
DayOfWeek,
LocalCourseSettings,
} from "@/models/local/localCourseSettings";
import { fileStorageService } from "../fileStorage/fileStorageService";
import { LocalCourseSettings, DayOfWeek } from "@/features/local/course/localCourseSettings";
describe("FileStorageTests", () => {
beforeEach(async () => {

View File

@@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest";
import { lectureToString } from "../fileStorage/utils/lectureUtils";
import { parseLecture } from "../fileStorage/utils/lectureUtils";
import { Lecture } from "@/models/local/lecture";
import { Lecture } from "@/features/local/lectures/lectureModel";
describe("can parse and stringify lectures", () => {
it("can parse lecture", () => {