isdragging in different context for styling

This commit is contained in:
2024-09-27 13:19:38 -06:00
parent fbfde530d8
commit f0e8f86201
9 changed files with 91 additions and 56 deletions

View File

@@ -1,6 +1,5 @@
"use client"; "use client";
import { import {
getDateFromString,
getDateFromStringOrThrow, getDateFromStringOrThrow,
getDateOnlyMarkdownString, getDateOnlyMarkdownString,
} from "@/models/local/timeUtils"; } from "@/models/local/timeUtils";
@@ -10,7 +9,6 @@ import Link from "next/link";
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 { getLectureUrl } from "@/services/urlUtils"; import { getLectureUrl } from "@/services/urlUtils";
import DropTargetStyling from "../../../../../components/DropTargetStyling";
import { ItemInDay } from "./ItemInDay"; import { ItemInDay } from "./ItemInDay";
import { useTodaysItems } from "./useTodaysItems"; import { useTodaysItems } from "./useTodaysItems";
import Modal from "@/components/Modal"; import Modal from "@/components/Modal";
@@ -41,7 +39,7 @@ export default function Day({ day, month }: { day: string; month: number }) {
"comparing end date in day" "comparing end date in day"
); );
const isInSemester = semesterStart < dayAsDate&& semesterEnd > dayAsDate; const isInSemester = semesterStart < dayAsDate && semesterEnd > dayAsDate;
const meetingClasses = const meetingClasses =
classOnThisDay && isInSemester ? " bg-slate-900 " : " "; classOnThisDay && isInSemester ? " bg-slate-900 " : " ";
@@ -57,7 +55,7 @@ export default function Day({ day, month }: { day: string; month: number }) {
onDrop={(e) => itemDropOnDay(e, day)} onDrop={(e) => itemDropOnDay(e, day)}
onDragOver={(e) => e.preventDefault()} onDragOver={(e) => e.preventDefault()}
> >
<DropTargetStyling draggingClassName="bg-slate-900 shadow-[0_0px_10px_0px] shadow-blue-800/50 "> <div className="draggingDay">
<DayTitle day={day} dayAsDate={dayAsDate} /> <DayTitle day={day} dayAsDate={dayAsDate} />
<div> <div>
{todaysAssignments.map( {todaysAssignments.map(
@@ -93,7 +91,7 @@ export default function Day({ day, month }: { day: string; month: number }) {
/> />
))} ))}
</div> </div>
</DropTargetStyling> </div>
</div> </div>
); );
} }

View File

