diff --git a/.replit b/.replit
index ccafaa6..4f7eaad 100644
--- a/.replit
+++ b/.replit
@@ -19,7 +19,7 @@ localPort = 35345
externalPort = 3002
[[ports]]
-localPort = 40293
+localPort = 39333
externalPort = 3001
[[ports]]
diff --git a/client/src/components/KanbanBoard.tsx b/client/src/components/KanbanBoard.tsx
index 913beaa..0ed76a4 100644
--- a/client/src/components/KanbanBoard.tsx
+++ b/client/src/components/KanbanBoard.tsx
@@ -7,7 +7,7 @@ import { LayoutGrid, Calendar as CalendarIcon, ChevronLeft, ChevronRight } from
import { Task, Label } from '@shared/schema';
import TaskCard from './TaskCard';
import { useQuery } from '@tanstack/react-query';
-import { format, startOfWeek, endOfWeek, startOfMonth, endOfMonth, addWeeks, addMonths, isWithinInterval, addDays, isSameDay, getDaysInMonth } from 'date-fns';
+import { format, startOfWeek, endOfWeek, startOfMonth, endOfMonth, addWeeks, addMonths, isWithinInterval } from 'date-fns';
interface KanbanBoardProps {
tasks: Task[];
@@ -78,8 +78,10 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate }:
const navigatePeriod = (direction: 'prev' | 'next') => {
if (viewMode === 'weekly') {
setCurrentDate(addWeeks(currentDate, direction === 'next' ? 1 : -1));
+ console.log(`Navigating to week of ${format(addWeeks(currentDate, direction === 'next' ? 1 : -1), 'd.M.yyyy')}`);
} else if (viewMode === 'monthly') {
setCurrentDate(addMonths(currentDate, direction === 'next' ? 1 : -1));
+ console.log(`Navigating to month of ${format(addMonths(currentDate, direction === 'next' ? 1 : -1), 'MMM yyyy')}`);
}
};
@@ -92,195 +94,6 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate }:
return 'All Tasks';
};
- const getTasksForDate = (date: Date) => {
- return tasks.filter(task =>
- task.dueDate && isSameDay(task.dueDate, date)
- );
- };
-
- const handleDateDrop = (date: Date) => {
- if (draggedTask) {
- const task = tasks.find(t => t.id === draggedTask);
- if (task) {
- onTaskUpdate?.(draggedTask, { dueDate: date });
- console.log(`Task ${draggedTask} moved to ${format(date, 'yyyy-MM-dd')}`);
- }
- setDraggedTask(null);
- }
- };
-
- const renderWeeklyCalendar = () => {
- const weekStart = startOfWeek(currentDate);
- const dates = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
-
- return (
-
- {dates.map((date, index) => {
- const dayTasks = getTasksForDate(date);
- const isToday = isSameDay(date, new Date());
- const isWeekend = date.getDay() === 0 || date.getDay() === 6;
-
- return (
-
handleDateDrop(date)}
- data-testid={`calendar-date-${format(date, 'yyyy-MM-dd')}`}
- >
-
-
- {format(date, 'EEE')}
-
-
- {format(date, 'd')}
-
-
-
-
- {dayTasks.slice(0, 3).map((task) => {
- const taskLabel = task.labelId && labels.length > 0 ? labels.find(label => label.id === task.labelId) : null;
-
- return (
-
handleDragStart(task.id)}
- onDragEnd={handleDragEnd}
- className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
- data-testid={`calendar-task-${task.id}`}
- >
-
-
- {task.title}
-
-
-
- );
- })}
-
- {dayTasks.length > 3 && (
-
- +{dayTasks.length - 3} more
-
- )}
-
-
- );
- })}
-
- );
- };
-
- const renderMonthlyCalendar = () => {
- const monthStart = startOfMonth(currentDate);
- const monthEnd = endOfMonth(currentDate);
- const calendarStart = startOfWeek(monthStart);
- const calendarEnd = endOfWeek(monthEnd);
-
- const dates = [];
- let currentDateIterator = calendarStart;
-
- while (currentDateIterator <= calendarEnd) {
- dates.push(currentDateIterator);
- currentDateIterator = addDays(currentDateIterator, 1);
- }
-
- return (
-
- {/* Month grid header */}
-
- {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
-
- {day}
-
- ))}
-
-
- {/* Month grid */}
-
- {dates.map((date, index) => {
- const dayTasks = getTasksForDate(date);
- const isToday = isSameDay(date, new Date());
- const isCurrentMonth = date >= monthStart && date <= monthEnd;
-
- return (
-
handleDateDrop(date)}
- data-testid={`calendar-date-${format(date, 'yyyy-MM-dd')}`}
- >
-
-
- {format(date, 'd')}
-
-
-
-
- {dayTasks.slice(0, 2).map((task) => {
- const taskLabel = task.labelId && labels.length > 0 ? labels.find(label => label.id === task.labelId) : null;
-
- return (
-
handleDragStart(task.id)}
- onDragEnd={handleDragEnd}
- className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
- data-testid={`calendar-task-${task.id}`}
- >
-
-
- {task.title}
-
-
-
- );
- })}
-
- {dayTasks.length > 2 && (
-
- +{dayTasks.length - 2}
-
- )}
-
-
- );
- })}
-
-
- );
- };
return (
@@ -339,8 +152,8 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate }:
+ {/* All view modes use the same kanban layout, just with different filtering */}
- {/* Kanban Columns */}
{columns.map((column) => {
const columnTasks = getTasksForColumn(column.status);
@@ -402,11 +215,125 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate }:
- {renderWeeklyCalendar()}
+
+ {columns.map((column) => {
+ const columnTasks = getTasksForColumn(column.status);
+
+ return (
+
handleDrop(column.status)}
+ data-testid={`column-${column.id}`}
+ >
+
+
+ {column.title}
+
+
+ {columnTasks.length}
+
+
+
+
+ {columnTasks.map((task) => (
+
handleDragStart(task.id)}
+ onDragEnd={handleDragEnd}
+ className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
+ >
+ {
+ onTaskUpdate?.(task.id, { isTracking: true });
+ console.log(`Timer started for ${task.title}`);
+ }}
+ onPause={() => {
+ onTaskUpdate?.(task.id, { isTracking: false });
+ console.log(`Timer paused for ${task.title}`);
+ }}
+ onEdit={() => {
+ console.log(`Edit task ${task.title}`);
+ }}
+ isDragging={draggedTask === task.id}
+ />
+
+ ))}
+
+ {columnTasks.length === 0 && (
+
+ No tasks in {column.title.toLowerCase()} for this week
+
+ )}
+
+
+ );
+ })}
+
- {renderMonthlyCalendar()}
+
+ {columns.map((column) => {
+ const columnTasks = getTasksForColumn(column.status);
+
+ return (
+
handleDrop(column.status)}
+ data-testid={`column-${column.id}`}
+ >
+
+
+ {column.title}
+
+
+ {columnTasks.length}
+
+
+
+
+ {columnTasks.map((task) => (
+
handleDragStart(task.id)}
+ onDragEnd={handleDragEnd}
+ className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
+ >
+ {
+ onTaskUpdate?.(task.id, { isTracking: true });
+ console.log(`Timer started for ${task.title}`);
+ }}
+ onPause={() => {
+ onTaskUpdate?.(task.id, { isTracking: false });
+ console.log(`Timer paused for ${task.title}`);
+ }}
+ onEdit={() => {
+ console.log(`Edit task ${task.title}`);
+ }}
+ isDragging={draggedTask === task.id}
+ />
+
+ ))}
+
+ {columnTasks.length === 0 && (
+
+ No tasks in {column.title.toLowerCase()} for this month
+
+ )}
+
+
+ );
+ })}
+