mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
redoing commit for pnpm
This commit is contained in:
@@ -17,13 +17,14 @@ const getUrl = (params: { rest: string[] }, req: NextRequest) => {
|
||||
|
||||
appendQueryParams(url, req);
|
||||
|
||||
return url;
|
||||
return url;``
|
||||
};
|
||||
|
||||
const proxyResponseHeaders = (response: any) => {
|
||||
const headers = new Headers();
|
||||
Object.entries(response.headers).forEach(([key, value]) => {
|
||||
headers.set(key, value as string);
|
||||
if (["link", "x-rate-limit-remaining"].includes(key))
|
||||
headers.set(key, value as string);
|
||||
});
|
||||
return headers;
|
||||
};
|
||||
@@ -32,21 +33,19 @@ export async function GET(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ rest: string[] }> }
|
||||
) {
|
||||
return withErrorHandling(async () => {
|
||||
try {
|
||||
const url = getUrl(await params, req);
|
||||
try {
|
||||
const url = getUrl(await params, req);
|
||||
|
||||
const response = await axiosClient.get(url.toString());
|
||||
|
||||
const headers = proxyResponseHeaders(response);
|
||||
return new NextResponse(JSON.stringify(response.data), { headers });
|
||||
} catch (error: any) {
|
||||
return new NextResponse(
|
||||
JSON.stringify({ error: error.message || "Canvas GET request failed" }),
|
||||
{ status: error.response?.status || 500 }
|
||||
);
|
||||
}
|
||||
});
|
||||
const response = await axiosClient.get(url.toString());
|
||||
const headers = proxyResponseHeaders(response);
|
||||
return NextResponse.json(response.data, { headers });
|
||||
} catch (error: any) {
|
||||
console.log("canvas get error", error, error?.message);
|
||||
return NextResponse.json(
|
||||
JSON.stringify({ error: error.message || "Canvas GET request failed" }),
|
||||
{ status: error.response?.status || 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(
|
||||
|
||||
@@ -6,11 +6,11 @@ import NewItemForm from "../../modules/NewItemForm";
|
||||
import { DraggableItem } from "../../context/drag/draggingContext";
|
||||
import { useDragStyleContext } from "../../context/drag/dragStyleContext";
|
||||
import { getLectureForDay } from "@/models/local/lectureUtils";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
import { useLecturesSuspenseQuery } from "@/hooks/localCourse/lectureHooks";
|
||||
|
||||
export function DayTitle({ day, dayAsDate }: { day: string; dayAsDate: Date }) {
|
||||
const { courseName } = useCourseContext();
|
||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||
const [weeks] = useLecturesSuspenseQuery();
|
||||
const { setIsDragging } = useDragStyleContext();
|
||||
const todaysLecture = getLectureForDay(weeks, dayAsDate);
|
||||
const modal = useModal();
|
||||
|
||||
@@ -33,7 +33,7 @@ export function useTodaysItems(day: string) {
|
||||
}[] = todaysModules
|
||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||
todaysModules[moduleName].assignments.map((assignment) => {
|
||||
const canvasAssignment = canvasAssignments.find(
|
||||
const canvasAssignment = canvasAssignments?.find(
|
||||
(c) => c.name === assignment.name
|
||||
);
|
||||
return {
|
||||
@@ -57,7 +57,7 @@ export function useTodaysItems(day: string) {
|
||||
}[] = todaysModules
|
||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||
todaysModules[moduleName].quizzes.map((quiz) => {
|
||||
const canvasQuiz = canvasQuizzes.find((q) => q.title === quiz.name);
|
||||
const canvasQuiz = canvasQuizzes?.find((q) => q.title === quiz.name);
|
||||
return {
|
||||
moduleName,
|
||||
quiz,
|
||||
@@ -79,7 +79,7 @@ export function useTodaysItems(day: string) {
|
||||
}[] = todaysModules
|
||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||
todaysModules[moduleName].pages.map((page) => {
|
||||
const canvasPage = canvasPages.find((p) => p.title === page.name);
|
||||
const canvasPage = canvasPages?.find((p) => p.title === page.name);
|
||||
return {
|
||||
moduleName,
|
||||
page,
|
||||
|
||||
@@ -18,9 +18,6 @@ export default function CalendarItemsContextProvider({
|
||||
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
||||
useAllCourseDataQuery();
|
||||
|
||||
|
||||
|
||||
|
||||
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||
(previous, { assignment, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"use client";
|
||||
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
||||
import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
||||
import {
|
||||
useLecturesSuspenseQuery,
|
||||
useLectureUpdateMutation,
|
||||
} from "@/hooks/localCourse/lectureHooks";
|
||||
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
@@ -36,9 +39,7 @@ export function useItemDropOnDay({
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const { courseName } = useCourseContext();
|
||||
// const { data: weeks } = useLecturesByWeekQuery();
|
||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({
|
||||
courseName: settings.name,
|
||||
});
|
||||
const [weeks] = useLecturesSuspenseQuery();
|
||||
const updateQuizMutation = useUpdateQuizMutation();
|
||||
const updateLectureMutation = useLectureUpdateMutation();
|
||||
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { MonacoEditor } from "@/components/editor/MonacoEditor";
|
||||
import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
||||
import { useLecturesSuspenseQuery, useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
||||
import {
|
||||
lectureToString,
|
||||
parseLecture,
|
||||
@@ -17,7 +17,7 @@ import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHoo
|
||||
export default function EditLecture({ lectureDay }: { lectureDay: string }) {
|
||||
const { courseName } = useCourseContext();
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||
const [weeks] = useLecturesSuspenseQuery();
|
||||
const updateLecture = useLectureUpdateMutation();
|
||||
|
||||
const lecture = weeks
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getCourseUrl, getLectureUrl } from "@/services/urlUtils";
|
||||
import { useCourseContext } from "../../../context/courseContext";
|
||||
import Link from "next/link";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
import { useLecturesSuspenseQuery } from "@/hooks/localCourse/lectureHooks";
|
||||
|
||||
export default function LecturePreviewPage({
|
||||
lectureDay,
|
||||
@@ -12,7 +13,7 @@ export default function LecturePreviewPage({
|
||||
lectureDay: string;
|
||||
}) {
|
||||
const { courseName } = useCourseContext();
|
||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||
const [weeks] = useLecturesSuspenseQuery();
|
||||
const lecture = weeks
|
||||
.flatMap(({ lectures }) => lectures.map((lecture) => lecture))
|
||||
.find((l) => l.date === lectureDay);
|
||||
|
||||
@@ -21,8 +21,9 @@ import { getModuleItemUrl } from "@/services/urlUtils";
|
||||
import { useCourseContext } from "../context/courseContext";
|
||||
import { Expandable } from "../../../../components/Expandable";
|
||||
import { useDragStyleContext } from "../context/drag/dragStyleContext";
|
||||
import { useAssignmentsQuery } from "@/hooks/localCourse/assignmentHooks";
|
||||
import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks";
|
||||
import { useAssignmentNamesQuery } from "@/hooks/localCourse/assignmentHooks";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
|
||||
export default function ExpandableModule({
|
||||
moduleName,
|
||||
@@ -30,8 +31,14 @@ export default function ExpandableModule({
|
||||
moduleName: string;
|
||||
}) {
|
||||
const { itemDropOnModule } = useDraggingContext();
|
||||
|
||||
const [assignments ] = useAssignmentsQuery(moduleName);
|
||||
const { courseName } = useCourseContext();
|
||||
const [assignmentNames] = useAssignmentNamesQuery(moduleName);
|
||||
|
||||
const [assignments] = trpc.useSuspenseQueries((t) =>
|
||||
assignmentNames.map((assignmentName) =>
|
||||
t.assignment.getAssignment({ courseName, moduleName, assignmentName })
|
||||
)
|
||||
);
|
||||
const [quizzes] = useQuizzesQueries(moduleName);
|
||||
const [pages] = usePagesQueries(moduleName);
|
||||
const modal = useModal();
|
||||
|
||||
@@ -10,7 +10,7 @@ export function ModuleCanvasStatus({ moduleName }: { moduleName: string }) {
|
||||
const { data: canvasModules } = useCanvasModulesQuery();
|
||||
const addToCanvas = useAddCanvasModuleMutation();
|
||||
|
||||
const canvasModule = canvasModules.find((c) => c.name === moduleName);
|
||||
const canvasModule = canvasModules?.find((c) => c.name === moduleName);
|
||||
|
||||
return (
|
||||
<div className="text-slate-400 text-end">
|
||||
|
||||
@@ -7,9 +7,9 @@ export default function ModuleList() {
|
||||
const [moduleNames] = useModuleNamesQuery();
|
||||
return (
|
||||
<div>
|
||||
{/* {moduleNames.map((m) => (
|
||||
{moduleNames.map((m) => (
|
||||
<ExpandableModule key={m} moduleName={m} />
|
||||
))} */}
|
||||
))}
|
||||
<div className="flex flex-col justify-center">
|
||||
<CreateModule />
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ export function AssignmentButtons({
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const modal = useModal();
|
||||
|
||||
const assignmentInCanvas = canvasAssignments.find(
|
||||
const assignmentInCanvas = canvasAssignments?.find(
|
||||
(a) => a.name === assignmentName
|
||||
);
|
||||
|
||||
@@ -61,7 +61,7 @@ export function AssignmentButtons({
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 justify-end">
|
||||
{anythingIsLoading && <Spinner />}
|
||||
{assignmentInCanvas && !assignmentInCanvas.published && (
|
||||
{assignmentInCanvas && !assignmentInCanvas?.published && (
|
||||
<div className="text-rose-300 my-auto">Not Published</div>
|
||||
)}
|
||||
{!assignmentInCanvas && (
|
||||
@@ -125,8 +125,8 @@ export function AssignmentButtons({
|
||||
<div className="flex justify-around gap-3">
|
||||
<button
|
||||
onClick={async () => {
|
||||
setIsLoading(true);
|
||||
router.push(getCourseUrl(courseName));
|
||||
setIsLoading(true);
|
||||
await deleteLocal.mutateAsync({
|
||||
moduleName,
|
||||
assignmentName,
|
||||
|
||||
@@ -16,7 +16,7 @@ import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
|
||||
import { getCourseUrl } from "@/services/urlUtils";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default function EditPageButtons({
|
||||
moduleName,
|
||||
@@ -35,6 +35,7 @@ export default function EditPageButtons({
|
||||
const deletePageInCanvas = useDeleteCanvasPageMutation();
|
||||
const deletePageLocal = useDeletePageMutation();
|
||||
const modal = useModal();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const pageInCanvas = canvasPages?.find((p) => p.title === pageName);
|
||||
|
||||
@@ -101,13 +102,14 @@ export default function EditPageButtons({
|
||||
<br />
|
||||
<div className="flex justify-around gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
router.push(getCourseUrl(courseName));
|
||||
deletePageLocal.mutate({
|
||||
onClick={async () => {
|
||||
setLoading(true);
|
||||
await deletePageLocal.mutateAsync({
|
||||
moduleName,
|
||||
pageName,
|
||||
courseName,
|
||||
});
|
||||
router.push(getCourseUrl(courseName));
|
||||
}}
|
||||
className="btn-danger"
|
||||
>
|
||||
@@ -115,6 +117,7 @@ export default function EditPageButtons({
|
||||
</button>
|
||||
<button onClick={closeModal}>No</button>
|
||||
</div>
|
||||
{loading && <Spinner />}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function QuizButtons({
|
||||
const deleteLocal = useDeleteQuizMutation();
|
||||
const modal = useModal();
|
||||
|
||||
const quizInCanvas = canvasQuizzes.find((c) => c.title === quizName);
|
||||
const quizInCanvas = canvasQuizzes?.find((c) => c.title === quizName);
|
||||
|
||||
return (
|
||||
<div className="p-5 flex flex-row justify-between">
|
||||
@@ -90,8 +90,8 @@ export function QuizButtons({
|
||||
<div className="flex justify-around gap-3">
|
||||
<button
|
||||
onClick={async () => {
|
||||
await deleteLocal.mutateAsync({ moduleName, quizName, courseName });
|
||||
router.push(getCourseUrl(courseName));
|
||||
deleteLocal.mutate({ moduleName, quizName, courseName });
|
||||
}}
|
||||
className="btn-danger"
|
||||
>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useSetAssignmentGroupsMutation } from "@/hooks/canvas/canvasCourseHooks
|
||||
export default function AssignmentGroupManagement() {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const updateSettings = useUpdateLocalCourseSettingsMutation();
|
||||
const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId); // untested
|
||||
// const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId); // untested
|
||||
|
||||
const [assignmentGroups, setAssignmentGroups] = useState<
|
||||
LocalAssignmentGroup[]
|
||||
|
||||
@@ -13,7 +13,10 @@ import { useEmptyDirectoriesQuery } from "@/hooks/localCourse/storageDirectoryHo
|
||||
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
||||
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
|
||||
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType";
|
||||
import { DayOfWeek } from "@/models/local/localCourseSettings";
|
||||
import {
|
||||
DayOfWeek,
|
||||
LocalCourseSettings,
|
||||
} from "@/models/local/localCourseSettings";
|
||||
import { getCourseUrl } from "@/services/urlUtils";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useMemo, useState } from "react";
|
||||
@@ -47,6 +50,9 @@ export default function NewCourseForm() {
|
||||
const [selectedDirectory, setSelectedDirectory] = useState<
|
||||
string | undefined
|
||||
>();
|
||||
const [courseToImport, setCourseToImport] = useState<
|
||||
LocalCourseSettings | undefined
|
||||
>();
|
||||
const createCourse = useCreateLocalCourseMutation();
|
||||
|
||||
const formIsComplete =
|
||||
@@ -71,17 +77,34 @@ export default function NewCourseForm() {
|
||||
setSelectedDirectory={setSelectedDirectory}
|
||||
selectedDaysOfWeek={selectedDaysOfWeek}
|
||||
setSelectedDaysOfWeek={setSelectedDaysOfWeek}
|
||||
courseToImport={courseToImport}
|
||||
setCourseToImport={setCourseToImport}
|
||||
/>
|
||||
)}
|
||||
</SuspenseAndErrorHandling>
|
||||
<div className="m-3 text-center">
|
||||
<button
|
||||
disabled={!formIsComplete || createCourse.isPending}
|
||||
onClick={() => {
|
||||
onClick={async () => {
|
||||
if (formIsComplete) {
|
||||
createCourse
|
||||
.mutateAsync({
|
||||
settings: {
|
||||
const newSettings: LocalCourseSettings = courseToImport
|
||||
? {
|
||||
...courseToImport,
|
||||
name: selectedDirectory,
|
||||
daysOfWeek: selectedDaysOfWeek,
|
||||
canvasId: selectedCanvasCourse.id,
|
||||
startDate: selectedTerm.start_at ?? "",
|
||||
endDate: selectedTerm.end_at ?? "",
|
||||
holidays: [],
|
||||
assignmentGroups: courseToImport.assignmentGroups.map(
|
||||
(assignmentGroup) => {
|
||||
const { canvasId, ...groupWithoutCanvas } =
|
||||
assignmentGroup;
|
||||
return groupWithoutCanvas;
|
||||
}
|
||||
),
|
||||
}
|
||||
: {
|
||||
name: selectedDirectory,
|
||||
assignmentGroups: [],
|
||||
daysOfWeek: selectedDaysOfWeek,
|
||||
@@ -96,11 +119,12 @@ export default function NewCourseForm() {
|
||||
defaultFileUploadTypes: ["pdf", "png", "jpg", "jpeg"],
|
||||
defaultLockHoursOffset: 0,
|
||||
holidays: [],
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
router.push(getCourseUrl(selectedDirectory));
|
||||
});
|
||||
};
|
||||
await createCourse.mutateAsync({
|
||||
settings: newSettings,
|
||||
settingsFromCourseToImport: courseToImport,
|
||||
});
|
||||
router.push(getCourseUrl(selectedDirectory));
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -125,6 +149,8 @@ function OtherSettings({
|
||||
setSelectedDirectory,
|
||||
selectedDaysOfWeek,
|
||||
setSelectedDaysOfWeek,
|
||||
courseToImport,
|
||||
setCourseToImport,
|
||||
}: {
|
||||
selectedTerm: CanvasEnrollmentTermModel;
|
||||
selectedCanvasCourse: CanvasCourseModel | undefined;
|
||||
@@ -137,15 +163,21 @@ function OtherSettings({
|
||||
>;
|
||||
selectedDaysOfWeek: DayOfWeek[];
|
||||
setSelectedDaysOfWeek: React.Dispatch<React.SetStateAction<DayOfWeek[]>>;
|
||||
courseToImport: LocalCourseSettings | undefined;
|
||||
setCourseToImport: React.Dispatch<
|
||||
React.SetStateAction<LocalCourseSettings | undefined>
|
||||
>;
|
||||
}) {
|
||||
const { data: canvasCourses } = useCourseListInTermQuery(selectedTerm.id);
|
||||
const [allSettings] = useLocalCoursesSettingsQuery();
|
||||
const [emptyDirectories] = useEmptyDirectoriesQuery();
|
||||
|
||||
const populatedCanvasCourseIds = allSettings.map((s) => s.canvasId);
|
||||
const availableCourses = canvasCourses.filter(
|
||||
(canvas) => !populatedCanvasCourseIds.includes(canvas.id)
|
||||
);
|
||||
const availableCourses =
|
||||
canvasCourses?.filter(
|
||||
(canvas: CanvasCourseModel) =>
|
||||
!populatedCanvasCourseIds.includes(canvas.id)
|
||||
) ?? [];
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -183,6 +215,13 @@ function OtherSettings({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<SelectInput
|
||||
value={courseToImport}
|
||||
setValue={setCourseToImport}
|
||||
label={"(Optional) Course Content to Import"}
|
||||
options={allSettings}
|
||||
getOptionName={(c) => c.name}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ import { getLecturePreviewUrl } from "@/services/urlUtils";
|
||||
import Link from "next/link";
|
||||
import { useCourseContext } from "../course/[courseName]/context/courseContext";
|
||||
import { getLectureForDay } from "@/models/local/lectureUtils";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
import { useLecturesSuspenseQuery as useLecturesQuery } from "@/hooks/localCourse/lectureHooks";
|
||||
|
||||
export default function OneCourseLectures() {
|
||||
const { courseName } = useCourseContext();
|
||||
// const { data: weeks } = useLecturesByWeekQuery();
|
||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||
const [weeks] = useLecturesQuery();
|
||||
|
||||
const dayAsDate = new Date();
|
||||
const dayAsString = getDateOnlyMarkdownString(dayAsDate);
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
|
||||
import { canvasService } from "@/services/canvas/canvasService";
|
||||
import {
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
useSuspenseQueries,
|
||||
useSuspenseQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||
@@ -24,28 +18,12 @@ export const canvasAssignmentKeys = {
|
||||
export const useCanvasAssignmentsQuery = () => {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
|
||||
return useSuspenseQuery({
|
||||
return useQuery({
|
||||
queryKey: canvasAssignmentKeys.assignments(settings.canvasId),
|
||||
queryFn: async () => canvasAssignmentService.getAll(settings.canvasId),
|
||||
});
|
||||
};
|
||||
|
||||
// export const useCanvasAssignmentsQuery = () => {
|
||||
// const [settings] = useLocalCourseSettingsQuery();
|
||||
// const { data: allAssignments } = useInnerCanvasAssignmentsQuery();
|
||||
|
||||
// return useSuspenseQueries({
|
||||
// queries: allAssignments.map((a) => ({
|
||||
// queryKey: canvasAssignmentKeys.assignment(settings.canvasId, a.name),
|
||||
// queryFn: () => a,
|
||||
// })),
|
||||
// combine: (results) => ({
|
||||
// data: results.map((r) => r.data),
|
||||
// pending: results.some((r) => r.isPending),
|
||||
// }),
|
||||
// });
|
||||
// };
|
||||
|
||||
export const useAddAssignmentToCanvasMutation = () => {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const { data: canvasModules } = useCanvasModulesQuery();
|
||||
@@ -60,6 +38,11 @@ export const useAddAssignmentToCanvasMutation = () => {
|
||||
assignment: LocalAssignment;
|
||||
moduleName: string;
|
||||
}) => {
|
||||
if (!canvasModules) {
|
||||
console.log("cannot add assignment until modules loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
const assignmentGroup = settings.assignmentGroups.find(
|
||||
(g) => g.name === assignment.localAssignmentGroupName
|
||||
);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
|
||||
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
||||
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup";
|
||||
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
|
||||
import { canvasService } from "@/services/canvas/canvasService";
|
||||
import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
|
||||
export const canvasCourseKeys = {
|
||||
courseDetails: (canavasId: number) =>
|
||||
@@ -13,34 +15,37 @@ export const canvasCourseKeys = {
|
||||
};
|
||||
|
||||
export const useCourseListInTermQuery = (canvasTermId: number | undefined) =>
|
||||
useSuspenseQuery({
|
||||
useQuery({
|
||||
queryKey: canvasCourseKeys.courseListInTerm(canvasTermId),
|
||||
queryFn: async () =>
|
||||
queryFn: async (): Promise<CanvasCourseModel[]> =>
|
||||
canvasTermId ? await canvasService.getCourses(canvasTermId) : [],
|
||||
enabled: !!canvasTermId,
|
||||
});
|
||||
|
||||
export const useCanvasCourseQuery = (canvasId: number) =>
|
||||
useSuspenseQuery({
|
||||
queryKey: canvasCourseKeys.courseDetails(canvasId),
|
||||
queryFn: async () => await canvasService.getCourse(canvasId),
|
||||
});
|
||||
// export const useCanvasCourseQuery = (canvasId: number) =>
|
||||
// useQuery({
|
||||
// queryKey: canvasCourseKeys.courseDetails(canvasId),
|
||||
// queryFn: async () => await canvasService.getCourse(canvasId),
|
||||
// });
|
||||
|
||||
export const useSetAssignmentGroupsMutation = (canvasId: number) => {
|
||||
const { data: canvasAssignmentGroups } = useAssignmentGroupsQuery(canvasId);
|
||||
return useMutation({
|
||||
mutationFn: async (localAssignmentGroups: LocalAssignmentGroup[]) => {
|
||||
if (!canvasAssignmentGroups) return;
|
||||
|
||||
const localNames = localAssignmentGroups.map((g) => g.name);
|
||||
const groupsToDelete = canvasAssignmentGroups.filter(
|
||||
(c) => !localNames.includes(c.name)
|
||||
(c: CanvasAssignmentGroup) => !localNames.includes(c.name)
|
||||
);
|
||||
await Promise.all([
|
||||
...groupsToDelete.map(
|
||||
async (g) =>
|
||||
async (g: CanvasAssignmentGroup) =>
|
||||
await canvasAssignmentGroupService.delete(canvasId, g.id, g.name)
|
||||
),
|
||||
...localAssignmentGroups.map(async (group) => {
|
||||
const canvasGroup = canvasAssignmentGroups.find(
|
||||
(c) => c.name === group.name
|
||||
(c: CanvasAssignmentGroup) => c.name === group.name
|
||||
);
|
||||
if (!canvasGroup) {
|
||||
await canvasAssignmentGroupService.create(canvasId, group);
|
||||
@@ -55,8 +60,8 @@ export const useSetAssignmentGroupsMutation = (canvasId: number) => {
|
||||
};
|
||||
|
||||
export const useAssignmentGroupsQuery = (canvasId: number) => {
|
||||
return useSuspenseQuery({
|
||||
return useQuery({
|
||||
queryKey: canvasCourseKeys.assignmentGroups(canvasId),
|
||||
queryFn: async () => await canvasAssignmentGroupService.getAll(canvasId),
|
||||
queryFn: async (): Promise<CanvasAssignmentGroup[]> => await canvasAssignmentGroupService.getAll(canvasId),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
useSuspenseQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||
|
||||
@@ -12,7 +12,7 @@ export const canvasCourseModuleKeys = {
|
||||
|
||||
export const useCanvasModulesQuery = () => {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
return useSuspenseQuery({
|
||||
return useQuery({
|
||||
queryKey: canvasCourseModuleKeys.modules(settings.canvasId),
|
||||
queryFn: async () =>
|
||||
await canvasModuleService.getCourseModules(settings.canvasId),
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||
import { canvasPageService } from "@/services/canvas/canvasPageService";
|
||||
import {
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
useSuspenseQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||
import {
|
||||
@@ -22,7 +18,7 @@ export const canvasPageKeys = {
|
||||
|
||||
export const useCanvasPagesQuery = () => {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
return useSuspenseQuery({
|
||||
return useQuery({
|
||||
queryKey: canvasPageKeys.pagesInCourse(settings.canvasId),
|
||||
queryFn: async () => await canvasPageService.getAll(settings.canvasId),
|
||||
});
|
||||
@@ -42,6 +38,10 @@ export const useCreateCanvasPageMutation = () => {
|
||||
page: LocalCoursePage;
|
||||
moduleName: string;
|
||||
}) => {
|
||||
if (!canvasModules) {
|
||||
console.log("cannot add page until modules loaded");
|
||||
return;
|
||||
}
|
||||
const canvasPage = await canvasPageService.create(
|
||||
settings.canvasId,
|
||||
page
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
useSuspenseQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||
import { canvasQuizService } from "@/services/canvas/canvasQuizService";
|
||||
@@ -20,7 +20,7 @@ export const canvasQuizKeys = {
|
||||
export const useCanvasQuizzesQuery = () => {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
|
||||
return useSuspenseQuery({
|
||||
return useQuery({
|
||||
queryKey: canvasQuizKeys.quizzes(settings.canvasId),
|
||||
queryFn: async () => canvasQuizService.getAll(settings.canvasId),
|
||||
});
|
||||
@@ -40,6 +40,10 @@ export const useAddQuizToCanvasMutation = () => {
|
||||
quiz: LocalQuiz;
|
||||
moduleName: string;
|
||||
}) => {
|
||||
if (!canvasModules) {
|
||||
console.log("cannot add quiz until modules loaded");
|
||||
return;
|
||||
}
|
||||
const assignmentGroup = settings.assignmentGroups.find(
|
||||
(g) => g.name === quiz.localAssignmentGroupName
|
||||
);
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
// import { QueryClient } from "@tanstack/react-query";
|
||||
// import { localCourseKeys } from "./localCourse/localCourseKeys";
|
||||
// import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||
// import { LocalCourseSettings } from "@/models/local/localCourseSettings";
|
||||
// import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
|
||||
// import { canvasAssignmentKeys } from "./canvas/canvasAssignmentHooks";
|
||||
// import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
// import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||
// import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
||||
// import { canvasQuizService } from "@/services/canvas/canvasQuizService";
|
||||
// import { canvasPageService } from "@/services/canvas/canvasPageService";
|
||||
// import { canvasQuizKeys } from "./canvas/canvasQuizHooks";
|
||||
// import { canvasPageKeys } from "./canvas/canvasPageHooks";
|
||||
// // import { getLecturesQueryConfig } from "./localCourse/lectureHooks";
|
||||
|
||||
// // https://tanstack.com/query/latest/docs/framework/react/guides/ssr
|
||||
// export const hydrateCourses = async (queryClient: QueryClient) => {
|
||||
// const allSettings = await fileStorageService.settings.getAllCoursesSettings();
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.allCoursesSettings,
|
||||
// queryFn: () => allSettings,
|
||||
// });
|
||||
|
||||
// await Promise.all(
|
||||
// allSettings.map(async (settings) => {
|
||||
// await hydrateCourse(queryClient, settings);
|
||||
// })
|
||||
// );
|
||||
// };
|
||||
|
||||
// export const hydrateCourse = async (
|
||||
// queryClient: QueryClient,
|
||||
// courseSettings: LocalCourseSettings
|
||||
// ) => {
|
||||
// const courseName = courseSettings.name;
|
||||
// const moduleNames = await fileStorageService.modules.getModuleNames(
|
||||
// courseName
|
||||
// );
|
||||
|
||||
// // await Promise.all(
|
||||
// // moduleNames.map(async (moduleName) => {
|
||||
// // const assignments = await trpcHelpers.assignment.getAllAssignments.fetch({
|
||||
// // courseName,
|
||||
// // moduleName,
|
||||
// // });
|
||||
// // await Promise.all(
|
||||
// // assignments.map(
|
||||
// // async (a) =>
|
||||
// // await trpcHelpers.assignment.getAssignment.fetch({
|
||||
// // courseName,
|
||||
// // moduleName,
|
||||
// // assignmentName: a.name,
|
||||
// // })
|
||||
// // )
|
||||
// // );
|
||||
// // })
|
||||
// // );
|
||||
|
||||
// const modulesData = await Promise.all(
|
||||
// moduleNames.map((moduleName) => loadAllModuleData(courseName, moduleName))
|
||||
// );
|
||||
|
||||
// // await queryClient.prefetchQuery(getLecturesQueryConfig(courseName));
|
||||
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.settings(courseName),
|
||||
// queryFn: () => courseSettings,
|
||||
// });
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.moduleNames(courseName),
|
||||
// queryFn: () => moduleNames,
|
||||
// });
|
||||
|
||||
// await Promise.all(
|
||||
// modulesData.map((d) => hydrateModuleData(d, courseName, queryClient))
|
||||
// );
|
||||
// };
|
||||
|
||||
// export const hydrateCanvasCourse = async (
|
||||
// canvasCourseId: number,
|
||||
// queryClient: QueryClient
|
||||
// ) => {
|
||||
// await Promise.all([
|
||||
// queryClient.prefetchQuery({
|
||||
// queryKey: canvasAssignmentKeys.assignments(canvasCourseId),
|
||||
// queryFn: async () => await canvasAssignmentService.getAll(canvasCourseId),
|
||||
// }),
|
||||
// queryClient.prefetchQuery({
|
||||
// queryKey: canvasQuizKeys.quizzes(canvasCourseId),
|
||||
// queryFn: async () => await canvasQuizService.getAll(canvasCourseId),
|
||||
// }),
|
||||
// queryClient.prefetchQuery({
|
||||
// queryKey: canvasPageKeys.pagesInCourse(canvasCourseId),
|
||||
// queryFn: async () => await canvasPageService.getAll(canvasCourseId),
|
||||
// }),
|
||||
// ]);
|
||||
// };
|
||||
|
||||
// const loadAllModuleData = async (courseName: string, moduleName: string) => {
|
||||
// const [pages, quizzes] = await Promise.all([
|
||||
// // await fileStorageService.assignments.getAssignmentNames(
|
||||
// // courseName,
|
||||
// // moduleName
|
||||
// // ),
|
||||
// await fileStorageService.pages.getPages(courseName, moduleName),
|
||||
// await fileStorageService.quizzes.getQuizzes(courseName, moduleName),
|
||||
// ]);
|
||||
|
||||
// // const [assignments] = await Promise.all([
|
||||
// // await Promise.all(
|
||||
// // assignmentNames.map(async (assignmentName) => {
|
||||
// // try {
|
||||
// // return await fileStorageService.assignments.getAssignment(
|
||||
// // courseName,
|
||||
// // moduleName,
|
||||
// // assignmentName
|
||||
// // );
|
||||
// // } catch (error) {
|
||||
// // console.error(`Error fetching assignment: ${assignmentName}`, error);
|
||||
// // return null; // or any other placeholder value
|
||||
// // }
|
||||
// // })
|
||||
// // ),
|
||||
// // ]);
|
||||
|
||||
// // const assignmentsLoaded = assignments.filter((a) => a !== null);
|
||||
// return {
|
||||
// moduleName,
|
||||
// // assignments: assignmentsLoaded,
|
||||
// quizzes,
|
||||
// pages,
|
||||
// };
|
||||
// };
|
||||
|
||||
// const hydrateModuleData = async (
|
||||
// {
|
||||
// moduleName,
|
||||
// // assignments,
|
||||
// quizzes,
|
||||
// pages,
|
||||
// }: {
|
||||
// moduleName: string;
|
||||
// // assignments: LocalAssignment[];
|
||||
// quizzes: LocalQuiz[];
|
||||
// pages: LocalCoursePage[];
|
||||
// },
|
||||
// courseName: string,
|
||||
// queryClient: QueryClient
|
||||
// ) => {
|
||||
// // await queryClient.prefetchQuery({
|
||||
// // queryKey: localCourseKeys.allItemsOfType(
|
||||
// // courseName,
|
||||
// // moduleName,
|
||||
// // "Assignment"
|
||||
// // ),
|
||||
// // queryFn: () => assignments,
|
||||
// // });
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Quiz"),
|
||||
// queryFn: () => quizzes,
|
||||
// });
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.allItemsOfType(courseName, moduleName, "Page"),
|
||||
// queryFn: () => pages,
|
||||
// });
|
||||
// // await Promise.all(
|
||||
// // assignments.map(
|
||||
// // async (assignment) =>
|
||||
// // await queryClient.prefetchQuery({
|
||||
// // queryKey: localCourseKeys.itemOfType(
|
||||
// // courseName,
|
||||
// // moduleName,
|
||||
// // assignment.name,
|
||||
// // "Assignment"
|
||||
// // ),
|
||||
// // queryFn: () => assignment,
|
||||
// // })
|
||||
// // )
|
||||
// // );
|
||||
// await Promise.all(
|
||||
// quizzes.map(
|
||||
// async (quiz) =>
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.itemOfType(
|
||||
// courseName,
|
||||
// moduleName,
|
||||
// quiz.name,
|
||||
// "Quiz"
|
||||
// ),
|
||||
// queryFn: () => quiz,
|
||||
// })
|
||||
// )
|
||||
// );
|
||||
// await Promise.all(
|
||||
// pages.map(
|
||||
// async (page) =>
|
||||
// await queryClient.prefetchQuery({
|
||||
// queryKey: localCourseKeys.itemOfType(
|
||||
// courseName,
|
||||
// moduleName,
|
||||
// page.name,
|
||||
// "Page"
|
||||
// ),
|
||||
// queryFn: () => page,
|
||||
// })
|
||||
// )
|
||||
// );
|
||||
// };
|
||||
@@ -14,13 +14,18 @@ export const useAssignmentQuery = (
|
||||
});
|
||||
};
|
||||
|
||||
export const useAssignmentsQuery = (moduleName: string) => {
|
||||
export const useAssignmentNamesQuery = (moduleName: string) => {
|
||||
const { courseName } = useCourseContext();
|
||||
console.log("rendering all assignments query");
|
||||
return trpc.assignment.getAllAssignments.useSuspenseQuery({
|
||||
moduleName,
|
||||
courseName,
|
||||
});
|
||||
return trpc.assignment.getAllAssignments.useSuspenseQuery(
|
||||
{
|
||||
moduleName,
|
||||
courseName,
|
||||
},
|
||||
{
|
||||
select: (assignments) => assignments.map((a) => a.name),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const useUpdateAssignmentMutation = () => {
|
||||
@@ -57,8 +62,18 @@ export const useCreateAssignmentMutation = () => {
|
||||
export const useDeleteAssignmentMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.assignment.deleteAssignment.useMutation({
|
||||
onSuccess: (_, { courseName, moduleName }) => {
|
||||
onSuccess: (_, { courseName, moduleName, assignmentName }) => {
|
||||
utils.assignment.getAllAssignments.invalidate({ courseName, moduleName });
|
||||
utils.assignment.getAssignment.invalidate(
|
||||
{
|
||||
courseName,
|
||||
moduleName,
|
||||
assignmentName,
|
||||
},
|
||||
{
|
||||
refetchType: "all",
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
|
||||
export const useLecturesSuspenseQuery = () => {
|
||||
const { courseName } = useCourseContext();
|
||||
return trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||
};
|
||||
|
||||
export const useLectureUpdateMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.lectures.updateLecture.useMutation({
|
||||
|
||||
@@ -41,7 +41,12 @@ export const useDeletePageMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.page.deletePage.useMutation({
|
||||
onSuccess: (_, { courseName, moduleName, pageName }) => {
|
||||
utils.page.getAllPages.invalidate({ courseName, moduleName });
|
||||
utils.page.getAllPages.invalidate(
|
||||
{ courseName, moduleName },
|
||||
{
|
||||
refetchType: "all",
|
||||
}
|
||||
);
|
||||
utils.page.getPage.invalidate({ courseName, moduleName, pageName });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -41,7 +41,10 @@ export const useDeleteQuizMutation = () => {
|
||||
const utils = trpc.useUtils();
|
||||
return trpc.quiz.deleteQuiz.useMutation({
|
||||
onSuccess: (_, { courseName, moduleName, quizName }) => {
|
||||
utils.quiz.getAllQuizzes.invalidate({ courseName, moduleName });
|
||||
utils.quiz.getAllQuizzes.invalidate(
|
||||
{ courseName, moduleName },
|
||||
{ refetchType: "all" }
|
||||
);
|
||||
utils.quiz.getQuiz.invalidate({ courseName, moduleName, quizName });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { LocalAssignment } from "./assignment/localAssignment";
|
||||
import { Lecture } from "./lecture";
|
||||
import { LocalCoursePage } from "./page/localCoursePage";
|
||||
import { LocalQuiz } from "./quiz/localQuiz";
|
||||
import {
|
||||
dateToMarkdownString,
|
||||
getDateFromString,
|
||||
getDateFromStringOrThrow,
|
||||
getDateOnlyMarkdownString,
|
||||
} from "./timeUtils";
|
||||
|
||||
export const prepAssignmentForNewSemester = (
|
||||
@@ -69,6 +68,24 @@ export const prepPageForNewSemester = (
|
||||
page.dueAt,
|
||||
};
|
||||
};
|
||||
export const prepLectureForNewSemester = (
|
||||
lecture: Lecture,
|
||||
oldSemesterStartDate: string,
|
||||
newSemesterStartDate: string
|
||||
): Lecture => {
|
||||
const updatedText = replaceClassroomUrl(lecture.content);
|
||||
const newDate = newDateOffset(
|
||||
lecture.date,
|
||||
oldSemesterStartDate,
|
||||
newSemesterStartDate
|
||||
);
|
||||
const newDateOnly = newDate?.split(" ")[0];
|
||||
return {
|
||||
...lecture,
|
||||
content: updatedText,
|
||||
date: newDateOnly ?? lecture.date,
|
||||
};
|
||||
};
|
||||
|
||||
const replaceClassroomUrl = (value: string) => {
|
||||
const classroomPattern =
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { LocalAssignment } from "../assignment/localAssignment";
|
||||
import { prepAssignmentForNewSemester, prepPageForNewSemester, prepQuizForNewSemester } from "../semesterTransferUtils";
|
||||
import {
|
||||
prepAssignmentForNewSemester,
|
||||
prepLectureForNewSemester,
|
||||
prepPageForNewSemester,
|
||||
prepQuizForNewSemester,
|
||||
} from "../semesterTransferUtils";
|
||||
import { LocalQuiz } from "../quiz/localQuiz";
|
||||
import { LocalCoursePage } from "../page/localCoursePage";
|
||||
import { Lecture } from "../lecture";
|
||||
|
||||
describe("can take an assignment and template it for a new semester", () => {
|
||||
it("can sanitize assignment github classroom repo url", () => {
|
||||
@@ -193,3 +199,24 @@ describe("can prep pages", () => {
|
||||
expect(sanitizedPage.dueAt).toEqual("01/12/2024 23:59:00");
|
||||
});
|
||||
});
|
||||
|
||||
describe("can prep lecture", () => {
|
||||
it("lecture gets new date, github url changes", () => {
|
||||
const lecture: Lecture = {
|
||||
name: "test title",
|
||||
date: "08/30/2023",
|
||||
content: "test text content",
|
||||
};
|
||||
|
||||
const oldSemesterStartDate = "08/26/2023 23:59:00";
|
||||
const newSemesterStartDate = "01/08/2024 23:59:00";
|
||||
|
||||
const sanitizedLecture = prepLectureForNewSemester(
|
||||
lecture,
|
||||
oldSemesterStartDate,
|
||||
newSemesterStartDate
|
||||
);
|
||||
|
||||
expect(sanitizedLecture.date).toEqual("01/12/2024");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
getDayOfWeek,
|
||||
LocalCourseSettings,
|
||||
} from "@/models/local/localCourseSettings";
|
||||
import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils";
|
||||
import { getDateFromStringOrThrow } from "@/models/local/timeUtils";
|
||||
|
||||
export async function getLectures(courseName: string) {
|
||||
|
||||
@@ -3,6 +3,17 @@ import { z } from "zod";
|
||||
import { router } from "../trpc";
|
||||
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||
import { zodLocalCourseSettings } from "@/models/local/localCourseSettings";
|
||||
import { trpc } from "../utils";
|
||||
import {
|
||||
getLectures,
|
||||
updateLecture,
|
||||
} from "@/services/fileStorage/lectureFileStorageService";
|
||||
import {
|
||||
prepAssignmentForNewSemester,
|
||||
prepLectureForNewSemester,
|
||||
prepPageForNewSemester,
|
||||
prepQuizForNewSemester,
|
||||
} from "@/models/local/semesterTransferUtils";
|
||||
|
||||
export const settingsRouter = router({
|
||||
allCoursesSettings: publicProcedure.query(async () => {
|
||||
@@ -25,6 +36,117 @@ export const settingsRouter = router({
|
||||
return s;
|
||||
}),
|
||||
createCourse: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
settings: zodLocalCourseSettings,
|
||||
settingsFromCourseToImport: zodLocalCourseSettings.optional(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input: { settings, settingsFromCourseToImport } }) => {
|
||||
await fileStorageService.settings.updateCourseSettings(
|
||||
settings.name,
|
||||
settings
|
||||
);
|
||||
|
||||
if (settingsFromCourseToImport) {
|
||||
const oldCourseName = settingsFromCourseToImport.name;
|
||||
const newCourseName = settings.name;
|
||||
const oldModules = await fileStorageService.modules.getModuleNames(
|
||||
oldCourseName
|
||||
);
|
||||
console.log(
|
||||
"old course name",
|
||||
oldCourseName,
|
||||
"new course name",
|
||||
newCourseName
|
||||
);
|
||||
|
||||
console.log(
|
||||
"old start date",
|
||||
settingsFromCourseToImport.startDate,
|
||||
"new start date",
|
||||
settings.startDate
|
||||
);
|
||||
await Promise.all(
|
||||
oldModules.map(async (moduleName) => {
|
||||
await fileStorageService.modules.createModule(
|
||||
newCourseName,
|
||||
moduleName
|
||||
);
|
||||
|
||||
const [oldAssignments, oldQuizzes, oldPages, oldLecturesByWeek] =
|
||||
await Promise.all([
|
||||
fileStorageService.assignments.getAssignments(
|
||||
oldCourseName,
|
||||
moduleName
|
||||
),
|
||||
await fileStorageService.quizzes.getQuizzes(
|
||||
oldCourseName,
|
||||
moduleName
|
||||
),
|
||||
await fileStorageService.pages.getPages(
|
||||
oldCourseName,
|
||||
moduleName
|
||||
),
|
||||
await getLectures(oldCourseName),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
...oldAssignments.map(async (oldAssignment) => {
|
||||
const newAssignment = prepAssignmentForNewSemester(
|
||||
oldAssignment,
|
||||
settingsFromCourseToImport.startDate,
|
||||
settings.startDate,
|
||||
);
|
||||
await fileStorageService.assignments.updateOrCreateAssignment({
|
||||
courseName: newCourseName,
|
||||
moduleName,
|
||||
assignmentName: newAssignment.name,
|
||||
assignment: newAssignment,
|
||||
});
|
||||
}),
|
||||
...oldQuizzes.map(async (oldQuiz) => {
|
||||
const newQuiz = prepQuizForNewSemester(
|
||||
oldQuiz,
|
||||
settingsFromCourseToImport.startDate,
|
||||
settings.startDate,
|
||||
);
|
||||
await fileStorageService.quizzes.updateQuiz({
|
||||
courseName: newCourseName,
|
||||
moduleName,
|
||||
quizName: newQuiz.name,
|
||||
quiz: newQuiz,
|
||||
});
|
||||
}),
|
||||
...oldPages.map(async (oldPage) => {
|
||||
const newPage = prepPageForNewSemester(
|
||||
oldPage,
|
||||
settingsFromCourseToImport.startDate,
|
||||
settings.startDate,
|
||||
);
|
||||
await fileStorageService.pages.updatePage({
|
||||
courseName: newCourseName,
|
||||
moduleName,
|
||||
pageName: newPage.name,
|
||||
page: newPage,
|
||||
});
|
||||
}),
|
||||
...oldLecturesByWeek.flatMap(async (oldLectureByWeek) =>
|
||||
oldLectureByWeek.lectures.map(async (oldLecture) => {
|
||||
const newLecture = prepLectureForNewSemester(
|
||||
oldLecture,
|
||||
settingsFromCourseToImport.startDate,
|
||||
settings.startDate,
|
||||
);
|
||||
await updateLecture(newCourseName, settings, newLecture);
|
||||
})
|
||||
),
|
||||
]);
|
||||
})
|
||||
);
|
||||
}
|
||||
}),
|
||||
updateSettings: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
settings: zodLocalCourseSettings,
|
||||
@@ -36,17 +158,4 @@ export const settingsRouter = router({
|
||||
settings
|
||||
);
|
||||
}),
|
||||
updateSettings: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
settings: zodLocalCourseSettings,
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input: { settings } }) => {
|
||||
await fileStorageService.settings.updateCourseSettings(
|
||||
settings.name,
|
||||
settings
|
||||
);
|
||||
}),
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user