# task-management-ui > Build complete task management interfaces with proper forms, modals, filters, and list views. - Author: Muhammad Sultan - Repository: sutanSultan/Heckathon-2 - Version: 20260208201009 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-08 - Source: https://github.com/sutanSultan/Heckathon-2 - Web: https://mule.run/skillshub/@@sutanSultan/Heckathon-2~task-management-ui:20260208201009 --- # Task Management UI Skill Build complete task management interfaces with proper forms, modals, filters, and list views. ## Core Components ### Task List Page ```typescript // app/tasks/page.tsx 'use client'; import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Plus, Filter } from 'lucide-react'; import TaskCard from '@/components/tasks/task-card'; import TaskFormModal from '@/components/tasks/task-form-modal'; import TaskFilters from '@/components/tasks/task-filters'; import { getTasks } from '@/lib/api/tasks'; export default function TasksPage() { const [tasks, setTasks] = useState([]); const [isModalOpen, setIsModalOpen] = useState(false); const [filters, setFilters] = useState({ status: 'all', priority: 'all', tag: '' }); useEffect(() => { loadTasks(); }, [filters]); const loadTasks = async () => { const data = await getTasks(filters); setTasks(data); }; const filteredTasks = tasks.filter(task => { if (filters.status !== 'all' && task.status !== filters.status) return false; if (filters.priority !== 'all' && task.priority !== filters.priority) return false; if (filters.tag && !task.tags?.includes(filters.tag)) return false; return true; }); return (
{/* Header */}

Tasks

{filteredTasks.length} task{filteredTasks.length !== 1 ? 's' : ''}

setIsModalOpen(true)} className="flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg font-medium hover:bg-primary/90 transition-colors" > New Task
{/* Task List */} {filteredTasks.length === 0 ? (

No tasks found

Try changing your filters or create a new task

) : (
{filteredTasks.map((task, index) => ( ))}
)}
{/* Create Task Modal */} setIsModalOpen(false)} onSuccess={loadTasks} />
); } ``` ### Task Card Component ```typescript // components/tasks/task-card.tsx 'use client'; import { motion } from 'framer-motion'; import { Calendar, Tag, MoreVertical, Check } from 'lucide-react'; import { format } from 'date-fns'; interface TaskCardProps { task: any; index: number; onUpdate: () => void; } const priorityColors = { low: 'bg-blue-500/10 text-blue-500 border-blue-500/20', medium: 'bg-yellow-500/10 text-yellow-500 border-yellow-500/20', high: 'bg-red-500/10 text-red-500 border-red-500/20', }; const statusColors = { pending: 'bg-gray-500/10 text-gray-500', active: 'bg-blue-500/10 text-blue-500', completed: 'bg-green-500/10 text-green-500', }; export default function TaskCard({ task, index, onUpdate }: TaskCardProps) { const handleToggleComplete = async () => { // Toggle task completion await fetch(`/api/tasks/${task.id}`, { method: 'PATCH', body: JSON.stringify({ status: task.status === 'completed' ? 'active' : 'completed' }) }); onUpdate(); }; return ( {/* Header */}

{task.title}

{task.description && (

{task.description}

)}
{/* Tags */} {task.tags && task.tags.length > 0 && (
{task.tags.map((tag: string) => ( {tag} ))}
)} {/* Footer */}
{task.dueDate && format(new Date(task.dueDate), 'MMM dd')}
{task.status} {task.priority}
); } ``` ### Task Form Modal (Proper Width/Height) ```typescript // components/tasks/task-form-modal.tsx 'use client'; import { motion, AnimatePresence } from 'framer-motion'; import { X } from 'lucide-react'; import { useState } from 'react'; interface TaskFormModalProps { isOpen: boolean; onClose: () => void; onSuccess: () => void; task?: any; } export default function TaskFormModal({ isOpen, onClose, onSuccess, task }: TaskFormModalProps) { const [formData, setFormData] = useState({ title: task?.title || '', description: task?.description || '', priority: task?.priority || 'medium', status: task?.status || 'pending', dueDate: task?.dueDate || '', tags: task?.tags?.join(', ') || '' }); const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); try { const payload = { ...formData, tags: formData.tags.split(',').map(t => t.trim()).filter(Boolean) }; const url = task ? `/api/tasks/${task.id}` : '/api/tasks'; const method = task ? 'PATCH' : 'POST'; const response = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) { onSuccess(); onClose(); } } catch (error) { console.error('Error saving task:', error); } finally { setIsSubmitting(false); } }; return ( {isOpen && (
{/* Backdrop */} {/* Modal - PROPER WIDTH/HEIGHT */} {/* Header */}

{task ? 'Edit Task' : 'Create New Task'}

{/* Form - Scrollable */}
{/* Title */}
setFormData({ ...formData, title: e.target.value })} className="w-full px-4 py-2.5 bg-background border rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all" placeholder="Enter task title" />
{/* Description */}