1→import { useEffect, useState } from 'react'
     2→import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2 } from 'lucide-react'
     3→import * as Dialog from '@radix-ui/react-dialog'
     4→import * as AlertDialog from '@radix-ui/react-alert-dialog'
     5→import { useProjectStore } from '../stores/projectStore'
     6→import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'
     7→
     8→const COLUMNS = [
     9→  { id: 'backlog', title: 'Backlog', color: 'border-slate-500' },
    10→  { id: 'in_progress', title: 'In Progress', color: 'border-accent' },
    11→  { id: 'qa', title: 'QA', color: 'border-primary-400' },
    12→  { id: 'done', title: 'Done', color: 'border-green-400' },
    13→  { id: 'blocked', title: 'Blocked', color: 'border-destructive' },
    14→]
    15→
    16→const PRIORITY_LABELS: Record<number, string> = {
    17→  0: 'Low',
    18→  1: 'Medium',
    19→  2: 'High',
    20→  3: 'Critical',
    21→}
    22→
    23→const STATUS_LABELS: Record<string, string> = {
    24→  backlog: 'Backlog',
    25→  in_progress: 'In Progress',
    26→  qa: 'QA',
    27→  done: 'Done',
    28→  blocked: 'Blocked',
    29→}
    30→
    31→export default function KanbanBoard() {
    32→  const { currentProject } = useProjectStore()
    33→  const { tasks, fetchTasks, createTask, updateTask, updateTaskStatus, deleteTask, isLoading } = useTaskStore()
    34→  const [showAddDialog, setShowAddDialog] = useState(false)
    35→  const [newTaskName, setNewTaskName] = useState('')
    36→  const [newTaskDescription, setNewTaskDescription] = useState('')
    37→  const [newTaskPriority, setNewTaskPriority] = useState(0)
    38→  const [isCreating, setIsCreating] = useState(false)
    39→  const [draggedTask, setDraggedTask] = useState<number | null>(null)
    40→  const [selectedTask, setSelectedTask] = useState<Task | null>(null)
    41→  const [isEditing, setIsEditing] = useState(false)
    42→  const [editName, setEditName] = useState('')
    43→  const [editDescription, setEditDescription] = useState('')
    44→  const [editPriority, setEditPriority] = useState(0)
    45→  const [isSaving, setIsSaving] = useState(false)
    46→  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
    47→  const [isDeleting, setIsDeleting] = useState(false)
    48→
    49→  useEffect(() => {
    50→    if (currentProject?.id) {
    51→      fetchTasks(currentProject.id)
    52→    }
    53→  }, [currentProject?.id, fetchTasks])
    54→
    55→  const getTasksByStatus = (status: string) => {
    56→    return tasks.filter((task) => task.status === status)
    57→  }
    58→
    59→  const handleCreateTask = async () => {
    60→    if (!currentProject || !newTaskName.trim()) return
    61→    setIsCreating(true)
    62→    try {
    63→      const taskData: TaskCreate = {
    64→        name: newTaskName.trim(),
    65→        description: newTaskDescription.trim() || undefined,
    66→        priority: newTaskPriority,
    67→      }
    68→      await createTask(currentProject.id, taskData)
    69→      setNewTaskName('')
    70→      setNewTaskDescription('')
    71→      setNewTaskPriority(0)
    72→      setShowAddDialog(false)
    73→    } catch (error) {
    74→      console.error('Failed to create task:', error)
    75→    } finally {
    76→      setIsCreating(false)
    77→    }
    78→  }
    79→
    80→  const handleDragStart = (taskId: number) => {
    81→    setDraggedTask(taskId)
    82→  }
    83→
    84→  const handleDragOver = (e: React.DragEvent) => {
    85→    e.preventDefault()
    86→  }
    87→
    88→  const handleDrop = async (targetStatus: string) => {
    89→    if (draggedTask === null) return
    90→    try {
    91→      await updateTaskStatus(draggedTask, targetStatus)
    92→    } catch (error) {
    93→      console.error('Failed to update task status:', error)
    94→    }
    95→    setDraggedTask(null)
    96→  }
    97→
    98→  const handleStartEdit = () => {
    99→    if (!selectedTask) return
   100→    setEditName(selectedTask.name)
   101→    setEditDescription(selectedTask.description || '')
   102→    setEditPriority(selectedTask.priority)
   103→    setIsEditing(true)
   104→  }
   105→
   106→  const handleCancelEdit = () => {
   107→    setIsEditing(false)
   108→  }
   109→
   110→  const handleSaveEdit = async () => {
   111→    if (!selectedTask) return
   112→    setIsSaving(true)
   113→    try {
   114→      const updates: TaskUpdate = {
   115→        name: editName.trim(),
   116→        description: editDescription.trim() || undefined,
   117→        priority: editPriority,
   118→      }
   119→      const updatedTask = await updateTask(selectedTask.id, updates)
   120→      setSelectedTask(updatedTask)
   121→      setIsEditing(false)
   122→    } catch (error) {
   123→      console.error('Failed to update task:', error)
   124→    } finally {
   125→      setIsSaving(false)
   126→    }
   127→  }
   128→
   129→  const handleDeleteTask = async () => {
   130→    if (!selectedTask) return
   131→    setIsDeleting(true)
   132→    try {
   133→      await deleteTask(selectedTask.id)
   134→      setSelectedTask(null)
   135→      setShowDeleteDialog(false)
   136→    } catch (error) {
   137→      console.error('Failed to delete task:', error)
   138→    } finally {
   139→      setIsDeleting(false)
   140→    }
   141→  }
   142→
   143→  if (!currentProject) {
   144→    return (
   145→

   146→
Select a project to view its Kanban board

   147→

   148→    )
   149→  }
   150→
   151→  return (
   152→

   153→      {/* Header */}
   154→

   155→
Kanban Board

   156→        <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
   157→          <Dialog.Trigger asChild>
   158→            <button className="btn-accent flex items-center gap-2">
   159→              <Plus size={18} />
   160→              Add Task
   161→            </button>
   162→          </Dialog.Trigger>
   163→          <Dialog.Portal>
   164→            <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
   165→            <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">
   166→

   167→                <Dialog.Title className="text-xl font-semibold text-white">
   168→                  Add New Task
   169→                </Dialog.Title>
   170→                <Dialog.Close asChild>
   171→                  <button className="text-slate-400 hover:text-white">
   172→                    <X size={20} />
   173→                  </button>
   174→                </Dialog.Close>
   175→

   176→              <Dialog.Description className="text-slate-400 mb-4">
   177→                Create a new task for this project.
   178→              </Dialog.Description>
   179→

   180→

   181→
   182→                    Task Name *
   183→
   184→                  <input
   185→                    type="text"
   186→                    value={newTaskName}
   187→                    onChange={(e) => setNewTaskName(e.target.value)}
   188→                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
   189→                    placeholder="Enter task name"
   190→                  />
   191→

   192→

   193→
   194→                    Description
   195→
   196→                  <textarea
   197→                    value={newTaskDescription}
   198→                    onChange={(e) => setNewTaskDescription(e.target.value)}
   199→                    rows={3}
   200→                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
   201→                    placeholder="Enter task description"
   202→                  />
   203→

   204→

   205→
   206→                    Priority
   207→
   208→                  <select
   209→                    value={newTaskPriority}
   210→                    onChange={(e) => setNewTaskPriority(Number(e.target.value))}
   211→                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
   212→                  >
   213→                    <option value={0}>Low</option>
   214→                    <option value={1}>Medium</option>
   215→                    <option value={2}>High</option>
   216→                    <option value={3}>Critical</option>
   217→                  </select>
   218→

   219→

   220→

   221→                <Dialog.Close asChild>
   222→                  <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
   223→                    Cancel
   224→                  </button>
   225→                </Dialog.Close>
   226→                <button
   227→                  onClick={handleCreateTask}
   228→                  disabled={isCreating || !newTaskName.trim()}
   229→                  className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
   230→                >
   231→                  {isCreating ? 'Creating...' : 'Create Task'}
   232→                </button>
   233→

   234→            </Dialog.Content>
   235→          </Dialog.Portal>
   236→        </Dialog.Root>
   237→

   238→
   239→      {/* Main Content Area */}
   240→

   241→        {/* Kanban Columns */}
   242→        <div className={`flex-1 flex gap-4 overflow-x-auto pb-4 ${selectedTask ? 'mr-0' : ''}`}>
   243→          {COLUMNS.map((column) => (
   244→          <div
   245→            key={column.id}
   246→            className={`flex-shrink-0 w-72 bg-slate-800 rounded-lg border-t-2 ${column.color}`}
   247→            onDragOver={handleDragOver}
   248→            onDrop={() => handleDrop(column.id)}
   249→          >
   250→            {/* Column Header */}
   251→

   252→

   253→
{column.title}

   254→
   255→                  {getTasksByStatus(column.id).length}
   256→
   257→

   258→

   259→
   260→            {/* Column Content */}
   261→

   262→              {isLoading && tasks.length === 0 ? (
   263→

   264→                  Loading...
   265→

   266→              ) : getTasksByStatus(column.id).length === 0 ? (
   267→

   268→                  No tasks
   269→

   270→              ) : (
   271→                getTasksByStatus(column.id).map((task) => (
   272→
 handleDragStart(task.id)}
   276→                    onClick={() => setSelectedTask(task)}
   277→                    className={`kanban-card bg-slate-900 rounded-lg p-4 border border-slate-700 cursor-pointer hover:border-slate-600 ${
   278→                      draggedTask === task.id ? 'opacity-50' : ''
   279→                    } ${selectedTask?.id === task.id ? 'ring-2 ring-accent' : ''}`}
   280→                  >
   281→

   282→                      <GripVertical size={16} className="text-slate-600 mt-0.5 flex-shrink-0" />
   283→

   284→
{task.name}

   285→                        {task.description && (
   286→

   287→                            {task.description}
   288→

   289→                        )}
   290→

   291→                          <span
   292→                            className={`badge ${
   293→                              column.id === 'backlog'
   294→                                ? 'badge-backlog'
   295→                                : column.id === 'in_progress'
   296→                                ? 'badge-in-progress'
   297→                                : column.id === 'qa'
   298→                                ? 'badge-qa'
   299→                                : column.id === 'done'
   300→                                ? 'badge-done'
   301→                                : 'badge-blocked'
   302→                            }`}
   303→                          >
   304→                            {column.title}
   305→
   306→
   312→                            {task.priority === 3 ? 'Critical' :
   313→                             task.priority === 2 ? 'High' :
   314→                             task.priority === 1 ? 'Medium' : 'Low'}
   315→
   316→

   317→

   318→

   319→

   320→                ))
   321→              )}
   322→

   323→

   324→          ))}
   325→

   326→
   327→        {/* Task Details Panel */}
   328→        {selectedTask && (
   329→

   330→

   331→
Task Details

   332→

   333→                {!isEditing && (
   334→                  <>
   335→                    <button
   336→                      onClick={handleStartEdit}
   337→                      className="text-slate-400 hover:text-accent transition-colors"
   338→                      title="Edit Task"
   339→                    >
   340→                      <Pencil size={18} />
   341→                    </button>
   342→                    <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
   343→                      <AlertDialog.Trigger asChild>
   344→                        <button
   345→                          className="text-slate-400 hover:text-destructive transition-colors"
   346→                          title="Delete Task"
   347→                        >
   348→                          <Trash2 size={18} />
   349→                        </button>
   350→                      </AlertDialog.Trigger>
   351→                      <AlertDialog.Portal>
   352→                        <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
   353→                        <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">
   354→                          <AlertDialog.Title className="text-xl font-semibold text-white">
   355→                            Delete Task
   356→                          </AlertDialog.Title>
   357→                          <AlertDialog.Description className="mt-3 text-slate-400">
   358→                            Are you sure you want to delete {selectedTask.name}?
   359→                            This action cannot be undone.
   360→                          </AlertDialog.Description>
   361→

   362→                            <AlertDialog.Cancel asChild>
   363→                              <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
   364→                                Cancel
   365→                              </button>
   366→                            </AlertDialog.Cancel>
   367→                            <AlertDialog.Action asChild>
   368→                              <button
   369→                                onClick={handleDeleteTask}
   370→                                disabled={isDeleting}
   371→                                className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
   372→                              >
   373→                                {isDeleting ? 'Deleting...' : 'Delete Task'}
   374→                              </button>
   375→                            </AlertDialog.Action>
   376→

   377→                        </AlertDialog.Content>
   378→                      </AlertDialog.Portal>
   379→                    </AlertDialog.Root>
   380→                  </>
   381→                )}
   382→                <button
   383→                  onClick={() => {
   384→                    setSelectedTask(null)
   385→                    setIsEditing(false)
   386→                  }}
   387→                  className="text-slate-400 hover:text-white transition-colors"
   388→                >
   389→                  <X size={20} />
   390→                </button>
   391→

   392→

   393→

   394→              {isEditing ? (
   395→                /* Edit Form */
   396→

   397→

   398→                    Name *
   399→                    <input
   400→                      type="text"
   401→                      value={editName}
   402→                      onChange={(e) => setEditName(e.target.value)}
   403→                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
   404→                      placeholder="Task name"
   405→                    />
   406→

   407→

   408→                    Description
   409→                    <textarea
   410→                      value={editDescription}
   411→                      onChange={(e) => setEditDescription(e.target.value)}
   412→                      rows={3}
   413→                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
   414→                      placeholder="Task description"
   415→                    />
   416→

   417→

   418→                    Priority
   419→                    <select
   420→                      value={editPriority}
   421→                      onChange={(e) => setEditPriority(Number(e.target.value))}
   422→                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
   423→                    >
   424→                      <option value={0}>Low</option>
   425→                      <option value={1}>Medium</option>
   426→                      <option value={2}>High</option>
   427→                      <option value={3}>Critical</option>
   428→                    </select>
   429→

   430→

   431→                    <button
   432→                      onClick={handleCancelEdit}
   433→                      className="flex-1 px-3 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors"
   434→                    >
   435→                      Cancel
   436→                    </button>
   437→                    <button
   438→                      onClick={handleSaveEdit}
   439→                      disabled={isSaving || !editName.trim()}
   440→                      className="flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
   441→                    >
   442→                      {isSaving ? 'Saving...' : <><Check size={16} /> Save</>}
   443→                    </button>
   444→

   445→

   446→              ) : (
   447→                /* View Mode */
   448→                <>
   449→                  {/* Task Name */}
   450→

   451→                    Name
   452→
{selectedTask.name}

   453→

   454→
   455→                  {/* Description */}
   456→

   457→                    Description
   458→

   459→                      {selectedTask.description || No description}
   460→

   461→

   462→
   463→                  {/* Status */}
   464→

   465→                    Status
   466→
   473→                      {STATUS_LABELS[selectedTask.status] || selectedTask.status}
   474→
   475→

   476→
   477→                  {/* Priority */}
   478→

   479→                    Priority
   480→
   486→                      {PRIORITY_LABELS[selectedTask.priority] || 'Unknown'}
   487→
   488→

   489→
   490→                  {/* Agent Assignment */}
   491→

   492→
   493→                      <User size={14} />
   494→                      Agent Assignment
   495→
   496→

   497→                      {selectedTask.agent_type ? (
   498→                        {selectedTask.agent_type.replace('_', ' ')}
   499→                      ) : (
   500→                        Not assigned
   501→                      )}
   502→

   503→

   504→
   505→                  {/* Iteration Count */}
   506→

   507→
   508→                      <RefreshCw size={14} />
   509→                      Iteration Count
   510→
   511→
{selectedTask.iteration_count}

   512→

   513→
   514→                  {/* Flagged for Review */}
   515→

   516→
   517→                      <Flag size={14} />
   518→                      Flagged for Review
   519→
   520→

   521→                      {selectedTask.flagged_for_review ? 'Yes' : 'No'}
   522→

   523→

   524→
   525→                  {/* Time Estimates */}
   526→                  {(selectedTask.estimated_time || selectedTask.actual_time) && (
   527→

   528→
   529→                        <Clock size={14} />
   530→                        Time
   531→
   532→

   533→                        {selectedTask.estimated_time &&
Estimated: {selectedTask.estimated_time} min
}
   534→                        {selectedTask.actual_time &&
Actual: {selectedTask.actual_time} min
}
   535→

   536→

   537→                  )}
   538→
   539→                  {/* Created/Updated timestamps */}
   540→

   541→
Created: {new Date(selectedTask.created_at).toLocaleString()}

   542→
Updated: {new Date(selectedTask.updated_at).toLocaleString()}

   543→

   544→                </>
   545→              )}
   546→

   547→

   548→        )}
   549→

   550→

   551→  )
   552→}
   553→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

