From e8debb4535a95cdc440fd5e9ae41a597167fcbd6 Mon Sep 17 00:00:00 2001 From: Akaswan Date: Mon, 28 Jul 2025 22:45:48 -0500 Subject: [PATCH] Saving before major structural changes are made --- src/main/components/App.tsx | 51 +++++++++++++------- src/main/components/Table.tsx | 61 +++++++++++++++--------- src/main/components/TaskCell.tsx | 3 ++ src/main/components/TaskEditor.tsx | 46 ++++++++++++++++++ src/main/main.ts | 76 ++++++++++++++++++++++++++---- src/main/sharedState.ts | 32 +++++++++++++ src/main/views/TableView.tsx | 16 +++++-- src/main/views/TaskEditorView.tsx | 66 ++++++++++++++++++++++++++ 8 files changed, 296 insertions(+), 55 deletions(-) create mode 100644 src/main/components/TaskEditor.tsx create mode 100644 src/main/sharedState.ts create mode 100644 src/main/views/TaskEditorView.tsx diff --git a/src/main/components/App.tsx b/src/main/components/App.tsx index f297b48..255adb3 100644 --- a/src/main/components/App.tsx +++ b/src/main/components/App.tsx @@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { useTableContext } from "../views/TableView"; import Table from "./Table"; import TopBar from "./TopBar"; -import { format, addDays, subDays, isSameDay } from "date-fns"; +import { addDays, subDays } from "date-fns"; import { createClient } from "@supabase/supabase-js"; import { Project, TableData, Task, TaskStatus } from "../types"; @@ -13,9 +13,27 @@ const supabaseAnonKey = process.env.SUPABASE_ANON_KEY ?? ""; const supabase = createClient(supabaseUrl, supabaseAnonKey); /** Utility Functions **/ -const getWeekDates = (startDate: Date, numDates: number) => +export const toMidnight = (date: Date | string): Date => { + const d = new Date(date); + d.setHours(0, 0, 0, 0); // set time to 00:00 UTC + return d; +}; + +const normalizeHours = (d: Date) => { + const copy = new Date(d); + copy.setHours(0, 0, 0, 0); + return copy; +}; + +const isBeforeNormalizedDay = (a: Date, b: Date) => + normalizeHours(a).getTime() < normalizeHours(b).getTime(); + +const isSameNormalizedDay = (a: Date, b: Date) => + normalizeHours(a).getTime() === normalizeHours(b).getTime(); + +const getWeekDates = (startDate: Date, numDates: number): Date[] => Array.from({ length: numDates }, (_, i) => - format(addDays(startDate, i), "yyyy-MM-dd") + addDays(startDate, i) ); const getTaskStatuses = (): TaskStatus[] => [ @@ -85,6 +103,7 @@ const App: React.FC = () => { const setDatesToThisWeek = () => { const today = new Date(); + console.log(today); setBaseDate(today); setDates(getWeekDates(today, datesShown)); }; @@ -153,10 +172,11 @@ const App: React.FC = () => { }; const moveTask = (id: number, newDate: string) => { + const normalizedDate = toMidnight(newDate); const newProjects = projects.map((p) => ({ ...p, tasks: p.tasks.map((t) => - t.id === id ? { ...t, date: new Date(newDate) } : t + t.id === id ? { ...t, date: normalizedDate } : t ), })); saveSpecificData("projects", newProjects); @@ -182,11 +202,11 @@ const App: React.FC = () => { setTimeout(() => ref.current?.focus(), 0); }; - const addTaskToProject = (project: Project, date: string) => { + const addTaskToProject = (project: Project, date: Date) => { const newTask: Task = { id: nextTaskId, name: "", - date: new Date(date), + date: toMidnight(date), parentProjectId: project.id, status: taskStatuses[0], }; @@ -202,25 +222,15 @@ const App: React.FC = () => { setNextTaskId(newId); }; -const normalizeDateUTC = (d: Date) => { - const copy = new Date(d); - copy.setUTCHours(0, 0, 0, 0); - return copy; -}; - -const isBeforeDayUTC = (a: Date, b: Date) => - normalizeDateUTC(a).getTime() < normalizeDateUTC(b).getTime(); - const findPendingTasksLeftSide = () => { let number = 0; projects.forEach((project) => { project.tasks.forEach((task) => { if ( - isBeforeDayUTC(new Date(task.date), baseDate) && + isBeforeNormalizedDay(new Date(task.date), baseDate) && task.status.id !== "completed" ) { number++; - console.log(new Date(task.date)); } }); }); @@ -311,6 +321,10 @@ const isBeforeDayUTC = (a: Date, b: Date) => /** Effects **/ useEffect(() => { dataRef.current = data; + // dates.forEach((date) => { + // console.log(new Date(date)); + // }); + console.log(toMidnight(new Date())); }, [data]); useEffect(() => { syncWithServer(); @@ -325,7 +339,7 @@ const isBeforeDayUTC = (a: Date, b: Date) => projects.forEach((project) => { project.tasks.forEach((task) => { if ( - isSameDay(new Date(task.date), subDays(new Date(), 1)) && + isSameNormalizedDay(new Date(task.date), new Date()) && task.status.id !== "completed" ) { remainingTasks++; @@ -384,6 +398,7 @@ const isBeforeDayUTC = (a: Date, b: Date) => editTaskStatus={editTaskStatus} moveTask={moveTask} wrapperRef={wrapperRef} + sharedState={tableContext!.sharedState} /> ); diff --git a/src/main/components/Table.tsx b/src/main/components/Table.tsx index 31577c7..a093aed 100644 --- a/src/main/components/Table.tsx +++ b/src/main/components/Table.tsx @@ -1,9 +1,11 @@ -import { format, parseISO } from "date-fns"; +import { format, isSameDay } from "date-fns"; import { useRef } from "react"; import * as React from "react"; import TaskCell from "./TaskCell"; import { DndContext, useDroppable, DragEndEvent } from "@dnd-kit/core"; import { Project, TaskStatus } from "../types"; +import { IntraViewData } from "../main"; +import { SharedState } from "../sharedState"; interface TableProps { projects: Project[]; @@ -13,8 +15,8 @@ interface TableProps { newName: string, newProjectInputRef: React.RefObject ) => void; - dates: string[]; - addTaskToProject: (project: Project, date: string) => void; + dates: Date[]; + addTaskToProject: (project: Project, date: Date) => void; removeProject: (id: number) => void; removeTask: (id: number) => void; nextTaskId: number; @@ -23,6 +25,7 @@ interface TableProps { editTaskStatus: (id: number, newStatusId: string) => void; moveTask: (taskId: number, newDate: string) => void; wrapperRef: React.RefObject; + sharedState: SharedState | null; } function DroppableCell({ @@ -62,11 +65,21 @@ const Table: React.FC = ({ taskStatuses, editTaskStatus, moveTask, - wrapperRef, + sharedState, }) => { const newProjectInputRef = useRef(null); const newTaskInputRef = useRef(null); + const isTaskAutoFocused = (taskId: number, taskName: string) => { + if (taskId === nextTaskId - 1 && taskName === "") { + sharedState?.set({ selectedTaskId: taskId }); + console.log("Auto focusing task:", taskId); + return true; + } else { + return false; + } + }; + return ( { @@ -86,18 +99,17 @@ const Table: React.FC = ({ Projects {dates.map((date) => { - const dateObj = parseISO(date); return ( - +
- {format(dateObj, "EEEE")} + {format(date, "EEEE")}
- {format( - dateObj, - "yyyy-MM-dd" - )} + {format(date, "yyyy-MM-dd")}
@@ -134,7 +146,7 @@ const Table: React.FC = ({ } /> - {dates.map((date, index) => ( + {dates.map((date) => ( { @@ -150,23 +162,23 @@ const Table: React.FC = ({ }, 0); } }} - key={`${project.id}-${date}`} // ADD KEY HERE + key={`${project.id}-${date}`} > {project.tasks - .filter( - (task) => - new Date( - task.date - ).toISOString() === - new Date( - date - ).toISOString() + .filter((task) => + isSameDay( + new Date(task.date), + new Date(date) + ) ) .map((task) => ( = ({ editTaskStatus={ editTaskStatus } + onFocus={(taskId) => { + sharedState?.set({ + selectedTaskId: taskId, + }); + }} /> ))} diff --git a/src/main/components/TaskCell.tsx b/src/main/components/TaskCell.tsx index 9009465..e89c267 100644 --- a/src/main/components/TaskCell.tsx +++ b/src/main/components/TaskCell.tsx @@ -47,6 +47,7 @@ interface TaskCellProps { taskStatuses: TaskStatus[]; editTaskStatus: (id: number, newStatusId: string) => void; autoFocus?: boolean; + onFocus: (taskId: number) => void; } const TaskCell: React.FC = ({ @@ -59,6 +60,7 @@ const TaskCell: React.FC = ({ taskStatuses, editTaskStatus, autoFocus = false, // default to false if not provided + onFocus, }) => { const taskBackground = `${status.color}33`; const lightTaskTextColor = transColor(status.color, 25); @@ -175,6 +177,7 @@ const TaskCell: React.FC = ({ height: "auto", }} rows={1} + onFocus={() => onFocus(task.id)} />