@@ -9,6 +9,7 @@ import {
} from "../../context/draggingContext"; } from "../../context/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";
export function ItemInDay({ export function ItemInDay({
type, type,
@@ -24,7 +25,7 @@ export function ItemInDay({
message: ReactNode; message: ReactNode;
}) { }) {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const { dragStart } = useDraggingContext(); const { setIsDragging } = useDragStyleContext();
const linkRef = useRef<HTMLAnchorElement>(null); const linkRef = useRef<HTMLAnchorElement>(null);
const [tooltipVisible, setTooltipVisible] = useState(false); const [tooltipVisible, setTooltipVisible] = useState(false);
return ( return (
@@ -52,7 +53,8 @@ export function ItemInDay({
"draggableItem", "draggableItem",
JSON.stringify(draggableItem) JSON.stringify(draggableItem)
); );
dragStart(); setIsDragging(true)
}} }}
onMouseEnter={() => setTooltipVisible(true)} onMouseEnter={() => setTooltipVisible(true)}
onMouseLeave={() => setTooltipVisible(false)} onMouseLeave={() => setTooltipVisible(false)}

View File

@@ -1,5 +1,5 @@
"use client"; "use client";
import { ReactNode, useCallback, DragEvent, useState, useEffect } from "react"; import { ReactNode, useCallback, DragEvent, useEffect } from "react";
import { DraggableItem, DraggingContext } from "./draggingContext"; import { DraggableItem, DraggingContext } from "./draggingContext";
import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
@@ -12,17 +12,18 @@ import { LocalAssignment } from "@/models/local/assignment/localAssignment";
import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks"; import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks";
import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks";
import { LocalCoursePage } from "@/models/local/page/localCoursePage"; import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { useDragStyleContext } from "./dragStyleContext";
export default function DraggingContextProvider({ export default function DraggingContextProvider({
children, children,
}: { }: {
children: ReactNode; children: ReactNode;
}) { }) {
const { setIsDragging } = useDragStyleContext();
const updateQuizMutation = useUpdateQuizMutation(); const updateQuizMutation = useUpdateQuizMutation();
const updateAssignmentMutation = useUpdateAssignmentMutation(); const updateAssignmentMutation = useUpdateAssignmentMutation();
const updatePageMutation = useUpdatePageMutation(); const updatePageMutation = useUpdatePageMutation();
const { data: settings } = useLocalCourseSettingsQuery(); const { data: settings } = useLocalCourseSettingsQuery();
const [isDragging, setIsDragging] = useState(false);
useEffect(() => { useEffect(() => {
const handleDrop = () => { const handleDrop = () => {
@@ -38,9 +39,7 @@ export default function DraggingContextProvider({
window.removeEventListener("drop", handleDrop); window.removeEventListener("drop", handleDrop);
window.addEventListener("dragover", preventDefault); window.addEventListener("dragover", preventDefault);
}; };
}, []); }, [setIsDragging]);
const dragStart = useCallback(() => setIsDragging(true), []);
const itemDropOnModule = useCallback( const itemDropOnModule = useCallback(
(e: DragEvent<HTMLDivElement>, dropModuleName: string) => { (e: DragEvent<HTMLDivElement>, dropModuleName: string) => {
@@ -92,7 +91,12 @@ export default function DraggingContextProvider({
}); });
} }
}, },
[updateAssignmentMutation, updatePageMutation, updateQuizMutation] [
setIsDragging,
updateAssignmentMutation,
updatePageMutation,
updateQuizMutation,
]
); );
const itemDropOnDay = useCallback( const itemDropOnDay = useCallback(
@@ -174,6 +178,7 @@ export default function DraggingContextProvider({
} }
}, },
[ [
setIsDragging,
settings.defaultDueTime.hour, settings.defaultDueTime.hour,
settings.defaultDueTime.minute, settings.defaultDueTime.minute,
updateAssignmentMutation, updateAssignmentMutation,
@@ -181,14 +186,13 @@ export default function DraggingContextProvider({
updateQuizMutation, updateQuizMutation,
] ]
); );
console.log("rerender");
return ( return (
<DraggingContext.Provider <DraggingContext.Provider
value={{ value={{
itemDropOnDay, itemDropOnDay,
itemDropOnModule, itemDropOnModule,
isDragging,
dragStart,
}} }}
> >
{children} {children}

View File

@@ -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={"min-h-0 flex flex-col " + (isDragging ? " dragging " : "")}
>
{children}
</div>
</DragStyleContext.Provider>
);
}

View File

@@ -11,14 +11,10 @@ export interface DraggableItem {
export interface DraggingContextInterface { export interface DraggingContextInterface {
itemDropOnDay: (e: DragEvent<HTMLDivElement>, droppedOnDay: string) => void; itemDropOnDay: (e: DragEvent<HTMLDivElement>, droppedOnDay: string) => void;
itemDropOnModule: (e: DragEvent<HTMLDivElement>, moduleName: string) => void; itemDropOnModule: (e: DragEvent<HTMLDivElement>, moduleName: string) => void;
isDragging: boolean;
dragStart: () => void;
} }
const defaultDraggingValue: DraggingContextInterface = { const defaultDraggingValue: DraggingContextInterface = {
itemDropOnDay: () => {}, itemDropOnDay: () => {},
itemDropOnModule: () => {}, itemDropOnModule: () => {},
isDragging: false,
dragStart: () => {},
}; };
export const DraggingContext = export const DraggingContext =
createContext<DraggingContextInterface>(defaultDraggingValue); createContext<DraggingContextInterface>(defaultDraggingValue);

View File

@@ -15,11 +15,11 @@ 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/draggingContext";
import DropTargetStyling from "../../../../components/DropTargetStyling";
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";
export default function ExpandableModule({ export default function ExpandableModule({
moduleName, moduleName,
@@ -67,7 +67,7 @@ export default function ExpandableModule({
onDrop={(e) => itemDropOnModule(e, moduleName)} onDrop={(e) => itemDropOnModule(e, moduleName)}
onDragOver={(e) => e.preventDefault()} onDragOver={(e) => e.preventDefault()}
> >
<DropTargetStyling draggingClassName="shadow-[0_0px_10px_0px] shadow-blue-500/50 "> <div className="draggingModule ">
<div className=" p-3 "> <div className=" p-3 ">
<Expandable <Expandable
ExpandableElement={({ setIsExpanded, isExpanded }) => ( ExpandableElement={({ setIsExpanded, isExpanded }) => (
@@ -116,7 +116,7 @@ export default function ExpandableModule({
</> </>
</Expandable> </Expandable>
</div> </div>
</DropTargetStyling> </div>
</div> </div>
); );
} }
@@ -132,7 +132,7 @@ function ExpandableModuleItem({
}) { }) {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const date = getDateFromString(item.dueAt); const date = getDateFromString(item.dueAt);
const { dragStart } = useDraggingContext(); const { setIsDragging } = useDragStyleContext();
return ( return (
<Fragment key={item.name + type}> <Fragment key={item.name + type}>
@@ -153,7 +153,7 @@ function ExpandableModuleItem({
"draggableItem", "draggableItem",
JSON.stringify(draggableItem) JSON.stringify(draggableItem)
); );
dragStart(); setIsDragging(true);
}} }}
> >
{item.name} {item.name}

View File

@@ -2,27 +2,29 @@ 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/DraggingContextProvider";
import Link from "next/link";
import CourseTitle from "./CourseTitle"; import CourseTitle from "./CourseTitle";
import { CourseNavigation } from "./CourseNavigation"; import { CourseNavigation } from "./CourseNavigation";
import { DragStyleContextProvider } from "./context/dragStyleContext";
export default async function CoursePage({}: {}) { export default async function CoursePage({}: {}) {
return ( return (
<> <>
<CourseTitle /> <CourseTitle />
<div className="h-full flex flex-col"> <div className="h-full flex flex-col">
<div className="flex flex-row min-h-0"> <DragStyleContextProvider>
<DraggingContextProvider> <DraggingContextProvider>
<div className="flex-1 min-h-0 flex flex-col"> <div className="flex flex-row min-h-0">
<CourseNavigation /> <div className="flex-1 min-h-0 flex flex-col">
<CourseCalendar /> <CourseNavigation />
</div> <CourseCalendar />
<div className="w-96 p-3 h-full overflow-y-auto"> </div>
<CourseSettingsLink /> <div className="w-96 p-3 h-full overflow-y-auto">
<ModuleList /> <CourseSettingsLink />
<ModuleList />
</div>
</div> </div>
</DraggingContextProvider> </DraggingContextProvider>
</div> </DragStyleContextProvider>
</div> </div>
</> </>
); );

View File

@@ -137,3 +137,19 @@ select {
.markdownPreview a { .markdownPreview a {
@apply text-blue-500 hover:text-blue-600 font-bold underline; @apply text-blue-500 hover:text-blue-600 font-bold underline;
} }
.draggingDay {
@apply h-full transition-all duration-500;
}
.dragging .draggingDay {
@apply bg-slate-900 shadow-[0_0px_10px_0px] shadow-blue-800/50;
}
.draggingModule {
@apply h-full transition-all duration-500;
}
.dragging .draggingModule {
@apply shadow-[0_0px_10px_0px] shadow-blue-500/50;
}

View File

@@ -1,22 +0,0 @@
import React, { ReactNode } from "react";
import { useDraggingContext } from "../app/course/[courseName]/context/draggingContext";
export default function DropTargetStyling({
children,
draggingClassName,
}: {
children: ReactNode;
draggingClassName: string;
}) {
const { isDragging } = useDraggingContext();
return (
<div
className={
"h-full transition-all duration-500 " +
(isDragging ? draggingClassName : "")
}
>
{children}
</div>
);
}