import { useEffect, useState } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2 } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'

const COLUMNS = [
  { id: 'backlog', title: 'Backlog', color: 'border-slate-500' },
  { id: 'in_progress', title: 'In Progress', color: 'border-accent' },
  { id: 'qa', title: 'QA', color: 'border-primary-400' },
  { id: 'done', title: 'Done', color: 'border-green-400' },
  { id: 'blocked', title: 'Blocked', color: 'border-destructive' },
]

const PRIORITY_LABELS: Record<number, string> = {
  0: 'Low',
  1: 'Medium',
  2: 'High',
  3: 'Critical',
}

const STATUS_LABELS: Record<string, string> = {
  backlog: 'Backlog',
  in_progress: 'In Progress',
  qa: 'QA',
  done: 'Done',
  blocked: 'Blocked',
}

export default function KanbanBoard() {
  const { currentProject } = useProjectStore()
  const { tasks, fetchTasks, createTask, updateTask, updateTaskStatus, deleteTask, isLoading } = useTaskStore()
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newTaskName, setNewTaskName] = useState('')
  const [newTaskDescription, setNewTaskDescription] = useState('')
  const [newTaskPriority, setNewTaskPriority] = useState(0)
  const [isCreating, setIsCreating] = useState(false)
  const [draggedTask, setDraggedTask] = useState<number | null>(null)
  const [selectedTask, setSelectedTask] = useState<Task | null>(null)
  const [isEditing, setIsEditing] = useState(false)
  const [editName, setEditName] = useState('')
  const [editDescription, setEditDescription] = useState('')
  const [editPriority, setEditPriority] = useState(0)
  const [isSaving, setIsSaving] = useState(false)
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  useEffect(() => {
    if (currentProject?.id) {
      fetchTasks(currentProject.id)
    }
  }, [currentProject?.id, fetchTasks])

  const getTasksByStatus = (status: string) => {
    return tasks.filter((task) => task.status === status)
  }

  const handleCreateTask = async () => {
    if (!currentProject || !newTaskName.trim()) return
    setIsCreating(true)
    try {
      const taskData: TaskCreate = {
        name: newTaskName.trim(),
        description: newTaskDescription.trim() || undefined,
        priority: newTaskPriority,
      }
      await createTask(currentProject.id, taskData)
      setNewTaskName('')
      setNewTaskDescription('')
      setNewTaskPriority(0)
      setShowAddDialog(false)
    } catch (error) {
      console.error('Failed to create task:', error)
    } finally {
      setIsCreating(false)
    }
  }

  const handleDragStart = (taskId: number) => {
    setDraggedTask(taskId)
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
  }

  const handleDrop = async (targetStatus: string) => {
    if (draggedTask === null) return
    try {
      await updateTaskStatus(draggedTask, targetStatus)
    } catch (error) {
      console.error('Failed to update task status:', error)
    }
    setDraggedTask(null)
  }

  const handleStartEdit = () => {
    if (!selectedTask) return
    setEditName(selectedTask.name)
    setEditDescription(selectedTask.description || '')
    setEditPriority(selectedTask.priority)
    setIsEditing(true)
  }

  const handleCancelEdit = () => {
    setIsEditing(false)
  }

  const handleSaveEdit = async () => {
    if (!selectedTask) return
    setIsSaving(true)
    try {
      const updates: TaskUpdate = {
        name: editName.trim(),
        description: editDescription.trim() || undefined,
        priority: editPriority,
      }
      const updatedTask = await updateTask(selectedTask.id, updates)
      setSelectedTask(updatedTask)
      setIsEditing(false)
    } catch (error) {
      console.error('Failed to update task:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDeleteTask = async () => {
    if (!selectedTask) return
    setIsDeleting(true)
    try {
      await deleteTask(selectedTask.id)
      setSelectedTask(null)
      setShowDeleteDialog(false)
    } catch (error) {
      console.error('Failed to delete task:', error)
    } finally {
      setIsDeleting(false)
    }
  }

  if (!currentProject) {
    return (

Select a project to view its Kanban board

    )
  }

  return (

      {/* Header */}

Kanban Board

        <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
          <Dialog.Trigger asChild>
            <button className="btn-accent flex items-center gap-2">
              <Plus size={18} />
              Add Task
            </button>
          </Dialog.Trigger>
          <Dialog.Portal>
            <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
            <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">

                <Dialog.Title className="text-xl font-semibold text-white">
                  Add New Task
                </Dialog.Title>
                <Dialog.Close asChild>
                  <button className="text-slate-400 hover:text-white">
                    <X size={20} />
                  </button>
                </Dialog.Close>

              <Dialog.Description className="text-slate-400 mb-4">
                Create a new task for this project.
              </Dialog.Description>

                    Task Name *

                  <input
                    type="text"
                    value={newTaskName}
                    onChange={(e) => setNewTaskName(e.target.value)}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    placeholder="Enter task name"
                  />

                    Description

                  <textarea
                    value={newTaskDescription}
                    onChange={(e) => setNewTaskDescription(e.target.value)}
                    rows={3}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                    placeholder="Enter task description"
                  />

                    Priority

                  <select
                    value={newTaskPriority}
                    onChange={(e) => setNewTaskPriority(Number(e.target.value))}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                  >
                    <option value={0}>Low</option>
                    <option value={1}>Medium</option>
                    <option value={2}>High</option>
                    <option value={3}>Critical</option>
                  </select>

                <Dialog.Close asChild>
                  <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                    Cancel
                  </button>
                </Dialog.Close>
                <button
                  onClick={handleCreateTask}
                  disabled={isCreating || !newTaskName.trim()}
                  className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                >
                  {isCreating ? 'Creating...' : 'Create Task'}
                </button>

            </Dialog.Content>
          </Dialog.Portal>
        </Dialog.Root>

      {/* Main Content Area */}

        {/* Kanban Columns */}
        <div className={`flex-1 flex gap-4 overflow-x-auto pb-4 ${selectedTask ? 'mr-0' : ''}`}>
          {COLUMNS.map((column) => (
          <div
            key={column.id}
            className={`flex-shrink-0 w-72 bg-slate-800 rounded-lg border-t-2 ${column.color}`}
            onDragOver={handleDragOver}
            onDrop={() => handleDrop(column.id)}
          >
            {/* Column Header */}

{column.title}

                  {getTasksByStatus(column.id).length}

            {/* Column Content */}

              {isLoading && tasks.length === 0 ? (

                  Loading...

              ) : getTasksByStatus(column.id).length === 0 ? (

                  No tasks

              ) : (
                getTasksByStatus(column.id).map((task) => (

 handleDragStart(task.id)}
                    onClick={() => setSelectedTask(task)}
                    className={`kanban-card bg-slate-900 rounded-lg p-4 border border-slate-700 cursor-pointer hover:border-slate-600 ${
                      draggedTask === task.id ? 'opacity-50' : ''
                    } ${selectedTask?.id === task.id ? 'ring-2 ring-accent' : ''}`}
                  >

                      <GripVertical size={16} className="text-slate-600 mt-0.5 flex-shrink-0" />

{task.name}

                        {task.description && (

                            {task.description}

                        )}

                          <span
                            className={`badge ${
                              column.id === 'backlog'
                                ? 'badge-backlog'
                                : column.id === 'in_progress'
                                ? 'badge-in-progress'
                                : column.id === 'qa'
                                ? 'badge-qa'
                                : column.id === 'done'
                                ? 'badge-done'
                                : 'badge-blocked'
                            }`}
                          >
                            {column.title}

                            {task.priority === 3 ? 'Critical' :
                             task.priority === 2 ? 'High' :
                             task.priority === 1 ? 'Medium' : 'Low'}

                ))
              )}

          ))}

        {/* Task Details Panel */}
        {selectedTask && (

Task Details

                {!isEditing && (
                  <>
                    <button
                      onClick={handleStartEdit}
                      className="text-slate-400 hover:text-accent transition-colors"
                      title="Edit Task"
                    >
                      <Pencil size={18} />
                    </button>
                    <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
                      <AlertDialog.Trigger asChild>
                        <button
                          className="text-slate-400 hover:text-destructive transition-colors"
                          title="Delete Task"
                        >
                          <Trash2 size={18} />
                        </button>
                      </AlertDialog.Trigger>
                      <AlertDialog.Portal>
                        <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
                        <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">
                          <AlertDialog.Title className="text-xl font-semibold text-white">
                            Delete Task
                          </AlertDialog.Title>
                          <AlertDialog.Description className="mt-3 text-slate-400">
                            Are you sure you want to delete {selectedTask.name}?
                            This action cannot be undone.
                          </AlertDialog.Description>

                            <AlertDialog.Cancel asChild>
                              <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                                Cancel
                              </button>
                            </AlertDialog.Cancel>
                            <AlertDialog.Action asChild>
                              <button
                                onClick={handleDeleteTask}
                                disabled={isDeleting}
                                className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
                              >
                                {isDeleting ? 'Deleting...' : 'Delete Task'}
                              </button>
                            </AlertDialog.Action>

                        </AlertDialog.Content>
                      </AlertDialog.Portal>
                    </AlertDialog.Root>
                  </>
                )}
                <button
                  onClick={() => {
                    setSelectedTask(null)
                    setIsEditing(false)
                  }}
                  className="text-slate-400 hover:text-white transition-colors"
                >
                  <X size={20} />
                </button>

              {isEditing ? (
                /* Edit Form */

                    Name *
                    <input
                      type="text"
                      value={editName}
                      onChange={(e) => setEditName(e.target.value)}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                      placeholder="Task name"
                    />

                    Description
                    <textarea
                      value={editDescription}
                      onChange={(e) => setEditDescription(e.target.value)}
                      rows={3}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                      placeholder="Task description"
                    />

                    Priority
                    <select
                      value={editPriority}
                      onChange={(e) => setEditPriority(Number(e.target.value))}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    >
                      <option value={0}>Low</option>
                      <option value={1}>Medium</option>
                      <option value={2}>High</option>
                      <option value={3}>Critical</option>
                    </select>

                    <button
                      onClick={handleCancelEdit}
                      className="flex-1 px-3 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors"
                    >
                      Cancel
                    </button>
                    <button
                      onClick={handleSaveEdit}
                      disabled={isSaving || !editName.trim()}
                      className="flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                    >
                      {isSaving ? 'Saving...' : <><Check size={16} /> Save</>}
                    </button>

              ) : (
                /* View Mode */
                <>
                  {/* Task Name */}

                    Name

{selectedTask.name}

                  {/* Description */}

                    Description

                      {selectedTask.description || No description}

                  {/* Status */}

                    Status

                      {STATUS_LABELS[selectedTask.status] || selectedTask.status}

                  {/* Priority */}

                    Priority

                      {PRIORITY_LABELS[selectedTask.priority] || 'Unknown'}

                  {/* Agent Assignment */}

                      <User size={14} />
                      Agent Assignment

                      {selectedTask.agent_type ? (
                        {selectedTask.agent_type.replace('_', ' ')}
                      ) : (
                        Not assigned
                      )}

                  {/* Iteration Count */}

                      <RefreshCw size={14} />
                      Iteration Count

{selectedTask.iteration_count}

                  {/* Flagged for Review */}

                      <Flag size={14} />
                      Flagged for Review

                      {selectedTask.flagged_for_review ? 'Yes' : 'No'}

                  {/* Time Estimates */}
                  {(selectedTask.estimated_time || selectedTask.actual_time) && (

                        <Clock size={14} />
                        Time

                        {selectedTask.estimated_time &&
Estimated: {selectedTask.estimated_time} min
}
                        {selectedTask.actual_time &&
Actual: {selectedTask.actual_time} min
}

                  )}

                  {/* Created/Updated timestamps */}

Created: {new Date(selectedTask.created_at).toLocaleString()}

Updated: {new Date(selectedTask.updated_at).toLocaleString()}

                </>
              )}

        )}

  )
}


