# render_task_list > Render the task list UI using a Next.js component with Tailwind CSS styling. Use this skill whenever list_tasks is called to display tasks with dynamic rendering handled by Claude code. - Author: Zahida Raees - Repository: zahidaraees/hackathon-ii-phase-ii-Full-Stack-Web-Application - Version: 20260207224919 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-07 - Source: https://github.com/zahidaraees/hackathon-ii-phase-ii-Full-Stack-Web-Application - Web: https://mule.run/skillshub/@@zahidaraees/hackathon-ii-phase-ii-Full-Stack-Web-Application~render_task_list:20260207224919 --- --- name: render_task_list description: Render the task list UI using a Next.js component with Tailwind CSS styling. Use this skill whenever list_tasks is called to display tasks with dynamic rendering handled by Claude code. license: Complete terms in LICENSE.txt --- # Render Task List Skill This skill provides a user interface for displaying a list of tasks in an organized and visually appealing way. ## Purpose Render a task list UI that displays all tasks or filtered tasks based on user criteria. This skill handles the presentation layer of task visualization. ## When to Use Use this skill whenever the `list_tasks` function is called to provide a user interface for viewing tasks. This includes: - Displaying all tasks assigned to a user - Showing tasks filtered by status, priority, or date - Providing a dashboard view of upcoming tasks - Rendering tasks in a searchable and sortable format ## Implementation Overview The task list rendering is implemented using: - Next.js component for the user interface - Tailwind CSS for responsive styling - Claude code for dynamic rendering and filtering ## Detailed Implementation ### 1. Next.js Task List Component Create a task list component in your Next.js application: ```jsx // components/TaskList.jsx import { useState, useEffect } from 'react'; import TaskItem from './TaskItem'; const TaskList = ({ tasks = [], filters = {}, onTaskUpdate, onTaskDelete }) => { const [filteredTasks, setFilteredTasks] = useState(tasks); const [sortConfig, setSortConfig] = useState({ key: 'dueDate', direction: 'asc' }); const [searchTerm, setSearchTerm] = useState(''); // Apply filters and search term when they change useEffect(() => { let result = [...tasks]; // Apply search filter if (searchTerm) { const term = searchTerm.toLowerCase(); result = result.filter(task => task.title.toLowerCase().includes(term) || task.description.toLowerCase().includes(term) || task.tags.some(tag => tag.toLowerCase().includes(term)) ); } // Apply status filter if (filters.status && filters.status !== 'all') { result = result.filter(task => task.status === filters.status); } // Apply priority filter if (filters.priority && filters.priority !== 'all') { result = result.filter(task => task.priority === filters.priority); } // Apply date range filter if (filters.startDate) { const startDate = new Date(filters.startDate); result = result.filter(task => new Date(task.dueDate) >= startDate); } if (filters.endDate) { const endDate = new Date(filters.endDate); result = result.filter(task => new Date(task.dueDate) <= endDate); } setFilteredTasks(result); }, [tasks, filters, searchTerm]); // Handle sorting const requestSort = (key) => { let direction = 'asc'; if (sortConfig.key === key && sortConfig.direction === 'asc') { direction = 'desc'; } setSortConfig({ key, direction }); }; // Apply sorting to filtered tasks useEffect(() => { const sortedTasks = [...filteredTasks].sort((a, b) => { if (a[sortConfig.key] < b[sortConfig.key]) { return sortConfig.direction === 'asc' ? -1 : 1; } if (a[sortConfig.key] > b[sortConfig.key]) { return sortConfig.direction === 'asc' ? 1 : -1; } return 0; }); setFilteredTasks(sortedTasks); }, [sortConfig]); // Calculate task statistics const taskStats = { total: tasks.length, completed: tasks.filter(t => t.status === 'completed').length, inProgress: tasks.filter(t => t.status === 'in-progress').length, overdue: tasks.filter(t => { if (t.status === 'completed') return false; return new Date(t.dueDate) < new Date(); }).length }; return (
{/* Task Statistics */}

