mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
refactored drag provider
This commit is contained in:
@@ -1,27 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { ReactNode, useCallback, DragEvent, useEffect, useState } from "react";
|
import { ReactNode, useEffect, useState } from "react";
|
||||||
import { DraggableItem, DraggingContext } from "./draggingContext";
|
import { DraggingContext } from "./draggingContext";
|
||||||
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
|
|
||||||
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
|
||||||
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
|
||||||
import {
|
|
||||||
getDateFromStringOrThrow,
|
|
||||||
dateToMarkdownString,
|
|
||||||
getDateOnlyMarkdownString,
|
|
||||||
} from "@/models/local/timeUtils";
|
|
||||||
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
|
||||||
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
|
||||||
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
|
||||||
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
|
||||||
import { useDragStyleContext } from "./dragStyleContext";
|
import { useDragStyleContext } from "./dragStyleContext";
|
||||||
import { Lecture } from "@/models/local/lecture";
|
import { useModal } from "@/components/Modal";
|
||||||
import {
|
import { LectureReplaceModal } from "./LectureReplaceModal";
|
||||||
useLecturesByWeekQuery,
|
import { useItemDropOnDay, useItemDropOnModule } from "./draggingContextUtils";
|
||||||
useLectureUpdateMutation,
|
|
||||||
} from "@/hooks/localCourse/lectureHooks";
|
|
||||||
import { getLectureForDay } from "@/models/local/lectureUtils";
|
|
||||||
import Modal, { useModal } from "@/components/Modal";
|
|
||||||
import { Spinner } from "@/components/Spinner";
|
|
||||||
|
|
||||||
export default function DraggingContextProvider({
|
export default function DraggingContextProvider({
|
||||||
children,
|
children,
|
||||||
@@ -29,12 +12,6 @@ export default function DraggingContextProvider({
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const { setIsDragging } = useDragStyleContext();
|
const { setIsDragging } = useDragStyleContext();
|
||||||
const updateQuizMutation = useUpdateQuizMutation();
|
|
||||||
const updateLectureMutation = useLectureUpdateMutation();
|
|
||||||
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
|
||||||
const updatePageMutation = useUpdatePageMutation();
|
|
||||||
const { data: settings } = useLocalCourseSettingsQuery();
|
|
||||||
const { data: weeks } = useLecturesByWeekQuery();
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [modalText, setModalText] = useState("");
|
const [modalText, setModalText] = useState("");
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
@@ -56,237 +33,17 @@ export default function DraggingContextProvider({
|
|||||||
};
|
};
|
||||||
}, [setIsDragging]);
|
}, [setIsDragging]);
|
||||||
|
|
||||||
const itemDropOnModule = useCallback(
|
const itemDropOnModule = useItemDropOnModule({
|
||||||
(e: DragEvent<HTMLDivElement>, dropModuleName: string) => {
|
setIsDragging,
|
||||||
console.log("dropping on module");
|
});
|
||||||
const rawData = e.dataTransfer.getData("draggableItem");
|
|
||||||
if (!rawData) return;
|
|
||||||
const itemBeingDragged: DraggableItem = JSON.parse(rawData);
|
|
||||||
|
|
||||||
if (itemBeingDragged) {
|
const itemDropOnDay = useItemDropOnDay({
|
||||||
if (itemBeingDragged.type === "quiz") {
|
setIsDragging,
|
||||||
updateQuiz();
|
setModalText,
|
||||||
} else if (itemBeingDragged.type === "assignment") {
|
setModalCallback,
|
||||||
updateAssignment();
|
setIsLoading,
|
||||||
} else if (itemBeingDragged.type === "page") {
|
modal,
|
||||||
updatePage();
|
});
|
||||||
} else if (itemBeingDragged.type === "lecture") {
|
|
||||||
// const lecture = itemBeingDragged.item as Lecture & { dueAt: string };
|
|
||||||
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({
|
|
||||||
item: quiz,
|
|
||||||
itemName: quiz.name,
|
|
||||||
moduleName: dropModuleName,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
previousItemName: quiz.name,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
`error dropping quiz, sourceModuleName is undefined `,
|
|
||||||
quiz
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function updateAssignment() {
|
|
||||||
const assignment = itemBeingDragged.item as LocalAssignment;
|
|
||||||
if (itemBeingDragged.sourceModuleName) {
|
|
||||||
updateAssignmentMutation.mutate({
|
|
||||||
item: assignment,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
moduleName: dropModuleName,
|
|
||||||
itemName: assignment.name,
|
|
||||||
previousItemName: assignment.name,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
`error dropping assignment, sourceModuleName is undefined `,
|
|
||||||
assignment
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function updatePage() {
|
|
||||||
const page = itemBeingDragged.item as LocalCoursePage;
|
|
||||||
if (itemBeingDragged.sourceModuleName) {
|
|
||||||
updatePageMutation.mutate({
|
|
||||||
item: page,
|
|
||||||
moduleName: dropModuleName,
|
|
||||||
itemName: page.name,
|
|
||||||
previousItemName: page.name,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
`error dropping page, sourceModuleName is undefined `,
|
|
||||||
page
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
setIsDragging,
|
|
||||||
updateAssignmentMutation,
|
|
||||||
updatePageMutation,
|
|
||||||
updateQuizMutation,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
const itemDropOnDay = useCallback(
|
|
||||||
(e: DragEvent<HTMLDivElement>, 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} with ${lecture.name}? This will delete ${existingLecture.name}.`
|
|
||||||
);
|
|
||||||
|
|
||||||
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),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
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),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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({
|
|
||||||
item: quiz,
|
|
||||||
itemName: quiz.name,
|
|
||||||
moduleName: itemBeingDragged.sourceModuleName,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
previousItemName: quiz.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({
|
|
||||||
item: page,
|
|
||||||
moduleName: itemBeingDragged.sourceModuleName,
|
|
||||||
itemName: page.name,
|
|
||||||
previousItemName: page.name,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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({
|
|
||||||
item: assignment,
|
|
||||||
previousModuleName: itemBeingDragged.sourceModuleName,
|
|
||||||
moduleName: itemBeingDragged.sourceModuleName,
|
|
||||||
itemName: assignment.name,
|
|
||||||
previousItemName: assignment.name,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
modal,
|
|
||||||
setIsDragging,
|
|
||||||
settings.defaultDueTime.hour,
|
|
||||||
settings.defaultDueTime.minute,
|
|
||||||
updateAssignmentMutation,
|
|
||||||
updateLectureMutation,
|
|
||||||
updatePageMutation,
|
|
||||||
updateQuizMutation,
|
|
||||||
weeks,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DraggingContext.Provider
|
<DraggingContext.Provider
|
||||||
@@ -295,56 +52,13 @@ export default function DraggingContextProvider({
|
|||||||
itemDropOnModule,
|
itemDropOnModule,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Modal modalControl={modal} buttonText={""} buttonClass="hidden">
|
<LectureReplaceModal
|
||||||
{({ closeModal }) => (
|
modal={modal}
|
||||||
<div>
|
modalText={modalText}
|
||||||
<div className="text-center">{modalText}</div>
|
modalCallback={modalCallback}
|
||||||
<br />
|
isLoading={isLoading}
|
||||||
<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>
|
|
||||||
{children}
|
{children}
|
||||||
</DraggingContext.Provider>
|
</DraggingContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@ export interface DraggableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DraggingContextInterface {
|
export interface DraggingContextInterface {
|
||||||
itemDropOnDay: (e: DragEvent<HTMLDivElement>, droppedOnDay: string) => void;
|
itemDropOnDay: (e: DragEvent, droppedOnDay: string) => void;
|
||||||
itemDropOnModule: (e: DragEvent<HTMLDivElement>, moduleName: string) => void;
|
itemDropOnModule: (e: DragEvent, moduleName: string) => void;
|
||||||
}
|
}
|
||||||
const defaultDraggingValue: DraggingContextInterface = {
|
const defaultDraggingValue: DraggingContextInterface = {
|
||||||
itemDropOnDay: () => {},
|
itemDropOnDay: () => {},
|
||||||
|
|||||||
@@ -0,0 +1,310 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
|
||||||
|
import {
|
||||||
|
useLecturesByWeekQuery,
|
||||||
|
useLectureUpdateMutation,
|
||||||
|
} from "@/hooks/localCourse/lectureHooks";
|
||||||
|
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
|
||||||
|
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
|
||||||
|
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
|
||||||
|
import { Lecture } from "@/models/local/lecture";
|
||||||
|
import { getLectureForDay } from "@/models/local/lectureUtils";
|
||||||
|
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
|
||||||
|
import { LocalQuiz } from "@/models/local/quiz/localQuiz";
|
||||||
|
import {
|
||||||
|
getDateFromStringOrThrow,
|
||||||
|
getDateOnlyMarkdownString,
|
||||||
|
dateToMarkdownString,
|
||||||
|
} from "@/models/local/timeUtils";
|
||||||
|
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
|
||||||
|
import { DraggableItem } from "./draggingContext";
|
||||||
|
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||||
|
|
||||||
|
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 { data: settings } = useLocalCourseSettingsQuery();
|
||||||
|
const { data: weeks } = useLecturesByWeekQuery();
|
||||||
|
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} with ${lecture.name}? This will delete ${existingLecture.name}.`
|
||||||
|
);
|
||||||
|
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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({
|
||||||
|
item: quiz,
|
||||||
|
itemName: quiz.name,
|
||||||
|
moduleName: itemBeingDragged.sourceModuleName,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
previousItemName: quiz.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({
|
||||||
|
item: page,
|
||||||
|
moduleName: itemBeingDragged.sourceModuleName,
|
||||||
|
itemName: page.name,
|
||||||
|
previousItemName: page.name,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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({
|
||||||
|
item: assignment,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
moduleName: itemBeingDragged.sourceModuleName,
|
||||||
|
itemName: assignment.name,
|
||||||
|
previousItemName: assignment.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
modal,
|
||||||
|
setIsDragging,
|
||||||
|
setIsLoading,
|
||||||
|
setModalCallback,
|
||||||
|
setModalText,
|
||||||
|
settings.defaultDueTime.hour,
|
||||||
|
settings.defaultDueTime.minute,
|
||||||
|
updateAssignmentMutation,
|
||||||
|
updateLectureMutation,
|
||||||
|
updatePageMutation,
|
||||||
|
updateQuizMutation,
|
||||||
|
weeks,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function useItemDropOnModule({
|
||||||
|
setIsDragging,
|
||||||
|
}: {
|
||||||
|
setIsDragging: Dispatch<SetStateAction<boolean>>;
|
||||||
|
}) {
|
||||||
|
const updateQuizMutation = useUpdateQuizMutation();
|
||||||
|
const updateAssignmentMutation = useUpdateAssignmentMutation();
|
||||||
|
const updatePageMutation = useUpdatePageMutation();
|
||||||
|
|
||||||
|
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({
|
||||||
|
item: quiz,
|
||||||
|
itemName: quiz.name,
|
||||||
|
moduleName: dropModuleName,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
previousItemName: quiz.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`error dropping quiz, sourceModuleName is undefined `,
|
||||||
|
quiz
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateAssignment() {
|
||||||
|
const assignment = itemBeingDragged.item as LocalAssignment;
|
||||||
|
if (itemBeingDragged.sourceModuleName) {
|
||||||
|
updateAssignmentMutation.mutate({
|
||||||
|
item: assignment,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
moduleName: dropModuleName,
|
||||||
|
itemName: assignment.name,
|
||||||
|
previousItemName: assignment.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`error dropping assignment, sourceModuleName is undefined `,
|
||||||
|
assignment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updatePage() {
|
||||||
|
const page = itemBeingDragged.item as LocalCoursePage;
|
||||||
|
if (itemBeingDragged.sourceModuleName) {
|
||||||
|
updatePageMutation.mutate({
|
||||||
|
item: page,
|
||||||
|
moduleName: dropModuleName,
|
||||||
|
itemName: page.name,
|
||||||
|
previousItemName: page.name,
|
||||||
|
previousModuleName: itemBeingDragged.sourceModuleName,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`error dropping page, sourceModuleName is undefined `,
|
||||||
|
page
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
setIsDragging,
|
||||||
|
updateAssignmentMutation,
|
||||||
|
updatePageMutation,
|
||||||
|
updateQuizMutation,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user