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:
3
nextjs/.gitignore
vendored
3
nextjs/.gitignore
vendored
@@ -1,5 +1,8 @@
|
|||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
.pnpm-store/
|
||||||
|
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
/.pnp
|
/.pnp
|
||||||
|
|||||||
@@ -10,4 +10,13 @@ docker run -it --rm \
|
|||||||
-v ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/intro_to_web \
|
-v ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/intro_to_web \
|
||||||
-v ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend \
|
-v ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend \
|
||||||
node \
|
node \
|
||||||
bash -c "npm i && npm run dev -- -H 0.0.0.0"
|
sh -c "
|
||||||
|
mkdir -p ~/.npm-global && \
|
||||||
|
npm config set prefix '~/.npm-global' && \
|
||||||
|
export PATH=~/.npm-global/bin:\$PATH && \
|
||||||
|
npm install -g pnpm && \
|
||||||
|
pnpm install && pnpm start
|
||||||
|
"
|
||||||
|
|
||||||
|
|
||||||
|
# bash -c "npm i -g pnpm && pnpm i && pnpm run dev -- -H 0.0.0.0"
|
||||||
|
|||||||
@@ -17,13 +17,14 @@ const getUrl = (params: { rest: string[] }, req: NextRequest) => {
|
|||||||
|
|
||||||
appendQueryParams(url, req);
|
appendQueryParams(url, req);
|
||||||
|
|
||||||
return url;
|
return url;``
|
||||||
};
|
};
|
||||||
|
|
||||||
const proxyResponseHeaders = (response: any) => {
|
const proxyResponseHeaders = (response: any) => {
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
Object.entries(response.headers).forEach(([key, value]) => {
|
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;
|
return headers;
|
||||||
};
|
};
|
||||||
@@ -32,21 +33,19 @@ export async function GET(
|
|||||||
req: NextRequest,
|
req: NextRequest,
|
||||||
{ params }: { params: Promise<{ rest: string[] }> }
|
{ params }: { params: Promise<{ rest: string[] }> }
|
||||||
) {
|
) {
|
||||||
return withErrorHandling(async () => {
|
try {
|
||||||
try {
|
const url = getUrl(await params, req);
|
||||||
const url = getUrl(await params, req);
|
|
||||||
|
|
||||||
const response = await axiosClient.get(url.toString());
|
const response = await axiosClient.get(url.toString());
|
||||||
|
const headers = proxyResponseHeaders(response);
|
||||||
const headers = proxyResponseHeaders(response);
|
return NextResponse.json(response.data, { headers });
|
||||||
return new NextResponse(JSON.stringify(response.data), { headers });
|
} catch (error: any) {
|
||||||
} catch (error: any) {
|
console.log("canvas get error", error, error?.message);
|
||||||
return new NextResponse(
|
return NextResponse.json(
|
||||||
JSON.stringify({ error: error.message || "Canvas GET request failed" }),
|
JSON.stringify({ error: error.message || "Canvas GET request failed" }),
|
||||||
{ status: error.response?.status || 500 }
|
{ status: error.response?.status || 500 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import NewItemForm from "../../modules/NewItemForm";
|
|||||||
import { DraggableItem } from "../../context/drag/draggingContext";
|
import { DraggableItem } from "../../context/drag/draggingContext";
|
||||||
import { useDragStyleContext } from "../../context/drag/dragStyleContext";
|
import { useDragStyleContext } from "../../context/drag/dragStyleContext";
|
||||||
import { getLectureForDay } from "@/models/local/lectureUtils";
|
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 }) {
|
export function DayTitle({ day, dayAsDate }: { day: string; dayAsDate: Date }) {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
const [weeks] = useLecturesSuspenseQuery();
|
||||||
const { setIsDragging } = useDragStyleContext();
|
const { setIsDragging } = useDragStyleContext();
|
||||||
const todaysLecture = getLectureForDay(weeks, dayAsDate);
|
const todaysLecture = getLectureForDay(weeks, dayAsDate);
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export function useTodaysItems(day: string) {
|
|||||||
}[] = todaysModules
|
}[] = todaysModules
|
||||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||||
todaysModules[moduleName].assignments.map((assignment) => {
|
todaysModules[moduleName].assignments.map((assignment) => {
|
||||||
const canvasAssignment = canvasAssignments.find(
|
const canvasAssignment = canvasAssignments?.find(
|
||||||
(c) => c.name === assignment.name
|
(c) => c.name === assignment.name
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
@@ -57,7 +57,7 @@ export function useTodaysItems(day: string) {
|
|||||||
}[] = todaysModules
|
}[] = todaysModules
|
||||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||||
todaysModules[moduleName].quizzes.map((quiz) => {
|
todaysModules[moduleName].quizzes.map((quiz) => {
|
||||||
const canvasQuiz = canvasQuizzes.find((q) => q.title === quiz.name);
|
const canvasQuiz = canvasQuizzes?.find((q) => q.title === quiz.name);
|
||||||
return {
|
return {
|
||||||
moduleName,
|
moduleName,
|
||||||
quiz,
|
quiz,
|
||||||
@@ -79,7 +79,7 @@ export function useTodaysItems(day: string) {
|
|||||||
}[] = todaysModules
|
}[] = todaysModules
|
||||||
? Object.keys(todaysModules).flatMap((moduleName) =>
|
? Object.keys(todaysModules).flatMap((moduleName) =>
|
||||||
todaysModules[moduleName].pages.map((page) => {
|
todaysModules[moduleName].pages.map((page) => {
|
||||||
const canvasPage = canvasPages.find((p) => p.title === page.name);
|
const canvasPage = canvasPages?.find((p) => p.title === page.name);
|
||||||
return {
|
return {
|
||||||
moduleName,
|
moduleName,
|
||||||
page,
|
page,
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ export default function CalendarItemsContextProvider({
|
|||||||
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
||||||
useAllCourseDataQuery();
|
useAllCourseDataQuery();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||||
(previous, { assignment, moduleName }) => {
|
(previous, { assignment, moduleName }) => {
|
||||||
const dueDay = getDateOnlyMarkdownString(
|
const dueDay = getDateOnlyMarkdownString(
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
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 { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||||
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
||||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||||
@@ -36,9 +39,7 @@ export function useItemDropOnDay({
|
|||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
// const { data: weeks } = useLecturesByWeekQuery();
|
// const { data: weeks } = useLecturesByWeekQuery();
|
||||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({
|
const [weeks] = useLecturesSuspenseQuery();
|
||||||
courseName: settings.name,
|
|
||||||
});
|
|
||||||
const updateQuizMutation = useUpdateQuizMutation();
|
const updateQuizMutation = useUpdateQuizMutation();
|
||||||
const updateLectureMutation = useLectureUpdateMutation();
|
const updateLectureMutation = useLectureUpdateMutation();
|
||||||
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { MonacoEditor } from "@/components/editor/MonacoEditor";
|
import { MonacoEditor } from "@/components/editor/MonacoEditor";
|
||||||
import { useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
import { useLecturesSuspenseQuery, useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
||||||
import {
|
import {
|
||||||
lectureToString,
|
lectureToString,
|
||||||
parseLecture,
|
parseLecture,
|
||||||
@@ -17,7 +17,7 @@ import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHoo
|
|||||||
export default function EditLecture({ lectureDay }: { lectureDay: string }) {
|
export default function EditLecture({ lectureDay }: { lectureDay: string }) {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
const [weeks] = useLecturesSuspenseQuery();
|
||||||
const updateLecture = useLectureUpdateMutation();
|
const updateLecture = useLectureUpdateMutation();
|
||||||
|
|
||||||
const lecture = weeks
|
const lecture = weeks
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { getCourseUrl, getLectureUrl } from "@/services/urlUtils";
|
|||||||
import { useCourseContext } from "../../../context/courseContext";
|
import { useCourseContext } from "../../../context/courseContext";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { trpc } from "@/services/trpc/utils";
|
import { trpc } from "@/services/trpc/utils";
|
||||||
|
import { useLecturesSuspenseQuery } from "@/hooks/localCourse/lectureHooks";
|
||||||
|
|
||||||
export default function LecturePreviewPage({
|
export default function LecturePreviewPage({
|
||||||
lectureDay,
|
lectureDay,
|
||||||
@@ -12,7 +13,7 @@ export default function LecturePreviewPage({
|
|||||||
lectureDay: string;
|
lectureDay: string;
|
||||||
}) {
|
}) {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
const [weeks] = useLecturesSuspenseQuery();
|
||||||
const lecture = weeks
|
const lecture = weeks
|
||||||
.flatMap(({ lectures }) => lectures.map((lecture) => lecture))
|
.flatMap(({ lectures }) => lectures.map((lecture) => lecture))
|
||||||
.find((l) => l.date === lectureDay);
|
.find((l) => l.date === lectureDay);
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ import { getModuleItemUrl } from "@/services/urlUtils";
|
|||||||
import { useCourseContext } from "../context/courseContext";
|
import { useCourseContext } from "../context/courseContext";
|
||||||
import { Expandable } from "../../../../components/Expandable";
|
import { Expandable } from "../../../../components/Expandable";
|
||||||
import { useDragStyleContext } from "../context/drag/dragStyleContext";
|
import { useDragStyleContext } from "../context/drag/dragStyleContext";
|
||||||
import { useAssignmentsQuery } from "@/hooks/localCourse/assignmentHooks";
|
|
||||||
import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks";
|
import { useQuizzesQueries } from "@/hooks/localCourse/quizHooks";
|
||||||
|
import { useAssignmentNamesQuery } from "@/hooks/localCourse/assignmentHooks";
|
||||||
|
import { trpc } from "@/services/trpc/utils";
|
||||||
|
|
||||||
export default function ExpandableModule({
|
export default function ExpandableModule({
|
||||||
moduleName,
|
moduleName,
|
||||||
@@ -30,8 +31,14 @@ export default function ExpandableModule({
|
|||||||
moduleName: string;
|
moduleName: string;
|
||||||
}) {
|
}) {
|
||||||
const { itemDropOnModule } = useDraggingContext();
|
const { itemDropOnModule } = useDraggingContext();
|
||||||
|
const { courseName } = useCourseContext();
|
||||||
const [assignments ] = useAssignmentsQuery(moduleName);
|
const [assignmentNames] = useAssignmentNamesQuery(moduleName);
|
||||||
|
|
||||||
|
const [assignments] = trpc.useSuspenseQueries((t) =>
|
||||||
|
assignmentNames.map((assignmentName) =>
|
||||||
|
t.assignment.getAssignment({ courseName, moduleName, assignmentName })
|
||||||
|
)
|
||||||
|
);
|
||||||
const [quizzes] = useQuizzesQueries(moduleName);
|
const [quizzes] = useQuizzesQueries(moduleName);
|
||||||
const [pages] = usePagesQueries(moduleName);
|
const [pages] = usePagesQueries(moduleName);
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function ModuleCanvasStatus({ moduleName }: { moduleName: string }) {
|
|||||||
const { data: canvasModules } = useCanvasModulesQuery();
|
const { data: canvasModules } = useCanvasModulesQuery();
|
||||||
const addToCanvas = useAddCanvasModuleMutation();
|
const addToCanvas = useAddCanvasModuleMutation();
|
||||||
|
|
||||||
const canvasModule = canvasModules.find((c) => c.name === moduleName);
|
const canvasModule = canvasModules?.find((c) => c.name === moduleName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-slate-400 text-end">
|
<div className="text-slate-400 text-end">
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ export default function ModuleList() {
|
|||||||
const [moduleNames] = useModuleNamesQuery();
|
const [moduleNames] = useModuleNamesQuery();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* {moduleNames.map((m) => (
|
{moduleNames.map((m) => (
|
||||||
<ExpandableModule key={m} moduleName={m} />
|
<ExpandableModule key={m} moduleName={m} />
|
||||||
))} */}
|
))}
|
||||||
<div className="flex flex-col justify-center">
|
<div className="flex flex-col justify-center">
|
||||||
<CreateModule />
|
<CreateModule />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export function AssignmentButtons({
|
|||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
const assignmentInCanvas = canvasAssignments.find(
|
const assignmentInCanvas = canvasAssignments?.find(
|
||||||
(a) => a.name === assignmentName
|
(a) => a.name === assignmentName
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ export function AssignmentButtons({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-3 justify-end">
|
<div className="flex flex-row gap-3 justify-end">
|
||||||
{anythingIsLoading && <Spinner />}
|
{anythingIsLoading && <Spinner />}
|
||||||
{assignmentInCanvas && !assignmentInCanvas.published && (
|
{assignmentInCanvas && !assignmentInCanvas?.published && (
|
||||||
<div className="text-rose-300 my-auto">Not Published</div>
|
<div className="text-rose-300 my-auto">Not Published</div>
|
||||||
)}
|
)}
|
||||||
{!assignmentInCanvas && (
|
{!assignmentInCanvas && (
|
||||||
@@ -125,8 +125,8 @@ export function AssignmentButtons({
|
|||||||
<div className="flex justify-around gap-3">
|
<div className="flex justify-around gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setIsLoading(true);
|
|
||||||
router.push(getCourseUrl(courseName));
|
router.push(getCourseUrl(courseName));
|
||||||
|
setIsLoading(true);
|
||||||
await deleteLocal.mutateAsync({
|
await deleteLocal.mutateAsync({
|
||||||
moduleName,
|
moduleName,
|
||||||
assignmentName,
|
assignmentName,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { baseCanvasUrl } from "@/services/canvas/canvasServiceUtils";
|
|||||||
import { getCourseUrl } from "@/services/urlUtils";
|
import { getCourseUrl } from "@/services/urlUtils";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
export default function EditPageButtons({
|
export default function EditPageButtons({
|
||||||
moduleName,
|
moduleName,
|
||||||
@@ -35,6 +35,7 @@ export default function EditPageButtons({
|
|||||||
const deletePageInCanvas = useDeleteCanvasPageMutation();
|
const deletePageInCanvas = useDeleteCanvasPageMutation();
|
||||||
const deletePageLocal = useDeletePageMutation();
|
const deletePageLocal = useDeletePageMutation();
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const pageInCanvas = canvasPages?.find((p) => p.title === pageName);
|
const pageInCanvas = canvasPages?.find((p) => p.title === pageName);
|
||||||
|
|
||||||
@@ -101,13 +102,14 @@ export default function EditPageButtons({
|
|||||||
<br />
|
<br />
|
||||||
<div className="flex justify-around gap-3">
|
<div className="flex justify-around gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
router.push(getCourseUrl(courseName));
|
setLoading(true);
|
||||||
deletePageLocal.mutate({
|
await deletePageLocal.mutateAsync({
|
||||||
moduleName,
|
moduleName,
|
||||||
pageName,
|
pageName,
|
||||||
courseName,
|
courseName,
|
||||||
});
|
});
|
||||||
|
router.push(getCourseUrl(courseName));
|
||||||
}}
|
}}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
>
|
>
|
||||||
@@ -115,6 +117,7 @@ export default function EditPageButtons({
|
|||||||
</button>
|
</button>
|
||||||
<button onClick={closeModal}>No</button>
|
<button onClick={closeModal}>No</button>
|
||||||
</div>
|
</div>
|
||||||
|
{loading && <Spinner />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export function QuizButtons({
|
|||||||
const deleteLocal = useDeleteQuizMutation();
|
const deleteLocal = useDeleteQuizMutation();
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
const quizInCanvas = canvasQuizzes.find((c) => c.title === quizName);
|
const quizInCanvas = canvasQuizzes?.find((c) => c.title === quizName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-5 flex flex-row justify-between">
|
<div className="p-5 flex flex-row justify-between">
|
||||||
@@ -90,8 +90,8 @@ export function QuizButtons({
|
|||||||
<div className="flex justify-around gap-3">
|
<div className="flex justify-around gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
await deleteLocal.mutateAsync({ moduleName, quizName, courseName });
|
||||||
router.push(getCourseUrl(courseName));
|
router.push(getCourseUrl(courseName));
|
||||||
deleteLocal.mutate({ moduleName, quizName, courseName });
|
|
||||||
}}
|
}}
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { useSetAssignmentGroupsMutation } from "@/hooks/canvas/canvasCourseHooks
|
|||||||
export default function AssignmentGroupManagement() {
|
export default function AssignmentGroupManagement() {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
const updateSettings = useUpdateLocalCourseSettingsMutation();
|
const updateSettings = useUpdateLocalCourseSettingsMutation();
|
||||||
const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId); // untested
|
// const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId); // untested
|
||||||
|
|
||||||
const [assignmentGroups, setAssignmentGroups] = useState<
|
const [assignmentGroups, setAssignmentGroups] = useState<
|
||||||
LocalAssignmentGroup[]
|
LocalAssignmentGroup[]
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ import { useEmptyDirectoriesQuery } from "@/hooks/localCourse/storageDirectoryHo
|
|||||||
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
||||||
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
|
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
|
||||||
import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType";
|
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 { getCourseUrl } from "@/services/urlUtils";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
@@ -47,6 +50,9 @@ export default function NewCourseForm() {
|
|||||||
const [selectedDirectory, setSelectedDirectory] = useState<
|
const [selectedDirectory, setSelectedDirectory] = useState<
|
||||||
string | undefined
|
string | undefined
|
||||||
>();
|
>();
|
||||||
|
const [courseToImport, setCourseToImport] = useState<
|
||||||
|
LocalCourseSettings | undefined
|
||||||
|
>();
|
||||||
const createCourse = useCreateLocalCourseMutation();
|
const createCourse = useCreateLocalCourseMutation();
|
||||||
|
|
||||||
const formIsComplete =
|
const formIsComplete =
|
||||||
@@ -71,17 +77,34 @@ export default function NewCourseForm() {
|
|||||||
setSelectedDirectory={setSelectedDirectory}
|
setSelectedDirectory={setSelectedDirectory}
|
||||||
selectedDaysOfWeek={selectedDaysOfWeek}
|
selectedDaysOfWeek={selectedDaysOfWeek}
|
||||||
setSelectedDaysOfWeek={setSelectedDaysOfWeek}
|
setSelectedDaysOfWeek={setSelectedDaysOfWeek}
|
||||||
|
courseToImport={courseToImport}
|
||||||
|
setCourseToImport={setCourseToImport}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</SuspenseAndErrorHandling>
|
</SuspenseAndErrorHandling>
|
||||||
<div className="m-3 text-center">
|
<div className="m-3 text-center">
|
||||||
<button
|
<button
|
||||||
disabled={!formIsComplete || createCourse.isPending}
|
disabled={!formIsComplete || createCourse.isPending}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
if (formIsComplete) {
|
if (formIsComplete) {
|
||||||
createCourse
|
const newSettings: LocalCourseSettings = courseToImport
|
||||||
.mutateAsync({
|
? {
|
||||||
settings: {
|
...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,
|
name: selectedDirectory,
|
||||||
assignmentGroups: [],
|
assignmentGroups: [],
|
||||||
daysOfWeek: selectedDaysOfWeek,
|
daysOfWeek: selectedDaysOfWeek,
|
||||||
@@ -96,11 +119,12 @@ export default function NewCourseForm() {
|
|||||||
defaultFileUploadTypes: ["pdf", "png", "jpg", "jpeg"],
|
defaultFileUploadTypes: ["pdf", "png", "jpg", "jpeg"],
|
||||||
defaultLockHoursOffset: 0,
|
defaultLockHoursOffset: 0,
|
||||||
holidays: [],
|
holidays: [],
|
||||||
},
|
};
|
||||||
})
|
await createCourse.mutateAsync({
|
||||||
.then(() => {
|
settings: newSettings,
|
||||||
router.push(getCourseUrl(selectedDirectory));
|
settingsFromCourseToImport: courseToImport,
|
||||||
});
|
});
|
||||||
|
router.push(getCourseUrl(selectedDirectory));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -125,6 +149,8 @@ function OtherSettings({
|
|||||||
setSelectedDirectory,
|
setSelectedDirectory,
|
||||||
selectedDaysOfWeek,
|
selectedDaysOfWeek,
|
||||||
setSelectedDaysOfWeek,
|
setSelectedDaysOfWeek,
|
||||||
|
courseToImport,
|
||||||
|
setCourseToImport,
|
||||||
}: {
|
}: {
|
||||||
selectedTerm: CanvasEnrollmentTermModel;
|
selectedTerm: CanvasEnrollmentTermModel;
|
||||||
selectedCanvasCourse: CanvasCourseModel | undefined;
|
selectedCanvasCourse: CanvasCourseModel | undefined;
|
||||||
@@ -137,15 +163,21 @@ function OtherSettings({
|
|||||||
>;
|
>;
|
||||||
selectedDaysOfWeek: DayOfWeek[];
|
selectedDaysOfWeek: DayOfWeek[];
|
||||||
setSelectedDaysOfWeek: React.Dispatch<React.SetStateAction<DayOfWeek[]>>;
|
setSelectedDaysOfWeek: React.Dispatch<React.SetStateAction<DayOfWeek[]>>;
|
||||||
|
courseToImport: LocalCourseSettings | undefined;
|
||||||
|
setCourseToImport: React.Dispatch<
|
||||||
|
React.SetStateAction<LocalCourseSettings | undefined>
|
||||||
|
>;
|
||||||
}) {
|
}) {
|
||||||
const { data: canvasCourses } = useCourseListInTermQuery(selectedTerm.id);
|
const { data: canvasCourses } = useCourseListInTermQuery(selectedTerm.id);
|
||||||
const [allSettings] = useLocalCoursesSettingsQuery();
|
const [allSettings] = useLocalCoursesSettingsQuery();
|
||||||
const [emptyDirectories] = useEmptyDirectoriesQuery();
|
const [emptyDirectories] = useEmptyDirectoriesQuery();
|
||||||
|
|
||||||
const populatedCanvasCourseIds = allSettings.map((s) => s.canvasId);
|
const populatedCanvasCourseIds = allSettings.map((s) => s.canvasId);
|
||||||
const availableCourses = canvasCourses.filter(
|
const availableCourses =
|
||||||
(canvas) => !populatedCanvasCourseIds.includes(canvas.id)
|
canvasCourses?.filter(
|
||||||
);
|
(canvas: CanvasCourseModel) =>
|
||||||
|
!populatedCanvasCourseIds.includes(canvas.id)
|
||||||
|
) ?? [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -183,6 +215,13 @@ function OtherSettings({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</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 Link from "next/link";
|
||||||
import { useCourseContext } from "../course/[courseName]/context/courseContext";
|
import { useCourseContext } from "../course/[courseName]/context/courseContext";
|
||||||
import { getLectureForDay } from "@/models/local/lectureUtils";
|
import { getLectureForDay } from "@/models/local/lectureUtils";
|
||||||
import { trpc } from "@/services/trpc/utils";
|
import { useLecturesSuspenseQuery as useLecturesQuery } from "@/hooks/localCourse/lectureHooks";
|
||||||
|
|
||||||
export default function OneCourseLectures() {
|
export default function OneCourseLectures() {
|
||||||
const { courseName } = useCourseContext();
|
const { courseName } = useCourseContext();
|
||||||
// const { data: weeks } = useLecturesByWeekQuery();
|
const [weeks] = useLecturesQuery();
|
||||||
const [weeks] = trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
|
||||||
|
|
||||||
const dayAsDate = new Date();
|
const dayAsDate = new Date();
|
||||||
const dayAsString = getDateOnlyMarkdownString(dayAsDate);
|
const dayAsString = getDateOnlyMarkdownString(dayAsDate);
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
|
import { canvasAssignmentService } from "@/services/canvas/canvasAssignmentService";
|
||||||
import { canvasService } from "@/services/canvas/canvasService";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import {
|
|
||||||
useMutation,
|
|
||||||
useQueryClient,
|
|
||||||
useSuspenseQueries,
|
|
||||||
useSuspenseQuery,
|
|
||||||
} from "@tanstack/react-query";
|
|
||||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||||
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||||
@@ -24,28 +18,12 @@ export const canvasAssignmentKeys = {
|
|||||||
export const useCanvasAssignmentsQuery = () => {
|
export const useCanvasAssignmentsQuery = () => {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
|
|
||||||
return useSuspenseQuery({
|
return useQuery({
|
||||||
queryKey: canvasAssignmentKeys.assignments(settings.canvasId),
|
queryKey: canvasAssignmentKeys.assignments(settings.canvasId),
|
||||||
queryFn: async () => canvasAssignmentService.getAll(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 = () => {
|
export const useAddAssignmentToCanvasMutation = () => {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
const { data: canvasModules } = useCanvasModulesQuery();
|
const { data: canvasModules } = useCanvasModulesQuery();
|
||||||
@@ -60,6 +38,11 @@ export const useAddAssignmentToCanvasMutation = () => {
|
|||||||
assignment: LocalAssignment;
|
assignment: LocalAssignment;
|
||||||
moduleName: string;
|
moduleName: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
if (!canvasModules) {
|
||||||
|
console.log("cannot add assignment until modules loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const assignmentGroup = settings.assignmentGroups.find(
|
const assignmentGroup = settings.assignmentGroups.find(
|
||||||
(g) => g.name === assignment.localAssignmentGroupName
|
(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 { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup";
|
||||||
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
|
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
|
||||||
import { canvasService } from "@/services/canvas/canvasService";
|
import { canvasService } from "@/services/canvas/canvasService";
|
||||||
import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
export const canvasCourseKeys = {
|
export const canvasCourseKeys = {
|
||||||
courseDetails: (canavasId: number) =>
|
courseDetails: (canavasId: number) =>
|
||||||
@@ -13,34 +15,37 @@ export const canvasCourseKeys = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useCourseListInTermQuery = (canvasTermId: number | undefined) =>
|
export const useCourseListInTermQuery = (canvasTermId: number | undefined) =>
|
||||||
useSuspenseQuery({
|
useQuery({
|
||||||
queryKey: canvasCourseKeys.courseListInTerm(canvasTermId),
|
queryKey: canvasCourseKeys.courseListInTerm(canvasTermId),
|
||||||
queryFn: async () =>
|
queryFn: async (): Promise<CanvasCourseModel[]> =>
|
||||||
canvasTermId ? await canvasService.getCourses(canvasTermId) : [],
|
canvasTermId ? await canvasService.getCourses(canvasTermId) : [],
|
||||||
|
enabled: !!canvasTermId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useCanvasCourseQuery = (canvasId: number) =>
|
// export const useCanvasCourseQuery = (canvasId: number) =>
|
||||||
useSuspenseQuery({
|
// useQuery({
|
||||||
queryKey: canvasCourseKeys.courseDetails(canvasId),
|
// queryKey: canvasCourseKeys.courseDetails(canvasId),
|
||||||
queryFn: async () => await canvasService.getCourse(canvasId),
|
// queryFn: async () => await canvasService.getCourse(canvasId),
|
||||||
});
|
// });
|
||||||
|
|
||||||
export const useSetAssignmentGroupsMutation = (canvasId: number) => {
|
export const useSetAssignmentGroupsMutation = (canvasId: number) => {
|
||||||
const { data: canvasAssignmentGroups } = useAssignmentGroupsQuery(canvasId);
|
const { data: canvasAssignmentGroups } = useAssignmentGroupsQuery(canvasId);
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (localAssignmentGroups: LocalAssignmentGroup[]) => {
|
mutationFn: async (localAssignmentGroups: LocalAssignmentGroup[]) => {
|
||||||
|
if (!canvasAssignmentGroups) return;
|
||||||
|
|
||||||
const localNames = localAssignmentGroups.map((g) => g.name);
|
const localNames = localAssignmentGroups.map((g) => g.name);
|
||||||
const groupsToDelete = canvasAssignmentGroups.filter(
|
const groupsToDelete = canvasAssignmentGroups.filter(
|
||||||
(c) => !localNames.includes(c.name)
|
(c: CanvasAssignmentGroup) => !localNames.includes(c.name)
|
||||||
);
|
);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
...groupsToDelete.map(
|
...groupsToDelete.map(
|
||||||
async (g) =>
|
async (g: CanvasAssignmentGroup) =>
|
||||||
await canvasAssignmentGroupService.delete(canvasId, g.id, g.name)
|
await canvasAssignmentGroupService.delete(canvasId, g.id, g.name)
|
||||||
),
|
),
|
||||||
...localAssignmentGroups.map(async (group) => {
|
...localAssignmentGroups.map(async (group) => {
|
||||||
const canvasGroup = canvasAssignmentGroups.find(
|
const canvasGroup = canvasAssignmentGroups.find(
|
||||||
(c) => c.name === group.name
|
(c: CanvasAssignmentGroup) => c.name === group.name
|
||||||
);
|
);
|
||||||
if (!canvasGroup) {
|
if (!canvasGroup) {
|
||||||
await canvasAssignmentGroupService.create(canvasId, group);
|
await canvasAssignmentGroupService.create(canvasId, group);
|
||||||
@@ -55,8 +60,8 @@ export const useSetAssignmentGroupsMutation = (canvasId: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useAssignmentGroupsQuery = (canvasId: number) => {
|
export const useAssignmentGroupsQuery = (canvasId: number) => {
|
||||||
return useSuspenseQuery({
|
return useQuery({
|
||||||
queryKey: canvasCourseKeys.assignmentGroups(canvasId),
|
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 { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||||
import {
|
import {
|
||||||
useMutation,
|
useMutation,
|
||||||
|
useQuery,
|
||||||
useQueryClient,
|
useQueryClient,
|
||||||
useSuspenseQuery,
|
|
||||||
} from "@tanstack/react-query";
|
} from "@tanstack/react-query";
|
||||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ export const canvasCourseModuleKeys = {
|
|||||||
|
|
||||||
export const useCanvasModulesQuery = () => {
|
export const useCanvasModulesQuery = () => {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
return useSuspenseQuery({
|
return useQuery({
|
||||||
queryKey: canvasCourseModuleKeys.modules(settings.canvasId),
|
queryKey: canvasCourseModuleKeys.modules(settings.canvasId),
|
||||||
queryFn: async () =>
|
queryFn: async () =>
|
||||||
await canvasModuleService.getCourseModules(settings.canvasId),
|
await canvasModuleService.getCourseModules(settings.canvasId),
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||||
import { canvasPageService } from "@/services/canvas/canvasPageService";
|
import { canvasPageService } from "@/services/canvas/canvasPageService";
|
||||||
import {
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
useMutation,
|
|
||||||
useQueryClient,
|
|
||||||
useSuspenseQuery,
|
|
||||||
} from "@tanstack/react-query";
|
|
||||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||||
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
import { canvasModuleService } from "@/services/canvas/canvasModuleService";
|
||||||
import {
|
import {
|
||||||
@@ -22,7 +18,7 @@ export const canvasPageKeys = {
|
|||||||
|
|
||||||
export const useCanvasPagesQuery = () => {
|
export const useCanvasPagesQuery = () => {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
return useSuspenseQuery({
|
return useQuery({
|
||||||
queryKey: canvasPageKeys.pagesInCourse(settings.canvasId),
|
queryKey: canvasPageKeys.pagesInCourse(settings.canvasId),
|
||||||
queryFn: async () => await canvasPageService.getAll(settings.canvasId),
|
queryFn: async () => await canvasPageService.getAll(settings.canvasId),
|
||||||
});
|
});
|
||||||
@@ -42,6 +38,10 @@ export const useCreateCanvasPageMutation = () => {
|
|||||||
page: LocalCoursePage;
|
page: LocalCoursePage;
|
||||||
moduleName: string;
|
moduleName: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
if (!canvasModules) {
|
||||||
|
console.log("cannot add page until modules loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const canvasPage = await canvasPageService.create(
|
const canvasPage = await canvasPageService.create(
|
||||||
settings.canvasId,
|
settings.canvasId,
|
||||||
page
|
page
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
useMutation,
|
useMutation,
|
||||||
|
useQuery,
|
||||||
useQueryClient,
|
useQueryClient,
|
||||||
useSuspenseQuery,
|
|
||||||
} from "@tanstack/react-query";
|
} from "@tanstack/react-query";
|
||||||
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
|
||||||
import { canvasQuizService } from "@/services/canvas/canvasQuizService";
|
import { canvasQuizService } from "@/services/canvas/canvasQuizService";
|
||||||
@@ -20,7 +20,7 @@ export const canvasQuizKeys = {
|
|||||||
export const useCanvasQuizzesQuery = () => {
|
export const useCanvasQuizzesQuery = () => {
|
||||||
const [settings] = useLocalCourseSettingsQuery();
|
const [settings] = useLocalCourseSettingsQuery();
|
||||||
|
|
||||||
return useSuspenseQuery({
|
return useQuery({
|
||||||
queryKey: canvasQuizKeys.quizzes(settings.canvasId),
|
queryKey: canvasQuizKeys.quizzes(settings.canvasId),
|
||||||
queryFn: async () => canvasQuizService.getAll(settings.canvasId),
|
queryFn: async () => canvasQuizService.getAll(settings.canvasId),
|
||||||
});
|
});
|
||||||
@@ -40,6 +40,10 @@ export const useAddQuizToCanvasMutation = () => {
|
|||||||
quiz: LocalQuiz;
|
quiz: LocalQuiz;
|
||||||
moduleName: string;
|
moduleName: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
if (!canvasModules) {
|
||||||
|
console.log("cannot add quiz until modules loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const assignmentGroup = settings.assignmentGroups.find(
|
const assignmentGroup = settings.assignmentGroups.find(
|
||||||
(g) => g.name === quiz.localAssignmentGroupName
|
(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();
|
const { courseName } = useCourseContext();
|
||||||
console.log("rendering all assignments query");
|
console.log("rendering all assignments query");
|
||||||
return trpc.assignment.getAllAssignments.useSuspenseQuery({
|
return trpc.assignment.getAllAssignments.useSuspenseQuery(
|
||||||
moduleName,
|
{
|
||||||
courseName,
|
moduleName,
|
||||||
});
|
courseName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (assignments) => assignments.map((a) => a.name),
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdateAssignmentMutation = () => {
|
export const useUpdateAssignmentMutation = () => {
|
||||||
@@ -57,8 +62,18 @@ export const useCreateAssignmentMutation = () => {
|
|||||||
export const useDeleteAssignmentMutation = () => {
|
export const useDeleteAssignmentMutation = () => {
|
||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.assignment.deleteAssignment.useMutation({
|
return trpc.assignment.deleteAssignment.useMutation({
|
||||||
onSuccess: (_, { courseName, moduleName }) => {
|
onSuccess: (_, { courseName, moduleName, assignmentName }) => {
|
||||||
utils.assignment.getAllAssignments.invalidate({ courseName, moduleName });
|
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";
|
import { trpc } from "@/services/trpc/utils";
|
||||||
|
|
||||||
|
export const useLecturesSuspenseQuery = () => {
|
||||||
|
const { courseName } = useCourseContext();
|
||||||
|
return trpc.lectures.getLectures.useSuspenseQuery({ courseName });
|
||||||
|
};
|
||||||
|
|
||||||
export const useLectureUpdateMutation = () => {
|
export const useLectureUpdateMutation = () => {
|
||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.lectures.updateLecture.useMutation({
|
return trpc.lectures.updateLecture.useMutation({
|
||||||
|
|||||||
@@ -41,7 +41,12 @@ export const useDeletePageMutation = () => {
|
|||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.page.deletePage.useMutation({
|
return trpc.page.deletePage.useMutation({
|
||||||
onSuccess: (_, { courseName, moduleName, pageName }) => {
|
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 });
|
utils.page.getPage.invalidate({ courseName, moduleName, pageName });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ export const useDeleteQuizMutation = () => {
|
|||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
return trpc.quiz.deleteQuiz.useMutation({
|
return trpc.quiz.deleteQuiz.useMutation({
|
||||||
onSuccess: (_, { courseName, moduleName, quizName }) => {
|
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 });
|
utils.quiz.getQuiz.invalidate({ courseName, moduleName, quizName });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { LocalAssignment } from "./assignment/localAssignment";
|
import { LocalAssignment } from "./assignment/localAssignment";
|
||||||
|
import { Lecture } from "./lecture";
|
||||||
import { LocalCoursePage } from "./page/localCoursePage";
|
import { LocalCoursePage } from "./page/localCoursePage";
|
||||||
import { LocalQuiz } from "./quiz/localQuiz";
|
import { LocalQuiz } from "./quiz/localQuiz";
|
||||||
import {
|
import {
|
||||||
dateToMarkdownString,
|
dateToMarkdownString,
|
||||||
getDateFromString,
|
|
||||||
getDateFromStringOrThrow,
|
getDateFromStringOrThrow,
|
||||||
getDateOnlyMarkdownString,
|
|
||||||
} from "./timeUtils";
|
} from "./timeUtils";
|
||||||
|
|
||||||
export const prepAssignmentForNewSemester = (
|
export const prepAssignmentForNewSemester = (
|
||||||
@@ -69,6 +68,24 @@ export const prepPageForNewSemester = (
|
|||||||
page.dueAt,
|
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 replaceClassroomUrl = (value: string) => {
|
||||||
const classroomPattern =
|
const classroomPattern =
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { LocalAssignment } from "../assignment/localAssignment";
|
import { LocalAssignment } from "../assignment/localAssignment";
|
||||||
import { prepAssignmentForNewSemester, prepPageForNewSemester, prepQuizForNewSemester } from "../semesterTransferUtils";
|
import {
|
||||||
|
prepAssignmentForNewSemester,
|
||||||
|
prepLectureForNewSemester,
|
||||||
|
prepPageForNewSemester,
|
||||||
|
prepQuizForNewSemester,
|
||||||
|
} from "../semesterTransferUtils";
|
||||||
import { LocalQuiz } from "../quiz/localQuiz";
|
import { LocalQuiz } from "../quiz/localQuiz";
|
||||||
import { LocalCoursePage } from "../page/localCoursePage";
|
import { LocalCoursePage } from "../page/localCoursePage";
|
||||||
|
import { Lecture } from "../lecture";
|
||||||
|
|
||||||
describe("can take an assignment and template it for a new semester", () => {
|
describe("can take an assignment and template it for a new semester", () => {
|
||||||
it("can sanitize assignment github classroom repo url", () => {
|
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");
|
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,
|
getDayOfWeek,
|
||||||
LocalCourseSettings,
|
LocalCourseSettings,
|
||||||
} from "@/models/local/localCourseSettings";
|
} from "@/models/local/localCourseSettings";
|
||||||
import { getWeekNumber } from "@/app/course/[courseName]/calendar/calendarMonthUtils";
|
|
||||||
import { getDateFromStringOrThrow } from "@/models/local/timeUtils";
|
import { getDateFromStringOrThrow } from "@/models/local/timeUtils";
|
||||||
|
|
||||||
export async function getLectures(courseName: string) {
|
export async function getLectures(courseName: string) {
|
||||||
|
|||||||
@@ -3,6 +3,17 @@ import { z } from "zod";
|
|||||||
import { router } from "../trpc";
|
import { router } from "../trpc";
|
||||||
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
|
||||||
import { zodLocalCourseSettings } from "@/models/local/localCourseSettings";
|
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({
|
export const settingsRouter = router({
|
||||||
allCoursesSettings: publicProcedure.query(async () => {
|
allCoursesSettings: publicProcedure.query(async () => {
|
||||||
@@ -25,6 +36,117 @@ export const settingsRouter = router({
|
|||||||
return s;
|
return s;
|
||||||
}),
|
}),
|
||||||
createCourse: publicProcedure
|
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(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
settings: zodLocalCourseSettings,
|
settings: zodLocalCourseSettings,
|
||||||
@@ -36,17 +158,4 @@ export const settingsRouter = router({
|
|||||||
settings
|
settings
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
updateSettings: publicProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
settings: zodLocalCourseSettings,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.mutation(async ({ input: { settings } }) => {
|
|
||||||
await fileStorageService.settings.updateCourseSettings(
|
|
||||||
settings.name,
|
|
||||||
settings
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
|
|||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
GET https://snow.instructure.com/api/v1/courses/871954/assignments
|
GET https://snow.instructure.com/api/v1/courses/1013058/assignments
|
||||||
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
|
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
GET https://snow.instructure.com/api/v1/courses/958185/quizzes
|
GET https://snow.instructure.com/api/v1/courses/1013058/quizzes
|
||||||
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
|
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|||||||
Reference in New Issue
Block a user