{taskStats.total}

Total Tasks

{taskStats.completed}

Completed

{taskStats.inProgress}

In Progress

{taskStats.overdue}

Overdue

{/* Search and Filters */}
setSearchTerm(e.target.value)} />
{/* Sort Controls */}
Sort by:
Showing {filteredTasks.length} of {tasks.length} tasks
{/* Task List */}
); }; export default TaskList; ``` ### 2. Task Item Component Create a reusable component for individual tasks: ```jsx // components/TaskItem.jsx import { useState } from 'react'; const TaskItem = ({ task, onTaskUpdate, onTaskDelete }) => { const [isEditing, setIsEditing] = useState(false); const [editData, setEditData] = useState({ ...task }); const handleSave = () => { onTaskUpdate(editData); setIsEditing(false); }; const handleCancel = () => { setEditData({ ...task }); setIsEditing(false); }; const handleInputChange = (field, value) => { setEditData(prev => ({ ...prev, [field]: value })); }; const getPriorityClass = (priority) => { switch (priority) { case 'urgent': return 'bg-red-100 text-red-800'; case 'high': return 'bg-orange-100 text-orange-800'; case 'medium': return 'bg-yellow-100 text-yellow-800'; case 'low': return 'bg-green-100 text-green-800'; default: return 'bg-gray-100 text-gray-800'; } }; const getStatusClass = (status) => { switch (status) { case 'completed': return 'bg-green-100 text-green-800'; case 'in-progress': return 'bg-blue-100 text-blue-800'; case 'pending': return 'bg-yellow-100 text-yellow-800'; default: return 'bg-gray-100 text-gray-800'; } }; const isOverdue = task.status !== 'completed' && new Date(task.dueDate) < new Date(); return (
  • {!isEditing ? ( <> { onTaskUpdate({ ...task, status: e.target.checked ? 'completed' : 'pending' }); }} className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />

    {task.title}

    {task.description}

    {task.priority.charAt(0).toUpperCase() + task.priority.slice(1)} {task.status.replace('-', ' ').charAt(0).toUpperCase() + task.status.slice(1).replace('-', ' ')} {isOverdue && ( Overdue )} {task.tags.map((tag, index) => ( {tag} ))}
    ) : (
    handleInputChange('title', e.target.value)} className="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" />
    handleInputChange('dueDate', e.target.value)} className="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" />
    )}
    {isEditing ? ( <> ) : ( <> )}
    Assigned to: {task.assignee || 'Unassigned'} • Due: {new Date(task.dueDate).toLocaleDateString()}
  • ); }; export default TaskItem; ``` ### 3. Tailwind CSS Styling The components use Tailwind CSS for responsive styling. Make sure your `tailwind.config.js` is properly configured: ```javascript // tailwind.config.js module.exports = { content: [ "./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } ``` And that Tailwind CSS is properly imported in your global CSS file: ```css /* styles/globals.css */ @tailwind base; @tailwind components; @tailwind utilities; ``` ### 4. Claude Code Dynamic Rendering The task list includes dynamic rendering capabilities that can be enhanced by Claude code. Here's an example of how Claude might orchestrate dynamic updates: ```javascript // utils/taskRendering.js export const enhanceTaskList = (tasks, userPreferences) => { // Apply user preferences to the task list let enhancedTasks = [...tasks]; // Highlight urgent tasks enhancedTasks = enhancedTasks.map(task => ({ ...task, isHighlighted: task.priority === 'urgent' || (task.priority === 'high' && isWithinDays(task.dueDate, 1)) || (task.status !== 'completed' && isOverdue(task.dueDate)) })); // Sort based on user preferences if (userPreferences.sortBy) { enhancedTasks.sort((a, b) => { if (a[userPreferences.sortBy] < b[userPreferences.sortBy]) { return userPreferences.sortDirection === 'asc' ? -1 : 1; } if (a[userPreferences.sortBy] > b[userPreferences.sortBy]) { return userPreferences.sortDirection === 'asc' ? 1 : -1; } return 0; }); } // Group tasks by date if requested if (userPreferences.groupByDate) { return groupTasksByDate(enhancedTasks); } return enhancedTasks; }; const isWithinDays = (dateStr, days) => { const date = new Date(dateStr); const now = new Date(); const diffTime = Math.abs(date - now); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); return diffDays <= days; }; const isOverdue = (dateStr) => { const date = new Date(dateStr); const now = new Date(); return date < now; }; const groupTasksByDate = (tasks) => { const groups = {}; tasks.forEach(task => { const date = new Date(task.dueDate).toDateString(); if (!groups[date]) { groups[date] = []; } groups[date].push(task); }); // Sort groups by date const sortedGroups = {}; Object.keys(groups) .sort((a, b) => new Date(a) - new Date(b)) .forEach(key => { sortedGroups[key] = groups[key]; }); return sortedGroups; }; // Function to dynamically update the UI based on real-time data export const setupRealtimeUpdates = (taskId, onUpdate) => { // Example WebSocket connection for real-time updates const ws = new WebSocket(process.env.NEXT_PUBLIC_WS_URL); ws.onopen = () => { console.log('Connected to task updates'); ws.send(JSON.stringify({ type: 'subscribe', taskId })); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'task_update' && data.taskId === taskId) { onUpdate(data.task); } }; return ws; }; ``` ### 5. Using the Task List Component Here's how to use the TaskList component in a Next.js page: ```jsx // pages/tasks/index.jsx import { useState, useEffect } from 'react'; import TaskList from '../../components/TaskList'; import { enhanceTaskList } from '../../utils/taskRendering'; const TaskListPage = () => { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(true); const [filters, setFilters] = useState({ status: 'all', priority: 'all', startDate: '', endDate: '' }); // Load tasks from API useEffect(() => { const fetchTasks = async () => { try { setLoading(true); const response = await fetch('/api/tasks'); const data = await response.json(); setTasks(data); } catch (error) { console.error('Error fetching tasks:', error); } finally { setLoading(false); } }; fetchTasks(); }, []); // Handle task updates const handleTaskUpdate = async (updatedTask) => { try { const response = await fetch(`/api/tasks/${updatedTask.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(updatedTask), }); if (response.ok) { const updatedTasks = tasks.map(task => task.id === updatedTask.id ? updatedTask : task ); setTasks(updatedTasks); } } catch (error) { console.error('Error updating task:', error); } }; // Handle task deletion const handleTaskDelete = async (taskId) => { try { const response = await fetch(`/api/tasks/${taskId}`, { method: 'DELETE', }); if (response.ok) { setTasks(tasks.filter(task => task.id !== taskId)); } } catch (error) { console.error('Error deleting task:', error); } }; // Handle filter changes const handleStatusFilterChange = (status) => { setFilters(prev => ({ ...prev, status })); }; const handlePriorityFilterChange = (priority) => { setFilters(prev => ({ ...prev, priority })); }; // Enhance tasks with Claude-driven logic const enhancedTasks = enhanceTaskList(tasks, { sortBy: 'dueDate', sortDirection: 'asc', groupByDate: false }); if (loading) { return (
    ); } return (

    Task List

    ); }; export default TaskListPage; ``` ## Additional Features The task list includes several UX enhancements: - Filtering by status, priority, and date range - Sorting by different attributes - Search functionality - Visual indicators for task priority and status - Responsive design for different screen sizes - Task statistics dashboard - Inline editing capabilities - Loading states and empty state handling ## Security Considerations - Sanitize user inputs before rendering - Implement proper authentication and authorization checks - Validate data on the server side as well - Protect against XSS attacks by properly escaping content - Implement rate limiting for API requests