Rename "Templates" tab to "Settings" and enhance calendar functionality

Refactors the application's navigation by renaming the 'templates' tab to 'settings'. It also introduces several enhancements to the calendar view, including fetching and displaying labels with custom colors, enabling drag-and-drop functionality for tasks onto specific dates, and improving the rendering of weekly calendar views with better date and task handling. The `ProjectTemplate` component is updated to `Project` with new interfaces and default data.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/oa49Utu
This commit is contained in:
paul-nothaft
2025-09-11 14:15:58 +00:00
parent 36453140f3
commit d5688f90b0
9 changed files with 606 additions and 267 deletions
+37 -19
View File
@@ -5,8 +5,9 @@ import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Search, Filter, SortAsc, Calendar, ChevronLeft, ChevronRight } from 'lucide-react';
import { Task } from '@shared/schema';
import { Task, Label } from '@shared/schema';
import TaskCard from './TaskCard';
import { useQuery } from '@tanstack/react-query';
import TimeCompletionModal from './TimeCompletionModal';
import { addDays, format, isSameDay, startOfToday } from 'date-fns';
@@ -31,6 +32,13 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit }: T
task: null
});
// Fetch labels to get label colors
const { data: labels = [] } = useQuery<Label[]>({
queryKey: ['/api/labels'],
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
// Get 7 days starting from today for calendar
const dates = Array.from({ length: 7 }, (_, i) => addDays(calendarStartDate, i));
@@ -371,25 +379,35 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit }: T
</div>
<div className="space-y-1">
{dayTasks.slice(0, 2).map((task) => (
<div
key={task.id}
draggable
onDragStart={(e) => handleDragStart(task.id, e)}
onDragEnd={handleDragEnd}
className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
data-testid={`calendar-task-${task.id}`}
>
<Badge
variant="outline"
className="w-full justify-start text-xs p-1 h-auto text-left"
{dayTasks.slice(0, 2).map((task) => {
// Find the label for this task
const taskLabel = task.labelId && labels.length > 0 ? labels.find(label => label.id === task.labelId) : null;
return (
<div
key={task.id}
draggable
onDragStart={(e) => handleDragStart(task.id, e)}
onDragEnd={handleDragEnd}
className={`cursor-move ${draggedTask === task.id ? 'opacity-50' : ''}`}
data-testid={`calendar-task-${task.id}`}
>
<div className="truncate text-xs">
{task.title}
</div>
</Badge>
</div>
))}
<Badge
variant="outline"
className="w-full justify-start text-xs p-1 h-auto text-left"
style={taskLabel ? {
borderColor: taskLabel.color,
borderWidth: '2px',
borderStyle: 'solid'
} : {}}
>
<div className="truncate text-xs">
{task.title}
</div>
</Badge>
</div>
);
})}
{dayTasks.length > 2 && (
<Badge variant="secondary" className="w-full justify-center text-xs py-0">