I see the current KanbanBoard doesn't have filter/sort functionality implemented yet. The feature requires filtering by priority and sorting by created date. I need to implement this functionality. Let me add filter and sort controls to the Kanban board:


Edit

import { useEffect, useState } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2 } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'

import { useEffect, useState, useMemo } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2, Filter, ArrowUpDown } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'


The file C:\Users\MikeSwanson\AutoBuilder\My-Auto-Builder\frontend\src\pages\KanbanBoard.tsx has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
     1→import { useEffect, useState, useMemo } from 'react'
     2→import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2, Filter, ArrowUpDown } from 'lucide-react'
     3→import * as Dialog from '@radix-ui/react-dialog'
     4→import * as AlertDialog from '@radix-ui/react-alert-dialog'
     5→import { useProjectStore } from '../stores/projectStore'
     6→import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'
     7→
     8→const COLUMNS = [
     9→  { id: 'backlog', title: 'Backlog', color: 'border-slate-500' },
    10→  { id: 'in_progress', title: 'In Progress', color: 'border-accent' },

import { useEffect, useState, useMemo } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2, Filter, ArrowUpDown } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'

import { useEffect, useState } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2 } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'

const COLUMNS = [
  { id: 'backlog', title: 'Backlog', color: 'border-slate-500' },
  { id: 'in_progress', title: 'In Progress', color: 'border-accent' },
  { id: 'qa', title: 'QA', color: 'border-primary-400' },
  { id: 'done', title: 'Done', color: 'border-green-400' },
  { id: 'blocked', title: 'Blocked', color: 'border-destructive' },
]

