diff --git a/CHANGELOG.md b/CHANGELOG.md index fdafee1..d92b22c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this project are documented in this file. +## [1.115.3] - 2026-09-03 + +### Fixed +- Drag & drop in views wider than 7 days: the drop target was keyed by weekday + (`date.getDay()`), which is only unique inside a 7-day window. In a 21-day view every + column sharing the weekday of the hovered one lit up as a drop target — three mirrored + highlights, one per Tuesday. Now keyed by the local date. +- Same bug, worse half: `handleDrop` resolved the target date with + `visibleDays.find(d => d.getDay() === dayOfWeek)`, so dropping a task on the second or + third Tuesday of a wide view silently scheduled it on the *first* Tuesday. The drop now + uses the column's own date. Tasks dragged in a >7-day view before this fix may sit on the + wrong date. +- The inline "click an empty slot to add a task" input had the same weekday key, so clicking + one slot opened an input in every column with that weekday. + ## [1.115.2] - 2026-09-03 ### Changed diff --git a/package-lock.json b/package-lock.json index 6ccc354..cff65a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "my-weekly-todo-list", - "version": "1.115.2", + "version": "1.115.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "my-weekly-todo-list", - "version": "1.115.2", + "version": "1.115.3", "license": "MIT", "dependencies": { "@auth/prisma-adapter": "^2.11.1", diff --git a/package.json b/package.json index 74f8aa8..f4aeba4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.115.2", + "version": "1.115.3", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 29cd18a..619d750 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -1071,8 +1071,10 @@ export default function WeeklyView() { const [slideDirection, setSlideDirection] = useState<"next" | "prev" | null>( null, ); + // Keyed by local date ("YYYY-MM-DD"), not by weekday: with more than 7 visible day + // columns a weekday matches several columns at once, which lit up every Tuesday. const [activeSlot, setActiveSlot] = useState<{ - day: number; + dateKey: string; slot: string; } | null>(null); const [newSlotTask, setNewSlotTask] = useState(""); @@ -1081,7 +1083,7 @@ export default function WeeklyView() { ); const [currentTime, setCurrentTime] = useState(new Date()); const [dropPreview, setDropPreview] = useState<{ - day?: number; + dateKey?: string; slot?: string; listId?: string; slotIdx?: number; @@ -5023,7 +5025,7 @@ export default function WeeklyView() { const handleDragOver = ( e: DragEvent | React.DragEvent, - dayOfWeek?: number, + date?: Date, slot?: string, ) => { // Reject someday list drags on day slots @@ -5039,17 +5041,16 @@ export default function WeeklyView() { e.dataTransfer.dropEffect = "move"; } // Update drop preview if we have day and slot info - if (dayOfWeek !== undefined && slot) { - setDropPreview({ day: dayOfWeek, slot }); + if (date && slot) { + setDropPreview({ dateKey: formatDateToISO(date), slot }); } }; - const handleDrop = async (e: DragEvent, dayOfWeek: number, slot?: string) => { + const handleDrop = async (e: DragEvent, date: Date, slot?: string) => { e.preventDefault(); if (draggedTask) { - const visibleDays = getVisibleDays(); - const targetDateObj = - visibleDays.find((d) => d.getDay() === dayOfWeek) || new Date(); + const targetDateObj = date; + const dayOfWeek = targetDateObj.getDay(); let targetSlot = slot; @@ -7652,7 +7653,7 @@ export default function WeeklyView() { const isHourStart = minutes === "00"; const slotEvents = getEventsForSlot(date, slot); const isActive = - activeSlot?.day === date.getDay() && + activeSlot?.dateKey === formatDateToISO(date) && activeSlot?.slot === slot; const isProtected = isSlotProtected(date, slot); const isOccupiedByTask = isSlotOccupiedByTask(date, slot, draggedTask?.id); @@ -7674,7 +7675,7 @@ export default function WeeklyView() { } if (!isActive) { - setActiveSlot({ day: date.getDay(), slot }); + setActiveSlot({ dateKey: formatDateToISO(date), slot }); setNewSlotTask(""); } }; @@ -7694,11 +7695,11 @@ export default function WeeklyView() { const handleSlotDrop = (e: React.DragEvent) => { e.preventDefault(); if (isProtected || isOccupiedByTask) return; // Don't allow dropping on protected or occupied slots - handleDrop(e, date.getDay(), slot); + handleDrop(e, date, slot); }; const isDropTarget = - dropPreview?.day === date.getDay() && + dropPreview?.dateKey === formatDateToISO(date) && dropPreview?.slot === slot; const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; @@ -7736,7 +7737,7 @@ export default function WeeklyView() { }} onDragOver={(e) => !isProtected && !isOccupiedByTask && - handleDragOver(e, date.getDay(), slot) + handleDragOver(e, date, slot) } onDrop={handleSlotDrop} > @@ -7947,8 +7948,8 @@ export default function WeeklyView() { ) : (