refactored drag provider

This commit is contained in:
2024-11-02 14:00:30 -06:00
parent fd65bf710d
commit 0dc3f08e9f
11 changed files with 144 additions and 142 deletions

View File

@@ -3,7 +3,7 @@ import {
getDateFromStringOrThrow, getDateFromStringOrThrow,
getDateOnlyMarkdownString, getDateOnlyMarkdownString,
} from "@/models/local/timeUtils"; } from "@/models/local/timeUtils";
import { useDraggingContext } from "../../context/draggingContext"; import { useDraggingContext } from "../../context/drag/draggingContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { getDayOfWeek } from "@/models/local/localCourse"; import { getDayOfWeek } from "@/models/local/localCourse";
import { ItemInDay } from "./ItemInDay"; import { ItemInDay } from "./ItemInDay";

View File

@@ -4,8 +4,8 @@ import { getLectureUrl } from "@/services/urlUtils";
import Link from "next/link"; import Link from "next/link";
import { useCourseContext } from "../../context/courseContext"; import { useCourseContext } from "../../context/courseContext";
import NewItemForm from "../../modules/NewItemForm"; import NewItemForm from "../../modules/NewItemForm";
import { DraggableItem } from "../../context/draggingContext"; import { DraggableItem } from "../../context/drag/draggingContext";
import { useDragStyleContext } from "../../context/dragStyleContext"; import { useDragStyleContext } from "../../context/drag/dragStyleContext";
import { getLectureForDay } from "@/models/local/lectureUtils"; import { getLectureForDay } from "@/models/local/lectureUtils";
export function DayTitle({ day, dayAsDate }: { day: string; dayAsDate: Date }) { export function DayTitle({ day, dayAsDate }: { day: string; dayAsDate: Date }) {

View File

@@ -6,10 +6,10 @@ import { useCourseContext } from "../../context/courseContext";
import { import {
useDraggingContext, useDraggingContext,
DraggableItem, DraggableItem,
} from "../../context/draggingContext"; } from "../../context/drag/draggingContext";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import ClientOnly from "@/components/ClientOnly"; import ClientOnly from "@/components/ClientOnly";
import { useDragStyleContext } from "../../context/dragStyleContext"; import { useDragStyleContext } from "../../context/drag/dragStyleContext";
export function ItemInDay({ export function ItemInDay({
type, type,

View File

@@ -3,8 +3,9 @@ import { ReactNode, useEffect, useState } from "react";
import { DraggingContext } from "./draggingContext"; import { DraggingContext } from "./draggingContext";
import { useDragStyleContext } from "./dragStyleContext"; import { useDragStyleContext } from "./dragStyleContext";
import { useModal } from "@/components/Modal"; import { useModal } from "@/components/Modal";
import { LectureReplaceModal } from "./LectureReplaceModal"; import { LectureReplaceModal } from "../LectureReplaceModal";
import { useItemDropOnDay, useItemDropOnModule } from "./draggingContextUtils"; import { useItemDropOnModule } from "./useItemDropOnModule";
import { useItemDropOnDay } from "./useItemDropOnDay";
export default function DraggingContextProvider({ export default function DraggingContextProvider({
children, children,

View File

@@ -0,0 +1,25 @@
"use client";
import { getDateFromStringOrThrow, dateToMarkdownString } from "@/models/local/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);
}

View File

@@ -1,10 +1,7 @@
"use client"; "use client";
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks"; import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
import { import { useLecturesByWeekQuery, useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
useLecturesByWeekQuery, import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
useLectureUpdateMutation,
} from "@/hooks/localCourse/lectureHooks";
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { LocalAssignment } from "@/models/local/assignment/localAssignment"; import { LocalAssignment } from "@/models/local/assignment/localAssignment";
@@ -12,27 +9,20 @@ import { Lecture } from "@/models/local/lecture";
import { getLectureForDay } from "@/models/local/lectureUtils"; import { getLectureForDay } from "@/models/local/lectureUtils";
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { LocalQuiz } from "@/models/local/quiz/localQuiz"; import { LocalQuiz } from "@/models/local/quiz/localQuiz";
import { import { getDateFromStringOrThrow, getDateOnlyMarkdownString, dateToMarkdownString } from "@/models/local/timeUtils";
getDateFromStringOrThrow,
getDateOnlyMarkdownString,
dateToMarkdownString,
} from "@/models/local/timeUtils";
import { Dispatch, SetStateAction, useCallback, DragEvent } from "react"; import { Dispatch, SetStateAction, useCallback, DragEvent } from "react";
import { DraggableItem } from "./draggingContext"; import { DraggableItem } from "./draggingContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { getNewLockDate } from "./getNewLockDate";
export function useItemDropOnDay({ export function useItemDropOnDay({
setIsDragging, setIsDragging, setModalText, setModalCallback, setIsLoading, modal,
setModalText,
setModalCallback,
setIsLoading,
modal,
}: { }: {
setIsDragging: Dispatch<SetStateAction<boolean>>; setIsDragging: Dispatch<SetStateAction<boolean>>;
setModalText: Dispatch<SetStateAction<string>>; setModalText: Dispatch<SetStateAction<string>>;
setModalCallback: Dispatch<SetStateAction<() => void>>; setModalCallback: Dispatch<SetStateAction<() => void>>;
setIsLoading: Dispatch<SetStateAction<boolean>>; setIsLoading: Dispatch<SetStateAction<boolean>>;
modal: { isOpen: boolean; openModal: () => void; closeModal: () => void }; modal: { isOpen: boolean; openModal: () => void; closeModal: () => void; };
}) { }) {
const { data: settings } = useLocalCourseSettingsQuery(); const { data: settings } = useLocalCourseSettingsQuery();
const { data: weeks } = useLecturesByWeekQuery(); const { data: weeks } = useLecturesByWeekQuery();
@@ -195,116 +185,3 @@ export function useItemDropOnDay({
] ]
); );
} }
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);
}

View File

@@ -0,0 +1,99 @@
"use client";
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
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";
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,
]
);
}

View File

@@ -14,12 +14,12 @@ import NewItemForm from "./NewItemForm";
import { ModuleCanvasStatus } from "./ModuleCanvasStatus"; import { ModuleCanvasStatus } from "./ModuleCanvasStatus";
import ClientOnly from "@/components/ClientOnly"; import ClientOnly from "@/components/ClientOnly";
import ExpandIcon from "../../../../components/icons/ExpandIcon"; import ExpandIcon from "../../../../components/icons/ExpandIcon";
import { DraggableItem, useDraggingContext } from "../context/draggingContext"; import { DraggableItem, useDraggingContext } from "../context/drag/draggingContext";
import Link from "next/link"; import Link from "next/link";
import { getModuleItemUrl } from "@/services/urlUtils"; 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/dragStyleContext"; import { useDragStyleContext } from "../context/drag/dragStyleContext";
export default function ExpandableModule({ export default function ExpandableModule({
moduleName, moduleName,

View File

@@ -1,10 +1,10 @@
import CourseCalendar from "./calendar/CourseCalendar"; import CourseCalendar from "./calendar/CourseCalendar";
import CourseSettingsLink from "./CourseSettingsLink"; import CourseSettingsLink from "./CourseSettingsLink";
import ModuleList from "./modules/ModuleList"; import ModuleList from "./modules/ModuleList";
import DraggingContextProvider from "./context/DraggingContextProvider"; import DraggingContextProvider from "./context/drag/DraggingContextProvider";
import CourseTitle from "./CourseTitle"; import CourseTitle from "./CourseTitle";
import { CourseNavigation } from "./CourseNavigation"; import { CourseNavigation } from "./CourseNavigation";
import { DragStyleContextProvider } from "./context/dragStyleContext"; import { DragStyleContextProvider } from "./context/drag/dragStyleContext";
export default async function CoursePage({}: {}) { export default async function CoursePage({}: {}) {
return ( return (