const PRIORITY_LABELS: Record<number, string> = {
  0: 'Low',
  1: 'Medium',
  2: 'High',
  3: 'Critical',
}

const STATUS_LABELS: Record<string, string> = {
  backlog: 'Backlog',
  in_progress: 'In Progress',
  qa: 'QA',
  done: 'Done',
  blocked: 'Blocked',
}

export default function KanbanBoard() {
  const { currentProject } = useProjectStore()
  const { tasks, fetchTasks, createTask, updateTask, updateTaskStatus, deleteTask, isLoading } = useTaskStore()
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newTaskName, setNewTaskName] = useState('')
  const [newTaskDescription, setNewTaskDescription] = useState('')
  const [newTaskPriority, setNewTaskPriority] = useState(0)
  const [isCreating, setIsCreating] = useState(false)
  const [draggedTask, setDraggedTask] = useState<number | null>(null)
  const [selectedTask, setSelectedTask] = useState<Task | null>(null)
  const [isEditing, setIsEditing] = useState(false)
  const [editName, setEditName] = useState('')
  const [editDescription, setEditDescription] = useState('')
  const [editPriority, setEditPriority] = useState(0)
  const [isSaving, setIsSaving] = useState(false)
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  useEffect(() => {
    if (currentProject?.id) {
      fetchTasks(currentProject.id)
    }
  }, [currentProject?.id, fetchTasks])

  const getTasksByStatus = (status: string) => {
    return tasks.filter((task) => task.status === status)
  }

  const handleCreateTask = async () => {
    if (!currentProject || !newTaskName.trim()) return
    setIsCreating(true)
    try {
      const taskData: TaskCreate = {
        name: newTaskName.trim(),
        description: newTaskDescription.trim() || undefined,
        priority: newTaskPriority,
      }
      await createTask(currentProject.id, taskData)
      setNewTaskName('')
      setNewTaskDescription('')
      setNewTaskPriority(0)
      setShowAddDialog(false)
    } catch (error) {
      console.error('Failed to create task:', error)
    } finally {
      setIsCreating(false)
    }
  }

  const handleDragStart = (taskId: number) => {
    setDraggedTask(taskId)
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
  }

  const handleDrop = async (targetStatus: string) => {
    if (draggedTask === null) return
    try {
      await updateTaskStatus(draggedTask, targetStatus)
    } catch (error) {
      console.error('Failed to update task status:', error)
    }
    setDraggedTask(null)
  }

  const handleStartEdit = () => {
    if (!selectedTask) return
    setEditName(selectedTask.name)
    setEditDescription(selectedTask.description || '')
    setEditPriority(selectedTask.priority)
    setIsEditing(true)
  }

  const handleCancelEdit = () => {
    setIsEditing(false)
  }

  const handleSaveEdit = async () => {
    if (!selectedTask) return
    setIsSaving(true)
    try {
      const updates: TaskUpdate = {
        name: editName.trim(),
        description: editDescription.trim() || undefined,
        priority: editPriority,
      }
      const updatedTask = await updateTask(selectedTask.id, updates)
      setSelectedTask(updatedTask)
      setIsEditing(false)
    } catch (error) {
      console.error('Failed to update task:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDeleteTask = async () => {
    if (!selectedTask) return
    setIsDeleting(true)
    try {
      await deleteTask(selectedTask.id)
      setSelectedTask(null)
      setShowDeleteDialog(false)
    } catch (error) {
      console.error('Failed to delete task:', error)
    } finally {
      setIsDeleting(false)
    }
  }

  if (!currentProject) {
    return (

Select a project to view its Kanban board

    )
  }

  return (

      {/* Header */}

Kanban Board

        <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
          <Dialog.Trigger asChild>
            <button className="btn-accent flex items-center gap-2">
              <Plus size={18} />
              Add Task
            </button>
          </Dialog.Trigger>
          <Dialog.Portal>
            <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
            <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">

                <Dialog.Title className="text-xl font-semibold text-white">
                  Add New Task
                </Dialog.Title>
                <Dialog.Close asChild>
                  <button className="text-slate-400 hover:text-white">
                    <X size={20} />
                  </button>
                </Dialog.Close>

              <Dialog.Description className="text-slate-400 mb-4">
                Create a new task for this project.
              </Dialog.Description>

                    Task Name *

                  <input
                    type="text"
                    value={newTaskName}
                    onChange={(e) => setNewTaskName(e.target.value)}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    placeholder="Enter task name"
                  />

                    Description

                  <textarea
                    value={newTaskDescription}
                    onChange={(e) => setNewTaskDescription(e.target.value)}
                    rows={3}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                    placeholder="Enter task description"
                  />

                    Priority

                  <select
                    value={newTaskPriority}
                    onChange={(e) => setNewTaskPriority(Number(e.target.value))}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                  >
                    <option value={0}>Low</option>
                    <option value={1}>Medium</option>
                    <option value={2}>High</option>
                    <option value={3}>Critical</option>
                  </select>

                <Dialog.Close asChild>
                  <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                    Cancel
                  </button>
                </Dialog.Close>
                <button
                  onClick={handleCreateTask}
                  disabled={isCreating || !newTaskName.trim()}
                  className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                >
                  {isCreating ? 'Creating...' : 'Create Task'}
                </button>

            </Dialog.Content>
          </Dialog.Portal>
        </Dialog.Root>

      {/* Main Content Area */}

        {/* Kanban Columns */}
        <div className={`flex-1 flex gap-4 overflow-x-auto pb-4 ${selectedTask ? 'mr-0' : ''}`}>
          {COLUMNS.map((column) => (
          <div
            key={column.id}
            className={`flex-shrink-0 w-72 bg-slate-800 rounded-lg border-t-2 ${column.color}`}
            onDragOver={handleDragOver}
            onDrop={() => handleDrop(column.id)}
          >
            {/* Column Header */}

{column.title}

                  {getTasksByStatus(column.id).length}

            {/* Column Content */}

              {isLoading && tasks.length === 0 ? (

                  Loading...

              ) : getTasksByStatus(column.id).length === 0 ? (

                  No tasks

              ) : (
                getTasksByStatus(column.id).map((task) => (

 handleDragStart(task.id)}
                    onClick={() => setSelectedTask(task)}
                    className={`kanban-card bg-slate-900 rounded-lg p-4 border border-slate-700 cursor-pointer hover:border-slate-600 ${
                      draggedTask === task.id ? 'opacity-50' : ''
                    } ${selectedTask?.id === task.id ? 'ring-2 ring-accent' : ''}`}
                  >

                      <GripVertical size={16} className="text-slate-600 mt-0.5 flex-shrink-0" />

{task.name}

                        {task.description && (

                            {task.description}

                        )}

                          <span
                            className={`badge ${
                              column.id === 'backlog'
                                ? 'badge-backlog'
                                : column.id === 'in_progress'
                                ? 'badge-in-progress'
                                : column.id === 'qa'
                                ? 'badge-qa'
                                : column.id === 'done'
                                ? 'badge-done'
                                : 'badge-blocked'
                            }`}
                          >
                            {column.title}

                            {task.priority === 3 ? 'Critical' :
                             task.priority === 2 ? 'High' :
                             task.priority === 1 ? 'Medium' : 'Low'}

                ))
              )}

          ))}

        {/* Task Details Panel */}
        {selectedTask && (

Task Details

                {!isEditing && (
                  <>
                    <button
                      onClick={handleStartEdit}
                      className="text-slate-400 hover:text-accent transition-colors"
                      title="Edit Task"
                    >
                      <Pencil size={18} />
                    </button>
                    <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
                      <AlertDialog.Trigger asChild>
                        <button
                          className="text-slate-400 hover:text-destructive transition-colors"
                          title="Delete Task"
                        >
                          <Trash2 size={18} />
                        </button>
                      </AlertDialog.Trigger>
                      <AlertDialog.Portal>
                        <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
                        <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">
                          <AlertDialog.Title className="text-xl font-semibold text-white">
                            Delete Task
                          </AlertDialog.Title>
                          <AlertDialog.Description className="mt-3 text-slate-400">
                            Are you sure you want to delete {selectedTask.name}?
                            This action cannot be undone.
                          </AlertDialog.Description>

                            <AlertDialog.Cancel asChild>
                              <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                                Cancel
                              </button>
                            </AlertDialog.Cancel>
                            <AlertDialog.Action asChild>
                              <button
                                onClick={handleDeleteTask}
                                disabled={isDeleting}
                                className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
                              >
                                {isDeleting ? 'Deleting...' : 'Delete Task'}
                              </button>
                            </AlertDialog.Action>

                        </AlertDialog.Content>
                      </AlertDialog.Portal>
                    </AlertDialog.Root>
                  </>
                )}
                <button
                  onClick={() => {
                    setSelectedTask(null)
                    setIsEditing(false)
                  }}
                  className="text-slate-400 hover:text-white transition-colors"
                >
                  <X size={20} />
                </button>

              {isEditing ? (
                /* Edit Form */

                    Name *
                    <input
                      type="text"
                      value={editName}
                      onChange={(e) => setEditName(e.target.value)}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                      placeholder="Task name"
                    />

                    Description
                    <textarea
                      value={editDescription}
                      onChange={(e) => setEditDescription(e.target.value)}
                      rows={3}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                      placeholder="Task description"
                    />

                    Priority
                    <select
                      value={editPriority}
                      onChange={(e) => setEditPriority(Number(e.target.value))}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    >
                      <option value={0}>Low</option>
                      <option value={1}>Medium</option>
                      <option value={2}>High</option>
                      <option value={3}>Critical</option>
                    </select>

                    <button
                      onClick={handleCancelEdit}
                      className="flex-1 px-3 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors"
                    >
                      Cancel
                    </button>
                    <button
                      onClick={handleSaveEdit}
                      disabled={isSaving || !editName.trim()}
                      className="flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                    >
                      {isSaving ? 'Saving...' : <><Check size={16} /> Save</>}
                    </button>

              ) : (
                /* View Mode */
                <>
                  {/* Task Name */}

                    Name

{selectedTask.name}

                  {/* Description */}

                    Description

                      {selectedTask.description || No description}

                  {/* Status */}

                    Status

                      {STATUS_LABELS[selectedTask.status] || selectedTask.status}

                  {/* Priority */}

                    Priority

                      {PRIORITY_LABELS[selectedTask.priority] || 'Unknown'}

                  {/* Agent Assignment */}

                      <User size={14} />
                      Agent Assignment

                      {selectedTask.agent_type ? (
                        {selectedTask.agent_type.replace('_', ' ')}
                      ) : (
                        Not assigned
                      )}

                  {/* Iteration Count */}

                      <RefreshCw size={14} />
                      Iteration Count

{selectedTask.iteration_count}

                  {/* Flagged for Review */}

                      <Flag size={14} />
                      Flagged for Review

                      {selectedTask.flagged_for_review ? 'Yes' : 'No'}

                  {/* Time Estimates */}
                  {(selectedTask.estimated_time || selectedTask.actual_time) && (

                        <Clock size={14} />
                        Time

                        {selectedTask.estimated_time &&
Estimated: {selectedTask.estimated_time} min
}
                        {selectedTask.actual_time &&
Actual: {selectedTask.actual_time} min
}

                  )}

                  {/* Created/Updated timestamps */}

Created: {new Date(selectedTask.created_at).toLocaleString()}

Updated: {new Date(selectedTask.updated_at).toLocaleString()}

                </>
              )}

        )}

  )
}

