Add labels to tasks for better organization and filtering

Introduce a label system to categorize tasks, enhancing organization and enabling filtering. The initial setup includes default labels like 'Work', 'Personal', 'Urgent', and 'Study', with fixed IDs for consistent data management. The client-side now supports associating labels with tasks, and the `TaskCard` component fetches labels to display their corresponding colors. The server-side storage has been updated to use predefined IDs for these default labels.

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/wGjfXkl
This commit is contained in:
paul-nothaft
2025-09-11 12:52:53 +00:00
parent 4ea8a7c6a1
commit 18fc3fed81
4 changed files with 20 additions and 13 deletions
+12 -7
View File
@@ -28,7 +28,8 @@ const initialTasks: Task[] = [
dueDate: addDays(new Date(), 2),
timeTracked: 0,
isTracking: false,
projectId: 'project-1'
projectId: 'project-1',
labelId: '2e8c3aa0-278f-4220-b2c5-aa109b4279b7' // Urgent label
},
{
id: '2',
@@ -39,16 +40,18 @@ const initialTasks: Task[] = [
dueDate: addDays(new Date(), 1),
timeTracked: 120,
isTracking: true,
projectId: 'project-2'
projectId: 'project-2',
labelId: 'cb44bed1-8ba3-43fe-9498-bb28e483ed1f' // Work label
},
{
id: '3',
title: 'Team standup meeting',
status: 'todo',
priority: 'low',
dueDate: new Date(),
dueDate: undefined, // Make unscheduled
timeTracked: 0,
isTracking: false
isTracking: false,
labelId: '274f0ba4-a133-471a-bbe9-8189aa3b0106' // Personal label
},
{
id: '4',
@@ -56,10 +59,11 @@ const initialTasks: Task[] = [
description: 'Users unable to login with special characters in password',
status: 'todo',
priority: 'high',
dueDate: subDays(new Date(), 1),
dueDate: undefined, // Make unscheduled
timeTracked: 30,
isTracking: false,
projectId: 'project-2'
projectId: 'project-2',
labelId: 'c5eccac9-7919-4eb1-bb50-badacad6b1c1' // Study label
},
{
id: '5',
@@ -88,7 +92,8 @@ function App() {
dueDate: newTask.dueDate,
timeTracked: 0,
isTracking: false,
projectId: newTask.projectId
projectId: newTask.projectId,
labelId: newTask.labelId
};
setTasks(prev => [...prev, task]);
console.log('Task created:', task);
+1
View File
@@ -21,6 +21,7 @@ export default function TaskCard({ task, onPlay, onPause, onEdit, onStatusChange
// Fetch labels to get the label color
const { data: labels = [], isLoading: labelsLoading, error: labelsError } = useQuery<Label[]>({
queryKey: ['/api/labels'],
queryFn: () => fetch('/api/labels').then(res => res.json()),
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

+7 -6
View File
@@ -39,15 +39,16 @@ export class MemStorage implements IStorage {
}
private async createDefaultLabels() {
// Use fixed IDs to prevent ID churn on server restarts
const defaultLabels = [
{ name: "Work", color: "#3B82F6" },
{ name: "Personal", color: "#10B981" },
{ name: "Urgent", color: "#EF4444" },
{ name: "Study", color: "#8B5CF6" },
{ id: 'cb44bed1-8ba3-43fe-9498-bb28e483ed1f', name: "Work", color: "#3B82F6" },
{ id: '274f0ba4-a133-471a-bbe9-8189aa3b0106', name: "Personal", color: "#10B981" },
{ id: '2e8c3aa0-278f-4220-b2c5-aa109b4279b7', name: "Urgent", color: "#EF4444" },
{ id: 'c5eccac9-7919-4eb1-bb50-badacad6b1c1', name: "Study", color: "#8B5CF6" },
];
for (const labelData of defaultLabels) {
await this.createLabel(labelData);
for (const label of defaultLabels) {
this.labels.set(label.id, label);
}
}