mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-26 07:38:33 -06:00
moving v2 to top level
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import { ReactNode } from "react";
|
||||
import {
|
||||
CalendarItemsContext,
|
||||
CalendarItemsInterface,
|
||||
} from "./calendarItemsContext";
|
||||
import {
|
||||
getDateFromStringOrThrow,
|
||||
getDateOnlyMarkdownString,
|
||||
} from "@/models/local/utils/timeUtils";
|
||||
import { useAllCourseDataQuery } from "@/hooks/localCourse/localCourseModuleHooks";
|
||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
||||
|
||||
export default function CalendarItemsContextProvider({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const { assignmentsAndModules, quizzesAndModules, pagesAndModules } =
|
||||
useAllCourseDataQuery();
|
||||
|
||||
const assignmentsByModuleByDate = assignmentsAndModules.reduce(
|
||||
(previous, { assignment, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(
|
||||
assignment.dueAt,
|
||||
"due at for assignment in items context"
|
||||
)
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
assignments: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
assignments: [...previousModule.assignments, assignment],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
|
||||
const quizzesByModuleByDate = quizzesAndModules.reduce(
|
||||
(previous, { quiz, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(quiz.dueAt, "due at for quiz in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
quizzes: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
quizzes: [...previousModule.quizzes, quiz],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
|
||||
const pagesByModuleByDate = pagesAndModules.reduce(
|
||||
(previous, { page, moduleName }) => {
|
||||
const dueDay = getDateOnlyMarkdownString(
|
||||
getDateFromStringOrThrow(page.dueAt, "due at for quiz in items context")
|
||||
);
|
||||
const previousModules = previous[dueDay] ?? {};
|
||||
const previousModule = previousModules[moduleName] ?? {
|
||||
pages: [],
|
||||
};
|
||||
|
||||
const updatedModule = {
|
||||
...previousModule,
|
||||
pages: [...previousModule.pages, page],
|
||||
};
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[dueDay]: {
|
||||
...previousModules,
|
||||
[moduleName]: updatedModule,
|
||||
},
|
||||
};
|
||||
},
|
||||
{} as CalendarItemsInterface
|
||||
);
|
||||
|
||||
const allDays = [
|
||||
...new Set([
|
||||
...Object.keys(assignmentsByModuleByDate),
|
||||
...Object.keys(quizzesByModuleByDate),
|
||||
...Object.keys(pagesByModuleByDate),
|
||||
]),
|
||||
];
|
||||
|
||||
const allItemsByModuleByDate = allDays.reduce((prev, day) => {
|
||||
const assignmentModulesInDay = assignmentsByModuleByDate[day] ?? {};
|
||||
const quizModulesInDay = quizzesByModuleByDate[day] ?? {};
|
||||
const pageModulesInDay = pagesByModuleByDate[day] ?? {};
|
||||
|
||||
const allModules = [
|
||||
...new Set([
|
||||
...Object.keys(assignmentModulesInDay),
|
||||
...Object.keys(quizModulesInDay),
|
||||
...Object.keys(pageModulesInDay),
|
||||
]),
|
||||
];
|
||||
|
||||
const modulesInDate = allModules.reduce((prev, moduleName) => {
|
||||
return {
|
||||
...prev,
|
||||
[moduleName]: {
|
||||
assignments: assignmentModulesInDay[moduleName]
|
||||
? assignmentModulesInDay[moduleName].assignments
|
||||
: [],
|
||||
quizzes: quizModulesInDay[moduleName]
|
||||
? quizModulesInDay[moduleName].quizzes
|
||||
: [],
|
||||
pages: pageModulesInDay[moduleName]
|
||||
? pageModulesInDay[moduleName].pages
|
||||
: [],
|
||||
},
|
||||
};
|
||||
}, {});
|
||||
|
||||
return { ...prev, [day]: modulesInDate };
|
||||
}, {} as CalendarItemsInterface);
|
||||
|
||||
return (
|
||||
<CalendarItemsContext.Provider value={allItemsByModuleByDate}>
|
||||
{children}
|
||||
</CalendarItemsContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
"use client"
|
||||
import { ReactNode } from "react";
|
||||
import { CourseContext } from "./courseContext";
|
||||
|
||||
export default function CourseContextProvider({
|
||||
localCourseName,
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
localCourseName: string;
|
||||
}) {
|
||||
return (
|
||||
<CourseContext.Provider
|
||||
value={{
|
||||
courseName: localCourseName,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</CourseContext.Provider>
|
||||
);
|
||||
}
|
||||
39
src/app/course/[courseName]/context/LectureReplaceModal.tsx
Normal file
39
src/app/course/[courseName]/context/LectureReplaceModal.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
import Modal, { ModalControl } from "@/components/Modal";
|
||||
import { Spinner } from "@/components/Spinner";
|
||||
|
||||
export function LectureReplaceModal({
|
||||
modal, modalText, modalCallback, isLoading,
|
||||
}: {
|
||||
modal: ModalControl;
|
||||
modalText: string;
|
||||
modalCallback: () => void;
|
||||
isLoading: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Modal modalControl={modal} buttonText={""} buttonClass="hidden">
|
||||
{({ closeModal }) => (
|
||||
<div>
|
||||
<div className="text-center">{modalText}</div>
|
||||
<br />
|
||||
<div className="flex justify-around gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
console.log("deleting");
|
||||
modalCallback();
|
||||
}}
|
||||
disabled={isLoading}
|
||||
className="btn-danger"
|
||||
>
|
||||
Yes
|
||||
</button>
|
||||
<button onClick={closeModal} disabled={isLoading}>
|
||||
No
|
||||
</button>
|
||||
</div>
|
||||
{isLoading && <Spinner />}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
22
src/app/course/[courseName]/context/calendarItemsContext.ts
Normal file
22
src/app/course/[courseName]/context/calendarItemsContext.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
export interface CalendarItemsInterface {
|
||||
[
|
||||
key: string // representing a date
|
||||
]: {
|
||||
[moduleName: string]: {
|
||||
assignments: LocalAssignment[];
|
||||
quizzes: LocalQuiz[];
|
||||
pages: LocalCoursePage[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const CalendarItemsContext = createContext<CalendarItemsInterface>({});
|
||||
|
||||
export function useCalendarItemsContext() {
|
||||
return useContext(CalendarItemsContext);
|
||||
}
|
||||
18
src/app/course/[courseName]/context/courseContext.ts
Normal file
18
src/app/course/[courseName]/context/courseContext.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
"use client";
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
export interface CourseContextInterface {
|
||||
courseName: string;
|
||||
}
|
||||
|
||||
const defaultValue: CourseContextInterface = {
|
||||
courseName: "",
|
||||
};
|
||||
|
||||
export const CourseContext =
|
||||
createContext<CourseContextInterface>(defaultValue);
|
||||
|
||||
export function useCourseContext() {
|
||||
return useContext(CourseContext);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
"use client";
|
||||
import { ReactNode, useEffect, useState } from "react";
|
||||
import { DraggingContext } from "./draggingContext";
|
||||
import { useDragStyleContext } from "./dragStyleContext";
|
||||
import { useModal } from "@/components/Modal";
|
||||
import { LectureReplaceModal } from "../LectureReplaceModal";
|
||||
import { useItemDropOnModule } from "./useItemDropOnModule";
|
||||
import { useItemDropOnDay } from "./useItemDropOnDay";
|
||||
|
||||
export default function DraggingContextProvider({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const { setIsDragging } = useDragStyleContext();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [modalText, setModalText] = useState("");
|
||||
const modal = useModal();
|
||||
const [modalCallback, setModalCallback] = useState<() => void>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
const handleDrop = () => {
|
||||
console.log("drop on window");
|
||||
setIsDragging(false);
|
||||
};
|
||||
const preventDefault = (e: globalThis.DragEvent) => e.preventDefault();
|
||||
if (typeof window !== "undefined") {
|
||||
window.addEventListener("drop", handleDrop);
|
||||
window.addEventListener("dragover", preventDefault);
|
||||
}
|
||||
return () => {
|
||||
window.removeEventListener("drop", handleDrop);
|
||||
window.addEventListener("dragover", preventDefault);
|
||||
};
|
||||
}, [setIsDragging]);
|
||||
|
||||
const itemDropOnModule = useItemDropOnModule({
|
||||
setIsDragging,
|
||||
});
|
||||
|
||||
const itemDropOnDay = useItemDropOnDay({
|
||||
setIsDragging,
|
||||
setModalText,
|
||||
setModalCallback,
|
||||
setIsLoading,
|
||||
modal,
|
||||
});
|
||||
|
||||
return (
|
||||
<DraggingContext.Provider
|
||||
value={{
|
||||
itemDropOnDay,
|
||||
itemDropOnModule,
|
||||
}}
|
||||
>
|
||||
<LectureReplaceModal
|
||||
modal={modal}
|
||||
modalText={modalText}
|
||||
modalCallback={modalCallback}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
{children}
|
||||
</DraggingContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
ReactNode,
|
||||
useState,
|
||||
SetStateAction,
|
||||
Dispatch,
|
||||
} from "react";
|
||||
|
||||
export interface DraggingStyleContextInterface {
|
||||
setIsDragging: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
const defaultDraggingValue: DraggingStyleContextInterface = {
|
||||
setIsDragging: () => {},
|
||||
};
|
||||
export const DragStyleContext =
|
||||
createContext<DraggingStyleContextInterface>(defaultDraggingValue);
|
||||
|
||||
export function useDragStyleContext() {
|
||||
return useContext(DragStyleContext);
|
||||
}
|
||||
|
||||
export function DragStyleContextProvider({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
return (
|
||||
<DragStyleContext.Provider value={{ setIsDragging }}>
|
||||
<div
|
||||
className={"h-full flex flex-col " + (isDragging ? " dragging " : "")}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</DragStyleContext.Provider>
|
||||
);
|
||||
}
|
||||
24
src/app/course/[courseName]/context/drag/draggingContext.tsx
Normal file
24
src/app/course/[courseName]/context/drag/draggingContext.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
import { IModuleItem } from "@/models/local/IModuleItem";
|
||||
import { createContext, useContext, DragEvent } from "react";
|
||||
|
||||
export interface DraggableItem {
|
||||
item: IModuleItem;
|
||||
sourceModuleName: string | undefined; // undefined for lectures
|
||||
type: "quiz" | "assignment" | "page" | "lecture";
|
||||
}
|
||||
|
||||
export interface DraggingContextInterface {
|
||||
itemDropOnDay: (e: DragEvent, droppedOnDay: string) => void;
|
||||
itemDropOnModule: (e: DragEvent, moduleName: string) => void;
|
||||
}
|
||||
const defaultDraggingValue: DraggingContextInterface = {
|
||||
itemDropOnDay: () => {},
|
||||
itemDropOnModule: () => {},
|
||||
};
|
||||
export const DraggingContext =
|
||||
createContext<DraggingContextInterface>(defaultDraggingValue);
|
||||
|
||||
export function useDraggingContext() {
|
||||
return useContext(DraggingContext);
|
||||
}
|
||||
25
src/app/course/[courseName]/context/drag/getNewLockDate.ts
Normal file
25
src/app/course/[courseName]/context/drag/getNewLockDate.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
"use client";
|
||||
import { getDateFromStringOrThrow, dateToMarkdownString } from "@/models/local/utils/timeUtils";
|
||||
|
||||
|
||||
export function getNewLockDate(
|
||||
originalDueDate: string,
|
||||
originalLockDate: string | undefined,
|
||||
dayAsDate: Date
|
||||
): string | undefined {
|
||||
// todo: preserve previous due date / lock date offset
|
||||
const dueDate = getDateFromStringOrThrow(originalDueDate, "dueAt date");
|
||||
const lockDate = originalLockDate === undefined
|
||||
? undefined
|
||||
: getDateFromStringOrThrow(originalLockDate, "lockAt date");
|
||||
|
||||
const originalOffset = lockDate === undefined ? undefined : lockDate.getTime() - dueDate.getTime();
|
||||
|
||||
const newLockDate = originalOffset === undefined
|
||||
? undefined
|
||||
: new Date(dayAsDate.getTime() + originalOffset);
|
||||
|
||||
return newLockDate === undefined
|
||||
? undefined
|
||||
: dateToMarkdownString(newLockDate);
|
||||
}
|
||||
212
src/app/course/[courseName]/context/drag/useItemDropOnDay.ts
Normal file
212
src/app/course/[courseName]/context/drag/useItemDropOnDay.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
"use client";
|
||||
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
||||
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";
|
||||
import { Lecture } from "@/models/local/lecture";
|
||||
import { getLectureForDay } from "@/models/local/utils/lectureUtils";
|
||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
||||
import {
|
||||
getDateFromStringOrThrow,
|
||||
getDateOnlyMarkdownString,
|
||||
dateToMarkdownString,
|
||||
} from "@/models/local/utils/timeUtils";
|
||||
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
|
||||
import { DraggableItem } from "./draggingContext";
|
||||
import { getNewLockDate } from "./getNewLockDate";
|
||||
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
|
||||
import { useCourseContext } from "../courseContext";
|
||||
|
||||
export function useItemDropOnDay({
|
||||
setIsDragging,
|
||||
setModalText,
|
||||
setModalCallback,
|
||||
setIsLoading,
|
||||
modal,
|
||||
}: {
|
||||
setIsDragging: Dispatch<SetStateAction<boolean>>;
|
||||
setModalText: Dispatch<SetStateAction<string>>;
|
||||
setModalCallback: Dispatch<SetStateAction<() => void>>;
|
||||
setIsLoading: Dispatch<SetStateAction<boolean>>;
|
||||
modal: { isOpen: boolean; openModal: () => void; closeModal: () => void };
|
||||
}) {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const { courseName } = useCourseContext();
|
||||
// const { data: weeks } = useLecturesByWeekQuery();
|
||||
const [weeks] = useLecturesSuspenseQuery();
|
||||
const updateQuizMutation = useUpdateQuizMutation();
|
||||
const updateLectureMutation = useLectureUpdateMutation();
|
||||
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
||||
const updatePageMutation = useUpdatePageMutation();
|
||||
|
||||
return useCallback(
|
||||
(e: DragEvent, day: string) => {
|
||||
const rawData = e.dataTransfer.getData("draggableItem");
|
||||
if (!rawData) return;
|
||||
const itemBeingDragged: DraggableItem = JSON.parse(rawData);
|
||||
|
||||
if (itemBeingDragged) {
|
||||
const dayAsDate = getDateWithDefaultDueTime();
|
||||
if (itemBeingDragged.type === "quiz") {
|
||||
updateQuiz(dayAsDate);
|
||||
} else if (itemBeingDragged.type === "assignment") {
|
||||
updateAssignment(dayAsDate);
|
||||
} else if (itemBeingDragged.type === "page") {
|
||||
updatePage(dayAsDate);
|
||||
} else if (itemBeingDragged.type === "lecture") {
|
||||
updateLecture(dayAsDate);
|
||||
}
|
||||
}
|
||||
setIsDragging(false);
|
||||
|
||||
function getDateWithDefaultDueTime() {
|
||||
const dayAsDate = getDateFromStringOrThrow(day, "in drop callback");
|
||||
dayAsDate.setHours(settings.defaultDueTime.hour);
|
||||
dayAsDate.setMinutes(settings.defaultDueTime.minute);
|
||||
dayAsDate.setSeconds(0);
|
||||
return dayAsDate;
|
||||
}
|
||||
function updateLecture(dayAsDate: Date) {
|
||||
const { dueAt, ...lecture } = itemBeingDragged.item as Lecture & {
|
||||
dueAt: string;
|
||||
};
|
||||
console.log("dropped lecture on day");
|
||||
const existingLecture = getLectureForDay(weeks, dayAsDate);
|
||||
if (existingLecture) {
|
||||
console.log("attempting to drop on existing lecture");
|
||||
setModalText(
|
||||
`Are you sure you want to replace ${
|
||||
existingLecture?.name || "Un-named Lecture"
|
||||
} with ${lecture.name}? This will delete ${
|
||||
existingLecture?.name || "Un-named Lecture"
|
||||
}.`
|
||||
);
|
||||
|
||||
setModalCallback(() => async () => {
|
||||
// because sometimes setStates receive a function
|
||||
console.log("running callback");
|
||||
setIsLoading(true);
|
||||
await updateLectureMutation.mutateAsync({
|
||||
previousDay: lecture.date,
|
||||
lecture: {
|
||||
...lecture,
|
||||
date: getDateOnlyMarkdownString(dayAsDate),
|
||||
},
|
||||
courseName,
|
||||
settings,
|
||||
});
|
||||
setModalText("");
|
||||
setModalCallback(() => {});
|
||||
modal.closeModal();
|
||||
setIsLoading(false);
|
||||
});
|
||||
modal.openModal();
|
||||
} else {
|
||||
console.log("updating lecture on unique day");
|
||||
updateLectureMutation.mutate({
|
||||
previousDay: lecture.date,
|
||||
lecture: {
|
||||
...lecture,
|
||||
date: getDateOnlyMarkdownString(dayAsDate),
|
||||
},
|
||||
courseName,
|
||||
settings,
|
||||
});
|
||||
}
|
||||
}
|
||||
function updateQuiz(dayAsDate: Date) {
|
||||
const previousQuiz = itemBeingDragged.item as LocalQuiz;
|
||||
if (!itemBeingDragged.sourceModuleName) {
|
||||
console.error(
|
||||
"error dropping quiz on day, sourceModuleName is undefined"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const quiz: LocalQuiz = {
|
||||
...previousQuiz,
|
||||
dueAt: dateToMarkdownString(dayAsDate),
|
||||
lockAt: getNewLockDate(
|
||||
previousQuiz.dueAt,
|
||||
previousQuiz.lockAt,
|
||||
dayAsDate
|
||||
),
|
||||
};
|
||||
updateQuizMutation.mutate({
|
||||
quiz,
|
||||
quizName: quiz.name,
|
||||
moduleName: itemBeingDragged.sourceModuleName,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
previousQuizName: quiz.name,
|
||||
courseName: settings.name,
|
||||
});
|
||||
}
|
||||
function updatePage(dayAsDate: Date) {
|
||||
const previousPage = itemBeingDragged.item as LocalCoursePage;
|
||||
if (!itemBeingDragged.sourceModuleName) {
|
||||
console.error(
|
||||
"error dropping page on day, sourceModuleName is undefined"
|
||||
);
|
||||
return;
|
||||
}
|
||||
const page: LocalCoursePage = {
|
||||
...previousPage,
|
||||
dueAt: dateToMarkdownString(dayAsDate),
|
||||
};
|
||||
updatePageMutation.mutate({
|
||||
page,
|
||||
moduleName: itemBeingDragged.sourceModuleName,
|
||||
pageName: page.name,
|
||||
previousPageName: page.name,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
courseName: settings.name,
|
||||
});
|
||||
}
|
||||
function updateAssignment(dayAsDate: Date) {
|
||||
if (!itemBeingDragged.sourceModuleName) {
|
||||
console.error(
|
||||
"error dropping assignment on day, sourceModuleName is undefined"
|
||||
);
|
||||
return;
|
||||
}
|
||||
const previousAssignment = itemBeingDragged.item as LocalAssignment;
|
||||
const assignment: LocalAssignment = {
|
||||
...previousAssignment,
|
||||
dueAt: dateToMarkdownString(dayAsDate),
|
||||
lockAt: getNewLockDate(
|
||||
previousAssignment.dueAt,
|
||||
previousAssignment.lockAt,
|
||||
dayAsDate
|
||||
),
|
||||
};
|
||||
updateAssignmentMutation.mutate({
|
||||
assignment,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
moduleName: itemBeingDragged.sourceModuleName,
|
||||
assignmentName: assignment.name,
|
||||
previousAssignmentName: assignment.name,
|
||||
courseName: settings.name,
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
courseName,
|
||||
modal,
|
||||
setIsDragging,
|
||||
setIsLoading,
|
||||
setModalCallback,
|
||||
setModalText,
|
||||
settings,
|
||||
updateAssignmentMutation,
|
||||
updateLectureMutation,
|
||||
updatePageMutation,
|
||||
updateQuizMutation,
|
||||
weeks,
|
||||
]
|
||||
);
|
||||
}
|
||||
105
src/app/course/[courseName]/context/drag/useItemDropOnModule.ts
Normal file
105
src/app/course/[courseName]/context/drag/useItemDropOnModule.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
"use client";
|
||||
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
||||
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
||||
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
|
||||
import { DraggableItem } from "./draggingContext";
|
||||
import { useCourseContext } from "../courseContext";
|
||||
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
|
||||
|
||||
export function useItemDropOnModule({
|
||||
setIsDragging,
|
||||
}: {
|
||||
setIsDragging: Dispatch<SetStateAction<boolean>>;
|
||||
}) {
|
||||
const updateQuizMutation = useUpdateQuizMutation();
|
||||
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
||||
const updatePageMutation = useUpdatePageMutation();
|
||||
const { courseName } = useCourseContext();
|
||||
|
||||
return useCallback(
|
||||
(e: DragEvent, dropModuleName: string) => {
|
||||
console.log("dropping on module");
|
||||
const rawData = e.dataTransfer.getData("draggableItem");
|
||||
if (!rawData) return;
|
||||
const itemBeingDragged: DraggableItem = JSON.parse(rawData);
|
||||
|
||||
if (itemBeingDragged) {
|
||||
if (itemBeingDragged.type === "quiz") {
|
||||
updateQuiz();
|
||||
} else if (itemBeingDragged.type === "assignment") {
|
||||
updateAssignment();
|
||||
} else if (itemBeingDragged.type === "page") {
|
||||
updatePage();
|
||||
} else if (itemBeingDragged.type === "lecture") {
|
||||
console.log("cannot drop lecture on module, only on days");
|
||||
}
|
||||
}
|
||||
setIsDragging(false);
|
||||
|
||||
function updateQuiz() {
|
||||
const quiz = itemBeingDragged.item as LocalQuiz;
|
||||
if (itemBeingDragged.sourceModuleName) {
|
||||
updateQuizMutation.mutate({
|
||||
quiz,
|
||||
quizName: quiz.name,
|
||||
moduleName: dropModuleName,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
previousQuizName: quiz.name,
|
||||
courseName,
|
||||
});
|
||||
} else {
|
||||
console.error(
|
||||
`error dropping quiz, sourceModuleName is undefined `,
|
||||
quiz
|
||||
);
|
||||
}
|
||||
}
|
||||
function updateAssignment() {
|
||||
const assignment = itemBeingDragged.item as LocalAssignment;
|
||||
if (itemBeingDragged.sourceModuleName) {
|
||||
updateAssignmentMutation.mutate({
|
||||
assignment,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
moduleName: dropModuleName,
|
||||
assignmentName: assignment.name,
|
||||
previousAssignmentName: assignment.name,
|
||||
courseName,
|
||||
});
|
||||
} else {
|
||||
console.error(
|
||||
`error dropping assignment, sourceModuleName is undefined `,
|
||||
assignment
|
||||
);
|
||||
}
|
||||
}
|
||||
function updatePage() {
|
||||
const page = itemBeingDragged.item as LocalCoursePage;
|
||||
if (itemBeingDragged.sourceModuleName) {
|
||||
updatePageMutation.mutate({
|
||||
page,
|
||||
moduleName: dropModuleName,
|
||||
pageName: page.name,
|
||||
previousPageName: page.name,
|
||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||
courseName,
|
||||
});
|
||||
} else {
|
||||
console.error(
|
||||
`error dropping page, sourceModuleName is undefined `,
|
||||
page
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
courseName,
|
||||
setIsDragging,
|
||||
updateAssignmentMutation,
|
||||
updatePageMutation,
|
||||
updateQuizMutation,
|
||||
]
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user