diff --git a/nextjs/src/app/course/[courseName]/calendar/CourseCalendar.tsx b/nextjs/src/app/course/[courseName]/calendar/CourseCalendar.tsx
index 26bd53f..66e6c79 100644
--- a/nextjs/src/app/course/[courseName]/calendar/CourseCalendar.tsx
+++ b/nextjs/src/app/course/[courseName]/calendar/CourseCalendar.tsx
@@ -28,7 +28,7 @@ export default function CourseCalendar() {
h-full
overflow-y-scroll
border-4
- border-slate-600
+ border-gray-900
rounded-xl
bg-slate-950
"
diff --git a/nextjs/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx b/nextjs/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx
index 65fbb00..1eec857 100644
--- a/nextjs/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx
+++ b/nextjs/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx
@@ -7,6 +7,14 @@ import {
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
import { useEffect, useState } from "react";
import QuizPreview from "./QuizPreview";
+import {
+ useAddQuizToCanvasMutation,
+ useCanvasQuizzesQuery,
+ useDeleteQuizFromCanvasMutation,
+} from "@/hooks/canvas/canvasQuizHooks";
+import { Spinner } from "@/components/Spinner";
+import { baseCanvasUrl, canvasApi } from "@/services/canvas/canvasServiceUtils";
+import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
export default function EditQuiz({
moduleName,
@@ -59,11 +67,54 @@ export default function EditQuiz({
-
-
-
+
+
+ );
+}
+
+function QuizButtons({
+ moduleName,
+ quizName,
+}: {
+ quizName: string;
+ moduleName: string;
+}) {
+ const { data: canvasQuizzes } = useCanvasQuizzesQuery();
+ const { data: quiz } = useQuizQuery(moduleName, quizName);
+ const { data: settings } = useLocalCourseSettingsQuery();
+ const addToCanvas = useAddQuizToCanvasMutation();
+ const deleteFromCanvas = useDeleteQuizFromCanvasMutation();
+
+ const quizInCanvas = canvasQuizzes.find((c) => c.title === quizName);
+
+ return (
+
+ {!quizInCanvas && (
+
+ )}
+ {quizInCanvas && (
+
+ View in Canvas
+
+ )}
+ {quizInCanvas && (
+
+ )}
+ {(addToCanvas.isPending || deleteFromCanvas.isPending) &&
}
);
}
diff --git a/nextjs/src/hooks/canvas/canvasQuizHooks.ts b/nextjs/src/hooks/canvas/canvasQuizHooks.ts
index 61abdf1..be71d95 100644
--- a/nextjs/src/hooks/canvas/canvasQuizHooks.ts
+++ b/nextjs/src/hooks/canvas/canvasQuizHooks.ts
@@ -1,8 +1,62 @@
-
+import {
+ useMutation,
+ useQueryClient,
+ useSuspenseQuery,
+} from "@tanstack/react-query";
+import { useLocalCourseSettingsQuery } from "../localCourse/localCoursesHooks";
+import { canvasQuizService } from "@/services/canvas/canvasQuizService";
+import { LocalQuiz } from "@/models/local/quiz/localQuiz";
export const canvasQuizKeys = {
- quizzes: (canvasCourseId: number )=> ["canvas", canvasCourseId, "quizzes"],
-}
+ quizzes: (canvasCourseId: number) => ["canvas", canvasCourseId, "quizzes"],
+};
+export const useCanvasQuizzesQuery = () => {
+ const { data: settings } = useLocalCourseSettingsQuery();
-export const useCanvasQuizQuery
\ No newline at end of file
+ return useSuspenseQuery({
+ queryKey: canvasQuizKeys.quizzes(settings.canvasId),
+ queryFn: async () => canvasQuizService.getAll(settings.canvasId),
+ });
+};
+
+export const useAddQuizToCanvasMutation = () => {
+ const { data: settings } = useLocalCourseSettingsQuery();
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async (quiz: LocalQuiz) => {
+ const assignmentGroup = settings.assignmentGroups.find(
+ (g) => g.name === quiz.localAssignmentGroupName
+ );
+ console.log("starting");
+ await canvasQuizService.create(
+ settings.canvasId,
+ quiz,
+ assignmentGroup?.canvasId
+ );
+ console.log("ending");
+ },
+ onSuccess: () => {
+ console.log("invalidating");
+ queryClient.invalidateQueries({
+ queryKey: canvasQuizKeys.quizzes(settings.canvasId),
+ });
+ },
+ });
+};
+
+export const useDeleteQuizFromCanvasMutation = () => {
+ const { data: settings } = useLocalCourseSettingsQuery();
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: async (canvasQuizId: number) => {
+ await canvasQuizService.delete(settings.canvasId, canvasQuizId);
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: canvasQuizKeys.quizzes(settings.canvasId),
+ });
+ },
+ });
+};
diff --git a/nextjs/src/models/canvas/quizzes/canvasQuizAnswerModel.ts b/nextjs/src/models/canvas/quizzes/canvasQuizAnswerModel.ts
new file mode 100644
index 0000000..2f66a9d
--- /dev/null
+++ b/nextjs/src/models/canvas/quizzes/canvasQuizAnswerModel.ts
@@ -0,0 +1,19 @@
+export interface CanvasQuizAnswer {
+ id: number;
+ text: string;
+ html?: string;
+ weight: number;
+ // comments?: string;
+ // text_after_answers?: string;
+ // answer_match_left?: string;
+ // answer_match_right?: string;
+ // matching_answer_incorrect_matches?: string;
+ // numerical_answer_type?: string;
+ // exact?: number;
+ // margin?: number;
+ // approximate?: number;
+ // precision?: number;
+ // start?: number;
+ // end?: number;
+ // blank_id?: number;
+}
diff --git a/nextjs/src/models/canvas/quizzes/canvasQuizQuestionModel.ts b/nextjs/src/models/canvas/quizzes/canvasQuizQuestionModel.ts
new file mode 100644
index 0000000..eab3572
--- /dev/null
+++ b/nextjs/src/models/canvas/quizzes/canvasQuizQuestionModel.ts
@@ -0,0 +1,14 @@
+import { CanvasQuizAnswer } from "./canvasQuizAnswerModel";
+
+export interface CanvasQuizQuestion {
+ id: number;
+ quiz_id: number;
+ position?: number;
+ question_name: string;
+ question_type: string;
+ question_text: string;
+ correct_comments: string;
+ incorrect_comments: string;
+ neutral_comments: string;
+ answers?: CanvasQuizAnswer[];
+}
\ No newline at end of file
diff --git a/nextjs/src/services/canvas/canvasAssignmentGroupService.ts b/nextjs/src/services/canvas/canvasAssignmentGroupService.ts
index 7fc285a..2237bc7 100644
--- a/nextjs/src/services/canvas/canvasAssignmentGroupService.ts
+++ b/nextjs/src/services/canvas/canvasAssignmentGroupService.ts
@@ -1,14 +1,13 @@
-import { baseCanvasUrl, canvasServiceUtils } from "./canvasServiceUtils";
+import { canvasApi, canvasServiceUtils } from "./canvasServiceUtils";
import { axiosClient } from "../axiosUtils";
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup";
import { rateLimitAwareDelete } from "./canvasWebRequestor";
-
export const canvasAssignmentGroupService = {
async getAll(courseId: number): Promise {
console.log("Requesting assignment groups");
- const url = `${baseCanvasUrl}/courses/${courseId}/assignment_groups`;
+ const url = `${canvasApi}/courses/${courseId}/assignment_groups`;
const assignmentGroups = await canvasServiceUtils.paginatedRequest<
CanvasAssignmentGroup[]
>({
@@ -22,7 +21,7 @@ export const canvasAssignmentGroupService = {
localAssignmentGroup: LocalAssignmentGroup
): Promise {
console.log(`Creating assignment group: ${localAssignmentGroup.name}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/assignment_groups`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/assignment_groups`;
const body = {
name: localAssignmentGroup.name,
group_weight: localAssignmentGroup.weight,
@@ -45,7 +44,7 @@ export const canvasAssignmentGroupService = {
if (!localAssignmentGroup.canvasId) {
throw new Error("Cannot update assignment group if canvas ID is null");
}
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/assignment_groups/${localAssignmentGroup.canvasId}`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/assignment_groups/${localAssignmentGroup.canvasId}`;
const body = {
name: localAssignmentGroup.name,
group_weight: localAssignmentGroup.weight,
@@ -56,11 +55,11 @@ export const canvasAssignmentGroupService = {
async delete(
canvasCourseId: number,
- canvasAssignmentGroupId: number
- , assignmentGroupName: string
+ canvasAssignmentGroupId: number,
+ assignmentGroupName: string
): Promise {
console.log(`Deleting assignment group: ${assignmentGroupName}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/assignment_groups/${canvasAssignmentGroupId}`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/assignment_groups/${canvasAssignmentGroupId}`;
await rateLimitAwareDelete(url);
},
};
diff --git a/nextjs/src/services/canvas/canvasAssignmentService.ts b/nextjs/src/services/canvas/canvasAssignmentService.ts
index 9503cf7..41a82ae 100644
--- a/nextjs/src/services/canvas/canvasAssignmentService.ts
+++ b/nextjs/src/services/canvas/canvasAssignmentService.ts
@@ -1,5 +1,5 @@
import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment";
-import { baseCanvasUrl, canvasServiceUtils } from "./canvasServiceUtils";
+import { canvasApi, canvasServiceUtils } from "./canvasServiceUtils";
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
import { axiosClient } from "../axiosUtils";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
@@ -8,17 +8,15 @@ import { assignmentPoints } from "@/models/local/assignment/utils/assignmentPoin
export const canvasAssignmentService = {
async getAll(courseId: number): Promise {
- const url = `courses/${courseId}/assignments`;
- const assignments = await canvasServiceUtils.paginatedRequest<
- CanvasAssignment[]
- >({ url });
- return assignments.flatMap((assignments) =>
- assignments.map((a) => ({
- ...a,
- due_at: a.due_at ? new Date(a.due_at).toLocaleString() : undefined, // timezones?
- lock_at: a.lock_at ? new Date(a.lock_at).toLocaleString() : undefined, // timezones?
- }))
+ const url = `${canvasApi}/courses/${courseId}/assignments`;
+ const { data: assignments } = await axiosClient.get(
+ url
);
+ return assignments.map((a) => ({
+ ...a,
+ due_at: a.due_at ? new Date(a.due_at).toLocaleString() : undefined, // timezones?
+ lock_at: a.lock_at ? new Date(a.lock_at).toLocaleString() : undefined, // timezones?
+ }));
},
async create(
@@ -27,7 +25,7 @@ export const canvasAssignmentService = {
canvasAssignmentGroupId?: number
): Promise {
console.log(`Creating assignment: ${localAssignment.name}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/assignments`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/assignments`;
const body = {
assignment: {
name: localAssignment.name,
@@ -66,7 +64,7 @@ export const canvasAssignmentService = {
canvasAssignmentGroupId?: number
): Promise {
console.log(`Updating assignment: ${localAssignment.name}`);
- const url = `${baseCanvasUrl}/courses/${courseId}/assignments/${canvasAssignmentId}`;
+ const url = `${canvasApi}/courses/${courseId}/assignments/${canvasAssignmentId}`;
const body = {
assignment: {
name: localAssignment.name,
@@ -94,7 +92,7 @@ export const canvasAssignmentService = {
assignmentName: string
): Promise {
console.log(`Deleting assignment from Canvas: ${assignmentName}`);
- const url = `${baseCanvasUrl}/courses/${courseId}/assignments/${assignmentCanvasId}`;
+ const url = `${canvasApi}/courses/${courseId}/assignments/${assignmentCanvasId}`;
const response = await axiosClient.delete(url);
if (!response.status.toString().startsWith("2")) {
@@ -134,7 +132,7 @@ export const canvasAssignmentService = {
},
};
- const rubricUrl = `${baseCanvasUrl}/courses/${courseId}/rubrics`;
+ const rubricUrl = `${canvasApi}/courses/${courseId}/rubrics`;
const rubricResponse = await axiosClient.post(
rubricUrl,
rubricBody
@@ -142,7 +140,7 @@ export const canvasAssignmentService = {
if (!rubricResponse.data) throw new Error("Failed to create rubric");
- const assignmentPointAdjustmentUrl = `${baseCanvasUrl}/courses/${courseId}/assignments/${assignmentCanvasId}`;
+ const assignmentPointAdjustmentUrl = `${canvasApi}/courses/${courseId}/assignments/${assignmentCanvasId}`;
const assignmentPointAdjustmentBody = {
assignment: { points_possible: assignmentPoints(localAssignment) },
};
diff --git a/nextjs/src/services/canvas/canvasModuleService.ts b/nextjs/src/services/canvas/canvasModuleService.ts
index cd40fd3..23d15b2 100644
--- a/nextjs/src/services/canvas/canvasModuleService.ts
+++ b/nextjs/src/services/canvas/canvasModuleService.ts
@@ -1,7 +1,7 @@
import { CanvasModuleItem } from "@/models/canvas/modules/canvasModuleItems";
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { axiosClient } from "../axiosUtils";
-import { baseCanvasUrl } from "./canvasServiceUtils";
+import { canvasApi } from "./canvasServiceUtils";
import { CanvasModule } from "@/models/canvas/modules/canvasModule";
export const canvasModuleService = {
@@ -11,7 +11,7 @@ export const canvasModuleService = {
item: CanvasModuleItem
) {
console.log(`Updating module item ${item.title}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/modules/${canvasModuleId}/items/${item.id}`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/modules/${canvasModuleId}/items/${item.id}`;
const body = {
module_item: { title: item.title, position: item.position },
};
@@ -28,7 +28,7 @@ export const canvasModuleService = {
contentId: number | string
): Promise {
console.log(`Creating new module item ${title}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/modules/${canvasModuleId}/items`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/modules/${canvasModuleId}/items`;
const body = { module_item: { title, type, content_id: contentId } };
await axiosClient.post(url, body);
},
@@ -40,7 +40,7 @@ export const canvasModuleService = {
canvasPage: CanvasPage
): Promise {
console.log(`Creating new module item ${title}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/modules/${canvasModuleId}/items`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/modules/${canvasModuleId}/items`;
const body = {
module_item: { title, type: "Page", page_url: canvasPage.url },
};
@@ -48,13 +48,13 @@ export const canvasModuleService = {
},
async getCourseModules(canvasCourseId: number) {
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/modules`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/modules`;
const response = await axiosClient.get(url);
return response.data;
},
async createModule(canvasCourseId: number, moduleName: string) {
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/modules`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/modules`;
const body = {
module: {
name: moduleName,
diff --git a/nextjs/src/services/canvas/canvasPageService.ts b/nextjs/src/services/canvas/canvasPageService.ts
index 6fdadc1..5561bd4 100644
--- a/nextjs/src/services/canvas/canvasPageService.ts
+++ b/nextjs/src/services/canvas/canvasPageService.ts
@@ -1,15 +1,14 @@
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
-import { baseCanvasUrl, canvasServiceUtils } from "./canvasServiceUtils";
+import { canvasApi, canvasServiceUtils } from "./canvasServiceUtils";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { axiosClient } from "../axiosUtils";
import { rateLimitAwareDelete } from "./canvasWebRequestor";
-
export const canvasPageService = {
async getAll(courseId: number): Promise {
console.log("requesting pages");
- const url = `${baseCanvasUrl}/courses/${courseId}/pages`;
+ const url = `${canvasApi}/courses/${courseId}/pages`;
const pages = await canvasServiceUtils.paginatedRequest({
url,
});
@@ -21,7 +20,7 @@ export const canvasPageService = {
page: LocalCoursePage
): Promise {
console.log(`Creating course page: ${page.name}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/pages`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/pages`;
const body = {
wiki_page: {
title: page.name,
@@ -42,7 +41,7 @@ export const canvasPageService = {
page: LocalCoursePage
): Promise {
console.log(`Updating course page: ${page.name}`);
- const url = `${baseCanvasUrl}/courses/${courseId}/pages/${canvasPageId}`;
+ const url = `${canvasApi}/courses/${courseId}/pages/${canvasPageId}`;
const body = {
wiki_page: {
title: page.name,
@@ -54,7 +53,7 @@ export const canvasPageService = {
async delete(courseId: number, canvasPageId: number): Promise {
console.log(`Deleting page from canvas ${canvasPageId}`);
- const url = `${baseCanvasUrl}/courses/${courseId}/pages/${canvasPageId}`;
+ const url = `${canvasApi}/courses/${courseId}/pages/${canvasPageId}`;
await rateLimitAwareDelete(url);
},
};
diff --git a/nextjs/src/services/canvas/canvasQuizService.ts b/nextjs/src/services/canvas/canvasQuizService.ts
index 0ca3ad6..a3b545c 100644
--- a/nextjs/src/services/canvas/canvasQuizService.ts
+++ b/nextjs/src/services/canvas/canvasQuizService.ts
@@ -1,27 +1,38 @@
import { CanvasQuiz } from "@/models/canvas/quizzes/canvasQuizModel";
import { axiosClient } from "../axiosUtils";
-import { baseCanvasUrl } from "./canvasServiceUtils";
+import { canvasApi } from "./canvasServiceUtils";
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { markdownToHTMLSafe } from "../htmlMarkdownUtils";
import { getDateFromStringOrThrow } from "@/models/local/timeUtils";
import { canvasAssignmentService } from "./canvasAssignmentService";
-import { LocalQuizQuestion } from "@/models/local/quiz/localQuizQuestion";
+import {
+ LocalQuizQuestion,
+ QuestionType,
+} from "@/models/local/quiz/localQuizQuestion";
+import { CanvasQuizQuestion } from "@/models/canvas/quizzes/canvasQuizQuestionModel";
const getAnswers = (question: LocalQuizQuestion) => {
- return question.answers.map((answer: any) => ({
- answer_html: answer.htmlText,
+ if (question.questionType === QuestionType.MATCHING)
+ return question.answers.map((a) => ({
+ answer_match_left: a.text,
+ answer_match_right: a.matchedText,
+ }));
+
+ return question.answers.map((answer) => ({
+ answer_html: markdownToHTMLSafe(answer.text),
answer_weight: answer.correct ? 100 : 0,
}));
};
+
const createQuestionOnly = async (
canvasCourseId: number,
canvasQuizId: number,
question: LocalQuizQuestion,
position: number
-): Promise<{ question: any; position: number }> => {
- console.log("Creating individual question", question);
+) => {
+ console.log("Creating individual question"); //, question);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/quizzes/${canvasQuizId}/questions`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/quizzes/${canvasQuizId}/questions`;
const body = {
question: {
question_text: markdownToHTMLSafe(question.text),
@@ -32,7 +43,7 @@ const createQuestionOnly = async (
},
};
- const response = await axiosClient.post(url, body);
+ const response = await axiosClient.post(url, body);
const newQuestion = response.data;
if (!newQuestion) throw new Error("Created question is null");
@@ -52,7 +63,7 @@ const hackFixQuestionOrdering = async (
id: qp.question.id.toString(),
}));
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/quizzes/${canvasQuizId}/reorder`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/quizzes/${canvasQuizId}/reorder`;
await axiosClient.post(url, { order });
};
@@ -65,21 +76,43 @@ const hackFixRedundantAssignments = async (canvasCourseId: number) => {
assignment.submission_types.includes("online_quiz")
);
- const deletionTasks = assignmentsToDelete.map((assignment) =>
- canvasAssignmentService.delete(
- canvasCourseId,
- assignment.id,
- assignment.name
+ await Promise.all(
+ assignmentsToDelete.map(
+ async (assignment) =>
+ await canvasAssignmentService.delete(
+ canvasCourseId,
+ assignment.id,
+ assignment.name
+ )
)
);
- await Promise.all(deletionTasks);
console.log(`Deleted ${assignmentsToDelete.length} redundant assignments`);
};
+const createQuizQuestions = async (
+ canvasCourseId: number,
+ canvasQuizId: number,
+ localQuiz: LocalQuiz
+) => {
+ console.log("Creating quiz questions"); //, localQuiz);
+
+ const tasks = localQuiz.questions.map(
+ async (question, index) =>
+ await createQuestionOnly(canvasCourseId, canvasQuizId, question, index)
+ );
+ const questionAndPositions = await Promise.all(tasks);
+ await hackFixQuestionOrdering(
+ canvasCourseId,
+ canvasQuizId,
+ questionAndPositions
+ );
+ await hackFixRedundantAssignments(canvasCourseId);
+};
+
export const canvasQuizService = {
async getAll(canvasCourseId: number): Promise {
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/quizzes`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/quizzes`;
const response = await axiosClient.get(url);
return response.data.map((quiz) => ({
...quiz,
@@ -97,7 +130,7 @@ export const canvasQuizService = {
): Promise {
console.log("Creating quiz", localQuiz);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/quizzes`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/quizzes`;
const body = {
quiz: {
title: localQuiz.name,
@@ -124,31 +157,14 @@ export const canvasQuizService = {
},
};
- const response = await axiosClient.post(url, body);
- const canvasQuiz: CanvasQuiz = response.data;
-
+ const { data: canvasQuiz } = await axiosClient.post(url, body);
if (!canvasQuiz) throw new Error("Created quiz is null");
- await this.createQuizQuestions(canvasCourseId, canvasQuiz.id, localQuiz);
+ await createQuizQuestions(canvasCourseId, canvasQuiz.id, localQuiz);
return canvasQuiz.id;
},
-
- async createQuizQuestions(
- canvasCourseId: number,
- canvasQuizId: number,
- localQuiz: LocalQuiz
- ) {
- console.log("Creating quiz questions", localQuiz);
-
- const tasks = localQuiz.questions.map((question, index) =>
- createQuestionOnly(canvasCourseId, canvasQuizId, question, index)
- );
- const questionAndPositions = await Promise.all(tasks);
- await hackFixQuestionOrdering(
- canvasCourseId,
- canvasQuizId,
- questionAndPositions
- );
- await hackFixRedundantAssignments(canvasCourseId);
+ async delete(canvasCourseId: number, canvasQuizId: number) {
+ const url = `${canvasApi}/courses/${canvasCourseId}/quizzes/${canvasQuizId}`;
+ await axiosClient.delete(url);
},
};
diff --git a/nextjs/src/services/canvas/canvasService.ts b/nextjs/src/services/canvas/canvasService.ts
index 484849e..8c09540 100644
--- a/nextjs/src/services/canvas/canvasService.ts
+++ b/nextjs/src/services/canvas/canvasService.ts
@@ -1,19 +1,16 @@
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
-import { baseCanvasUrl, canvasServiceUtils } from "./canvasServiceUtils";
+import { canvasApi, canvasServiceUtils } from "./canvasServiceUtils";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { CanvasModuleItem } from "@/models/canvas/modules/canvasModuleItems";
import { CanvasPage } from "@/models/canvas/pages/canvasPageModel";
import { CanvasEnrollmentModel } from "@/models/canvas/enrollments/canvasEnrollmentModel";
import { axiosClient } from "../axiosUtils";
-
const getAllTerms = async () => {
- const url = `${baseCanvasUrl}/accounts/10/terms`;
- const { data } = await axiosClient.get<
- {
- enrollment_terms: CanvasEnrollmentTermModel[];
- }
- >(url);
+ const url = `${canvasApi}/accounts/10/terms`;
+ const { data } = await axiosClient.get<{
+ enrollment_terms: CanvasEnrollmentTermModel[];
+ }>(url);
const terms = data.enrollment_terms;
return terms;
};
@@ -21,7 +18,7 @@ const getAllTerms = async () => {
export const canvasService = {
getAllTerms,
async getCourses(termId: number) {
- const url = `${baseCanvasUrl}/courses`;
+ const url = `${canvasApi}/courses`;
const response = await axiosClient.get(url);
const allCourses = response.data;
const coursesInTerm = allCourses
@@ -31,7 +28,7 @@ export const canvasService = {
},
async getCourse(courseId: number): Promise {
- const url = `${baseCanvasUrl}/courses/${courseId}`;
+ const url = `${canvasApi}/courses/${courseId}`;
const { data } = await axiosClient.get(url);
return data;
},
@@ -56,10 +53,9 @@ export const canvasService = {
return currentTerms;
},
-
async getEnrolledStudents(canvasCourseId: number) {
console.log(`Getting students for course ${canvasCourseId}`);
- const url = `${baseCanvasUrl}/courses/${canvasCourseId}/enrollments?enrollment_type=student`;
+ const url = `${canvasApi}/courses/${canvasCourseId}/enrollments?enrollment_type=student`;
const { data } = await axiosClient.get(url);
if (!data)
diff --git a/nextjs/src/services/canvas/canvasServiceUtils.ts b/nextjs/src/services/canvas/canvasServiceUtils.ts
index 360b971..48dab46 100644
--- a/nextjs/src/services/canvas/canvasServiceUtils.ts
+++ b/nextjs/src/services/canvas/canvasServiceUtils.ts
@@ -3,8 +3,8 @@
import { AxiosResponseHeaders, RawAxiosResponseHeaders } from "axios";
import { axiosClient } from "../axiosUtils";
-
-export const baseCanvasUrl = "https://snow.instructure.com/api/v1";
+export const baseCanvasUrl = "https://snow.instructure.com";
+export const canvasApi = baseCanvasUrl + "/api/v1";
const getNextUrl = (
headers: AxiosResponseHeaders | RawAxiosResponseHeaders