From 4d0d750042d49b01b6bfdc547a19d939311e0005 Mon Sep 17 00:00:00 2001 From: paul-nothaft <40865108-paul-nothaft@users.noreply.replit.com> Date: Thu, 11 Sep 2025 21:51:41 +0000 Subject: [PATCH] Add planned end date for projects and improve task interaction Adds a 'plannedEndDate' field to projects, making it editable. Enhances task interaction by allowing direct clicking on tasks in various views to open details and report time. Also, includes a helper function to ensure date selections respect the current day. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/P2PZNJ9 --- .replit | 4 + client/src/components/ProjectTemplate.tsx | 98 ++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/.replit b/.replit index 61099cd..dddfbf4 100644 --- a/.replit +++ b/.replit @@ -18,6 +18,10 @@ externalPort = 80 localPort = 35345 externalPort = 3002 +[[ports]] +localPort = 38369 +externalPort = 3001 + [[ports]] localPort = 41353 externalPort = 3000 diff --git a/client/src/components/ProjectTemplate.tsx b/client/src/components/ProjectTemplate.tsx index e10195a..17b7403 100644 --- a/client/src/components/ProjectTemplate.tsx +++ b/client/src/components/ProjectTemplate.tsx @@ -13,6 +13,12 @@ import { Label } from '@shared/schema'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { apiRequest } from '@/lib/queryClient'; +// Helper function to get today's date at start of day for proper date comparison +const getStartOfToday = () => { + const today = new Date(); + return new Date(today.getFullYear(), today.getMonth(), today.getDate()); +}; + interface ProjectTask { id: string; title: string; @@ -31,6 +37,7 @@ interface Project { tasks: ProjectTask[]; startDate?: Date; endDate?: Date; + plannedEndDate?: Date; createdAt: Date; } @@ -94,6 +101,8 @@ export default function ProjectTemplate({ const [isEditProjectOpen, setIsEditProjectOpen] = useState(false); const [newProjectName, setNewProjectName] = useState(''); const [newProjectDescription, setNewProjectDescription] = useState(''); + const [newPlannedEndDate, setNewPlannedEndDate] = useState(); + const [isPlannedEndDateCalendarOpen, setIsPlannedEndDateCalendarOpen] = useState(false); const [isRestartProjectOpen, setIsRestartProjectOpen] = useState(false); const [restartingProject, setRestartingProject] = useState(null); const [newEndDate, setNewEndDate] = useState(); @@ -162,12 +171,14 @@ export default function ProjectTemplate({ description: newProjectDescription.trim() || undefined, status: 'planning', tasks: projectTasks, + plannedEndDate: newPlannedEndDate, createdAt: new Date() }; setProjects([...projects, newProject]); setNewProjectName(''); setNewProjectDescription(''); + setNewPlannedEndDate(undefined); setProjectTasks([]); setIsCreateProjectOpen(false); console.log('Created new project:', newProject.name, 'with', projectTasks.length, 'tasks'); @@ -650,7 +661,7 @@ export default function ProjectTemplate({ setNewEndDate(date); setIsEndDateCalendarOpen(false); }} - disabled={(date) => date < new Date()} + disabled={(date) => date < getStartOfToday()} initialFocus /> @@ -700,6 +711,9 @@ export default function ProjectTemplate({ {/* Create Project Dialog */} { setIsCreateProjectOpen(false); + setNewProjectName(''); + setNewProjectDescription(''); + setNewPlannedEndDate(undefined); setProjectTasks([]); setTaskForm({}); setIsEditingTask(false); @@ -731,6 +745,46 @@ export default function ProjectTemplate({ + {/* Planned End Date */} +
+ + + + + + + { + setNewPlannedEndDate(date); + setIsPlannedEndDateCalendarOpen(false); + }} + disabled={(date) => date < getStartOfToday()} + initialFocus + /> + + + {newPlannedEndDate && ( + + )} +
+ {/* Tasks Section */}
@@ -980,6 +1034,48 @@ export default function ProjectTemplate({
+ {/* Planned End Date */} +
+ + + + + + + { + setSelectedProject({ ...selectedProject, plannedEndDate: date }); + setIsPlannedEndDateCalendarOpen(false); + }} + disabled={(date) => date < getStartOfToday()} + initialFocus + /> + + + {selectedProject.plannedEndDate && ( + + )} +
+ {/* Tasks Section */}