Add label functionality to tasks for better organization and tracking

Update TaskCard and TaskCreationModal components to support task labels, including UI elements for selection and display. Refactor schema imports to use '@shared/schema'.

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/vtpluZY
This commit is contained in:
paul-nothaft
2025-09-11 12:36:38 +00:00
parent 5f866afbb1
commit 4ea8a7c6a1
5 changed files with 55 additions and 9 deletions
+34 -2
View File
@@ -6,8 +6,9 @@ import { Textarea } from '@/components/ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Calendar } from '@/components/ui/calendar';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { CalendarIcon, Plus } from 'lucide-react';
import { Task } from './TaskCard';
import { CalendarIcon, Plus, Tag } from 'lucide-react';
import { Task, Label } from '@shared/schema';
import { useQuery } from '@tanstack/react-query';
interface TaskCreationModalProps {
isOpen: boolean;
@@ -20,8 +21,14 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat
const [description, setDescription] = useState('');
const [priority, setPriority] = useState<'low' | 'medium' | 'high'>('medium');
const [dueDate, setDueDate] = useState<Date | undefined>();
const [labelId, setLabelId] = useState<string | undefined>();
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
// Fetch labels
const { data: labels = [] } = useQuery<Label[]>({
queryKey: ['/api/labels'],
});
const handleSave = () => {
if (!title.trim()) return;
@@ -30,6 +37,7 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat
description: description.trim() || undefined,
priority,
dueDate,
labelId,
status: 'todo',
timeTracked: 0,
isTracking: false
@@ -43,6 +51,7 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat
setDescription('');
setPriority('medium');
setDueDate(undefined);
setLabelId(undefined);
onClose();
};
@@ -58,6 +67,7 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat
setDescription('');
setPriority('medium');
setDueDate(undefined);
setLabelId(undefined);
onClose();
};
@@ -109,6 +119,28 @@ export default function TaskCreationModal({ isOpen, onClose, onSave }: TaskCreat
</Select>
</div>
<div className="flex-1">
<Select value={labelId || 'none'} onValueChange={(value) => setLabelId(value === 'none' ? undefined : value)}>
<SelectTrigger data-testid="select-task-label">
<SelectValue placeholder="Label" />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">No Label</SelectItem>
{labels.map((label) => (
<SelectItem key={label.id} value={label.id}>
<div className="flex items-center gap-2">
<div
className="w-3 h-3 rounded"
style={{ backgroundColor: label.color }}
/>
{label.name}
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<Popover open={isCalendarOpen} onOpenChange={setIsCalendarOpen}>
<PopoverTrigger asChild>
<Button