import React, { useState } from 'react'; import { X, Flag, User, ArrowRight, CheckCircle, Circle, AlertCircle, Pause, Edit, Save, Copy, ChevronDown, ChevronRight, Clock } from 'lucide-react'; import { cn } from '../lib/utils'; import TaskIndicator from './TaskIndicator'; import { api } from '../utils/api'; import { useTaskMaster } from '../contexts/TaskMasterContext'; const TaskDetail = ({ task, onClose, onEdit, onStatusChange, onTaskClick, isOpen = true, className = '' }) => { const [editMode, setEditMode] = useState(false); const [editedTask, setEditedTask] = useState(task || {}); const [isSaving, setIsSaving] = useState(false); const [showDetails, setShowDetails] = useState(false); const [showTestStrategy, setShowTestStrategy] = useState(false); const { currentProject, refreshTasks } = useTaskMaster(); if (!isOpen || !task) return null; const handleSave = async () => { if (!currentProject) return; setIsSaving(true); try { // Only include changed fields const updates = {}; if (editedTask.title !== task.title) updates.title = editedTask.title; if (editedTask.description !== task.description) updates.description = editedTask.description; if (editedTask.details !== task.details) updates.details = editedTask.details; if (Object.keys(updates).length > 0) { const response = await api.taskmaster.updateTask(currentProject.name, task.id, updates); if (response.ok) { // Refresh tasks to get updated data refreshTasks?.(); onEdit?.(editedTask); setEditMode(false); } else { const error = await response.json(); console.error('Failed to update task:', error); alert(`Failed to update task: ${error.message}`); } } else { setEditMode(false); } } catch (error) { console.error('Error updating task:', error); alert('Error updating task. Please try again.'); } finally { setIsSaving(false); } }; const handleStatusChange = async (newStatus) => { if (!currentProject) return; try { const response = await api.taskmaster.updateTask(currentProject.name, task.id, { status: newStatus }); if (response.ok) { refreshTasks?.(); onStatusChange?.(task.id, newStatus); } else { const error = await response.json(); console.error('Failed to update task status:', error); alert(`Failed to update task status: ${error.message}`); } } catch (error) { console.error('Error updating task status:', error); alert('Error updating task status. Please try again.'); } }; const copyTaskId = () => { navigator.clipboard.writeText(task.id.toString()); }; const getStatusConfig = (status) => { switch (status) { case 'done': return { icon: CheckCircle, color: 'text-green-600 dark:text-green-400', bg: 'bg-green-50 dark:bg-green-950' }; case 'in-progress': return { icon: Clock, color: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-50 dark:bg-blue-950' }; case 'review': return { icon: AlertCircle, color: 'text-amber-600 dark:text-amber-400', bg: 'bg-amber-50 dark:bg-amber-950' }; case 'deferred': return { icon: Pause, color: 'text-gray-500 dark:text-gray-400', bg: 'bg-gray-50 dark:bg-gray-800' }; case 'cancelled': return { icon: X, color: 'text-red-600 dark:text-red-400', bg: 'bg-red-50 dark:bg-red-950' }; default: return { icon: Circle, color: 'text-slate-500 dark:text-slate-400', bg: 'bg-slate-50 dark:bg-slate-800' }; } }; const statusConfig = getStatusConfig(task.status); const StatusIcon = statusConfig.icon; const getPriorityColor = (priority) => { switch (priority) { case 'high': return 'text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950'; case 'medium': return 'text-yellow-600 dark:text-yellow-400 bg-yellow-50 dark:bg-yellow-950'; case 'low': return 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-950'; default: return 'text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800'; } }; const statusOptions = [ { value: 'pending', label: 'Pending' }, { value: 'in-progress', label: 'In Progress' }, { value: 'review', label: 'Review' }, { value: 'done', label: 'Done' }, { value: 'deferred', label: 'Deferred' }, { value: 'cancelled', label: 'Cancelled' } ]; return (
{/* Header */}
{task.parentId && ( Subtask of Task {task.parentId} )}
{editMode ? ( setEditedTask({ ...editedTask, title: e.target.value })} className="w-full text-lg font-semibold bg-transparent border-b-2 border-blue-500 focus:outline-none text-gray-900 dark:text-white" placeholder="Task title" /> ) : (

{task.title}

)}
{editMode ? ( <> ) : ( )}
{/* Content */}
{/* Status and Metadata Row */}
{/* Status */}
{statusOptions.find(option => option.value === task.status)?.label || task.status}
{/* Priority */}
{task.priority || 'Not set'}
{/* Dependencies */}
{task.dependencies && task.dependencies.length > 0 ? (
{task.dependencies.map(depId => ( ))}
) : ( No dependencies )}
{/* Description */}
{editMode ? (