-import { useEffect, useState } from 'react'

-import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2 } from 'lucide-react'

+import { useEffect, useState, useMemo } from 'react'

+import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2, Filter, ArrowUpDown } from 'lucide-react'


  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  useEffect(() => {

  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)
  // Filter and Sort state
  const [priorityFilter, setPriorityFilter] = useState<number | 'all'>('all')
  const [sortOrder, setSortOrder] = useState<'newest' | 'oldest' | 'priority'>('newest')

  useEffect(() => {


The file C:\Users\MikeSwanson\AutoBuilder\My-Auto-Builder\frontend\src\pages\KanbanBoard.tsx has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
    42→  const [editName, setEditName] = useState('')
    43→  const [editDescription, setEditDescription] = useState('')
    44→  const [editPriority, setEditPriority] = useState(0)
    45→  const [isSaving, setIsSaving] = useState(false)
    46→  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
    47→  const [isDeleting, setIsDeleting] = useState(false)
    48→  // Filter and Sort state
    49→  const [priorityFilter, setPriorityFilter] = useState<number | 'all'>('all')
    50→  const [sortOrder, setSortOrder] = useState<'newest' | 'oldest' | 'priority'>('newest')
    51→
    52→  useEffect(() => {
    53→    if (currentProject?.id) {
    54→      fetchTasks(currentProject.id)
    55→    }
    56→  }, [currentProject?.id, fetchTasks])

  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)
  // Filter and Sort state
  const [priorityFilter, setPriorityFilter] = useState<number | 'all'>('all')
  const [sortOrder, setSortOrder] = useState<'newest' | 'oldest' | 'priority'>('newest')

  useEffect(() => {

import { useEffect, useState, useMemo } from 'react'
import { Plus, X, GripVertical, Clock, User, RefreshCw, Flag, Pencil, Check, Trash2, Filter, ArrowUpDown } from 'lucide-react'
import * as Dialog from '@radix-ui/react-dialog'
import * as AlertDialog from '@radix-ui/react-alert-dialog'
import { useProjectStore } from '../stores/projectStore'
import { useTaskStore, Task, TaskCreate, TaskUpdate } from '../stores/taskStore'

const COLUMNS = [
  { id: 'backlog', title: 'Backlog', color: 'border-slate-500' },
  { id: 'in_progress', title: 'In Progress', color: 'border-accent' },
  { id: 'qa', title: 'QA', color: 'border-primary-400' },
  { id: 'done', title: 'Done', color: 'border-green-400' },
  { id: 'blocked', title: 'Blocked', color: 'border-destructive' },
]

const PRIORITY_LABELS: Record<number, string> = {
  0: 'Low',
  1: 'Medium',
  2: 'High',
  3: 'Critical',
}

const STATUS_LABELS: Record<string, string> = {
  backlog: 'Backlog',
  in_progress: 'In Progress',
  qa: 'QA',
  done: 'Done',
  blocked: 'Blocked',
}

export default function KanbanBoard() {
  const { currentProject } = useProjectStore()
  const { tasks, fetchTasks, createTask, updateTask, updateTaskStatus, deleteTask, isLoading } = useTaskStore()
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newTaskName, setNewTaskName] = useState('')
  const [newTaskDescription, setNewTaskDescription] = useState('')
  const [newTaskPriority, setNewTaskPriority] = useState(0)
  const [isCreating, setIsCreating] = useState(false)
  const [draggedTask, setDraggedTask] = useState<number | null>(null)
  const [selectedTask, setSelectedTask] = useState<Task | null>(null)
  const [isEditing, setIsEditing] = useState(false)
  const [editName, setEditName] = useState('')
  const [editDescription, setEditDescription] = useState('')
  const [editPriority, setEditPriority] = useState(0)
  const [isSaving, setIsSaving] = useState(false)
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  useEffect(() => {
    if (currentProject?.id) {
      fetchTasks(currentProject.id)
    }
  }, [currentProject?.id, fetchTasks])

  const getTasksByStatus = (status: string) => {
    return tasks.filter((task) => task.status === status)
  }

  const handleCreateTask = async () => {
    if (!currentProject || !newTaskName.trim()) return
    setIsCreating(true)
    try {
      const taskData: TaskCreate = {
        name: newTaskName.trim(),
        description: newTaskDescription.trim() || undefined,
        priority: newTaskPriority,
      }
      await createTask(currentProject.id, taskData)
      setNewTaskName('')
      setNewTaskDescription('')
      setNewTaskPriority(0)
      setShowAddDialog(false)
    } catch (error) {
      console.error('Failed to create task:', error)
    } finally {
      setIsCreating(false)
    }
  }

  const handleDragStart = (taskId: number) => {
    setDraggedTask(taskId)
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
  }

  const handleDrop = async (targetStatus: string) => {
    if (draggedTask === null) return
    try {
      await updateTaskStatus(draggedTask, targetStatus)
    } catch (error) {
      console.error('Failed to update task status:', error)
    }
    setDraggedTask(null)
  }

  const handleStartEdit = () => {
    if (!selectedTask) return
    setEditName(selectedTask.name)
    setEditDescription(selectedTask.description || '')
    setEditPriority(selectedTask.priority)
    setIsEditing(true)
  }

  const handleCancelEdit = () => {
    setIsEditing(false)
  }

  const handleSaveEdit = async () => {
    if (!selectedTask) return
    setIsSaving(true)
    try {
      const updates: TaskUpdate = {
        name: editName.trim(),
        description: editDescription.trim() || undefined,
        priority: editPriority,
      }
      const updatedTask = await updateTask(selectedTask.id, updates)
      setSelectedTask(updatedTask)
      setIsEditing(false)
    } catch (error) {
      console.error('Failed to update task:', error)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDeleteTask = async () => {
    if (!selectedTask) return
    setIsDeleting(true)
    try {
      await deleteTask(selectedTask.id)
      setSelectedTask(null)
      setShowDeleteDialog(false)
    } catch (error) {
      console.error('Failed to delete task:', error)
    } finally {
      setIsDeleting(false)
    }
  }

  if (!currentProject) {
    return (

Select a project to view its Kanban board

    )
  }

  return (

      {/* Header */}

Kanban Board

        <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
          <Dialog.Trigger asChild>
            <button className="btn-accent flex items-center gap-2">
              <Plus size={18} />
              Add Task
            </button>
          </Dialog.Trigger>
          <Dialog.Portal>
            <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
            <Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">

                <Dialog.Title className="text-xl font-semibold text-white">
                  Add New Task
                </Dialog.Title>
                <Dialog.Close asChild>
                  <button className="text-slate-400 hover:text-white">
                    <X size={20} />
                  </button>
                </Dialog.Close>

              <Dialog.Description className="text-slate-400 mb-4">
                Create a new task for this project.
              </Dialog.Description>

                    Task Name *

                  <input
                    type="text"
                    value={newTaskName}
                    onChange={(e) => setNewTaskName(e.target.value)}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    placeholder="Enter task name"
                  />

                    Description

                  <textarea
                    value={newTaskDescription}
                    onChange={(e) => setNewTaskDescription(e.target.value)}
                    rows={3}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                    placeholder="Enter task description"
                  />

                    Priority

                  <select
                    value={newTaskPriority}
                    onChange={(e) => setNewTaskPriority(Number(e.target.value))}
                    className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                  >
                    <option value={0}>Low</option>
                    <option value={1}>Medium</option>
                    <option value={2}>High</option>
                    <option value={3}>Critical</option>
                  </select>

                <Dialog.Close asChild>
                  <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                    Cancel
                  </button>
                </Dialog.Close>
                <button
                  onClick={handleCreateTask}
                  disabled={isCreating || !newTaskName.trim()}
                  className="px-4 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                >
                  {isCreating ? 'Creating...' : 'Create Task'}
                </button>

            </Dialog.Content>
          </Dialog.Portal>
        </Dialog.Root>

      {/* Main Content Area */}

        {/* Kanban Columns */}
        <div className={`flex-1 flex gap-4 overflow-x-auto pb-4 ${selectedTask ? 'mr-0' : ''}`}>
          {COLUMNS.map((column) => (
          <div
            key={column.id}
            className={`flex-shrink-0 w-72 bg-slate-800 rounded-lg border-t-2 ${column.color}`}
            onDragOver={handleDragOver}
            onDrop={() => handleDrop(column.id)}
          >
            {/* Column Header */}

{column.title}

                  {getTasksByStatus(column.id).length}

            {/* Column Content */}

              {isLoading && tasks.length === 0 ? (

                  Loading...

              ) : getTasksByStatus(column.id).length === 0 ? (

                  No tasks

              ) : (
                getTasksByStatus(column.id).map((task) => (

 handleDragStart(task.id)}
                    onClick={() => setSelectedTask(task)}
                    className={`kanban-card bg-slate-900 rounded-lg p-4 border border-slate-700 cursor-pointer hover:border-slate-600 ${
                      draggedTask === task.id ? 'opacity-50' : ''
                    } ${selectedTask?.id === task.id ? 'ring-2 ring-accent' : ''}`}
                  >

                      <GripVertical size={16} className="text-slate-600 mt-0.5 flex-shrink-0" />

{task.name}

                        {task.description && (

                            {task.description}

                        )}

                          <span
                            className={`badge ${
                              column.id === 'backlog'
                                ? 'badge-backlog'
                                : column.id === 'in_progress'
                                ? 'badge-in-progress'
                                : column.id === 'qa'
                                ? 'badge-qa'
                                : column.id === 'done'
                                ? 'badge-done'
                                : 'badge-blocked'
                            }`}
                          >
                            {column.title}

                            {task.priority === 3 ? 'Critical' :
                             task.priority === 2 ? 'High' :
                             task.priority === 1 ? 'Medium' : 'Low'}

                ))
              )}

          ))}

        {/* Task Details Panel */}
        {selectedTask && (

Task Details

                {!isEditing && (
                  <>
                    <button
                      onClick={handleStartEdit}
                      className="text-slate-400 hover:text-accent transition-colors"
                      title="Edit Task"
                    >
                      <Pencil size={18} />
                    </button>
                    <AlertDialog.Root open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
                      <AlertDialog.Trigger asChild>
                        <button
                          className="text-slate-400 hover:text-destructive transition-colors"
                          title="Delete Task"
                        >
                          <Trash2 size={18} />
                        </button>
                      </AlertDialog.Trigger>
                      <AlertDialog.Portal>
                        <AlertDialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
                        <AlertDialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-slate-800 border border-slate-700 rounded-lg p-6 w-full max-w-md z-50 shadow-xl">
                          <AlertDialog.Title className="text-xl font-semibold text-white">
                            Delete Task
                          </AlertDialog.Title>
                          <AlertDialog.Description className="mt-3 text-slate-400">
                            Are you sure you want to delete {selectedTask.name}?
                            This action cannot be undone.
                          </AlertDialog.Description>

                            <AlertDialog.Cancel asChild>
                              <button className="px-4 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors">
                                Cancel
                              </button>
                            </AlertDialog.Cancel>
                            <AlertDialog.Action asChild>
                              <button
                                onClick={handleDeleteTask}
                                disabled={isDeleting}
                                className="px-4 py-2 text-sm bg-destructive hover:bg-destructive/80 text-white rounded-lg transition-colors disabled:opacity-50"
                              >
                                {isDeleting ? 'Deleting...' : 'Delete Task'}
                              </button>
                            </AlertDialog.Action>

                        </AlertDialog.Content>
                      </AlertDialog.Portal>
                    </AlertDialog.Root>
                  </>
                )}
                <button
                  onClick={() => {
                    setSelectedTask(null)
                    setIsEditing(false)
                  }}
                  className="text-slate-400 hover:text-white transition-colors"
                >
                  <X size={20} />
                </button>

              {isEditing ? (
                /* Edit Form */

                    Name *
                    <input
                      type="text"
                      value={editName}
                      onChange={(e) => setEditName(e.target.value)}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                      placeholder="Task name"
                    />

                    Description
                    <textarea
                      value={editDescription}
                      onChange={(e) => setEditDescription(e.target.value)}
                      rows={3}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent resize-none"
                      placeholder="Task description"
                    />

                    Priority
                    <select
                      value={editPriority}
                      onChange={(e) => setEditPriority(Number(e.target.value))}
                      className="w-full px-3 py-2 bg-slate-900 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent"
                    >
                      <option value={0}>Low</option>
                      <option value={1}>Medium</option>
                      <option value={2}>High</option>
                      <option value={3}>Critical</option>
                    </select>

                    <button
                      onClick={handleCancelEdit}
                      className="flex-1 px-3 py-2 text-sm text-slate-300 hover:bg-slate-700 rounded-lg transition-colors"
                    >
                      Cancel
                    </button>
                    <button
                      onClick={handleSaveEdit}
                      disabled={isSaving || !editName.trim()}
                      className="flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm bg-accent hover:bg-accent/80 text-white rounded-lg transition-colors disabled:opacity-50"
                    >
                      {isSaving ? 'Saving...' : <><Check size={16} /> Save</>}
                    </button>

              ) : (
                /* View Mode */
                <>
                  {/* Task Name */}

                    Name

{selectedTask.name}

                  {/* Description */}

                    Description

                      {selectedTask.description || No description}

                  {/* Status */}

                    Status

                      {STATUS_LABELS[selectedTask.status] || selectedTask.status}

                  {/* Priority */}

                    Priority

                      {PRIORITY_LABELS[selectedTask.priority] || 'Unknown'}

                  {/* Agent Assignment */}

                      <User size={14} />
                      Agent Assignment

                      {selectedTask.agent_type ? (
                        {selectedTask.agent_type.replace('_', ' ')}
                      ) : (
                        Not assigned
                      )}

                  {/* Iteration Count */}

                      <RefreshCw size={14} />
                      Iteration Count

{selectedTask.iteration_count}

                  {/* Flagged for Review */}

                      <Flag size={14} />
                      Flagged for Review

                      {selectedTask.flagged_for_review ? 'Yes' : 'No'}

                  {/* Time Estimates */}
                  {(selectedTask.estimated_time || selectedTask.actual_time) && (

                        <Clock size={14} />
                        Time

                        {selectedTask.estimated_time &&
Estimated: {selectedTask.estimated_time} min
}
                        {selectedTask.actual_time &&
Actual: {selectedTask.actual_time} min
}

                  )}

                  {/* Created/Updated timestamps */}

Created: {new Date(selectedTask.created_at).toLocaleString()}

Updated: {new Date(selectedTask.updated_at).toLocaleString()}

                </>
              )}

        )}

  )
}

+  const [priorityFilter, setPriorityFilter] = useState<number | 'all'>('all')

+  const [sortOrder, setSortOrder] = useState<'newest' | 'oldest' | 'priority'>('newest')


  }, [currentProject?.id, fetchTasks])

  const getTasksByStatus = (status: string) => {
    return tasks.filter((task) => task.status === status)
  }

  }, [currentProject?.id, fetchTasks])

  // Filtered and sorted tasks
  const filteredAndSortedTasks = useMemo(() => {
    let result = [...tasks]

    // Apply priority filter
    if (priorityFilter !== 'all') {
      result = result.filter(task => task.priority === priorityFilter)
    }

    // Apply sort
    result.sort((a, b) => {
      if (sortOrder === 'newest') {
        return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
      } else if (sortOrder === 'oldest') {
        return new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
      } else {
        // priority - highest first
        return b.priority - a.priority
      }
    })

    return result
  }, [tasks, priorityFilter, sortOrder])

  const getTasksByStatus = (status: string) => {
    return filteredAndSortedTasks.filter((task) => task.status === status)
  }