The file /Users/khalidbinkalban/my-workspace/client/src/components/Tasks.jsx has been updated successfully.

import { useState, useEffect, useRef } from 'react';
import { Plus, Search, SlidersHorizontal, CheckSquare, X, Check, Calendar, User, AlertTriangle } from 'lucide-react';

import { useState, useEffect, useRef } from 'react';
import { Plus, Search, SlidersHorizontal, CheckSquare, X } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import TaskCard from './TaskCard';
import TaskModal from './TaskModal';
import ConfirmDialog from './ConfirmDialog';
import { CATEGORIES, STATUSES, PRIORITIES } from '../utils';

function useDebounce(v, d = 300) {
  const [dv, setDv] = useState(v);
  useEffect(() => { const t = setTimeout(() => setDv(v), d); return () => clearTimeout(t); }, [v, d]);
  return dv;
}

// Status columns for horizontal kanban-style layout
const STATUS_COLS = [
  { id: '',          label: 'All',         color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'Open',      label: 'Open',        color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'In Progress',label:'In Progress', color: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' },
  { id: 'Waiting',   label: 'Waiting',     color: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300' },
  { id: 'Done',      label: 'Done',        color: 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300' },
];

export default function Tasks() {
  const [tasks, setTasks]           = useState([]);
  const [projects, setProjects]     = useState([]);
  const [loading, setLoading]       = useState(true);
  const [search, setSearch]         = useState('');
  const [statusFilter, setStatus]   = useState('');
  const [catFilter, setCat]         = useState('');
  const [priorityFilter, setPri]    = useState('');
  const [showFilters, setShowFilters] = useState(false);
  const [editTask, setEditTask]     = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [showNew, setShowNew]       = useState(false);
  const [selected, setSelected]     = useState(new Set());
  const [viewMode, setViewMode]     = useState('grid'); // 'grid' | 'kanban'
  const debouncedSearch = useDebounce(search);

  const load = async () => {
    setLoading(true);
    const p = new URLSearchParams();
    if (debouncedSearch)  p.set('search',   debouncedSearch);
    if (statusFilter)     p.set('status',   statusFilter);
    if (catFilter)        p.set('category', catFilter);
    if (priorityFilter)   p.set('priority', priorityFilter);
    try {
      const [t, pr] = await Promise.all([api.get('/tasks?' + p), api.get('/projects')]);
      setTasks(t); setProjects(pr);
    } finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [debouncedSearch, statusFilter, catFilter, priorityFilter]);

  const handleSave = async (form) => {
    try {
      if (editTask?.id) { await api.put(`/tasks/${editTask.id}`, form); toast.success('Task updated'); }
      else              { await api.post('/tasks', form);               toast.success('Task added');   }
      setEditTask(null); setShowNew(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleDelete = async () => {
    await api.delete(`/tasks/${deleteTask.id}`); toast.success('Deleted');
    setDeleteTask(null); load();
  };

  const toggleFocus = async (task) => { await api.patch(`/tasks/${task.id}/focus`); load(); };

  const toggleSelect = (id) => setSelected(s => {
    const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n;
  });

  const bulkDone = async () => {
    await Promise.all([...selected].map(id => api.patch(`/tasks/${id}/status`, { status: 'Done' })));
    toast.success(`${selected.size} tasks done`);
    setSelected(new Set()); load();
  };

  const hasFilters = statusFilter || catFilter || priorityFilter;

  // Kanban grouping by status
  const KANBAN_COLS = ['Open', 'In Progress', 'Waiting', 'Done'];
  const byStatus = KANBAN_COLS.reduce((acc, s) => {
    acc[s] = tasks.filter(t => t.status === s);
    return acc;
  }, {});

  return (

      {/* Header */}

Tasks

            {/* View toggle */}

              {[{ id:'grid', label:'Grid' }, { id:'kanban', label:'Board' }].map(v => (
                <button key={v.id} onClick={() => setViewMode(v.id)}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
                    viewMode === v.id ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm' : 'text-gray-500'
                  }`}>
                  {v.label}
                </button>
              ))}

            <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">
              <Plus size={14} /> New Task
            </button>

        {/* Search + filter row */}

            <Search size={13} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
            <input className="input pl-8 py-2 text-sm" placeholder="Search tasks…" value={search} onChange={e => setSearch(e.target.value)} />

          <button onClick={() => setShowFilters(!showFilters)}
            className={`btn-secondary flex items-center gap-1.5 py-2 text-sm ${hasFilters ? 'border-primary text-primary' : ''}`}>
            <SlidersHorizontal size={13} />
            {hasFilters ? 'Filtered' : 'Filter'}
          </button>

        {/* Filter chips */}
        {showFilters && (

            <select className="select text-xs py-1.5 w-auto" value={statusFilter} onChange={e => setStatus(e.target.value)}>
              <option value="">All Status</option>
              {STATUSES.map(s => <option key={s}>{s}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={catFilter} onChange={e => setCat(e.target.value)}>
              <option value="">All Categories</option>
              {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={priorityFilter} onChange={e => setPri(e.target.value)}>
              <option value="">All Priorities</option>
              {PRIORITIES.map(p => <option key={p}>{p}</option>)}
            </select>
            {hasFilters && (
              <button onClick={() => { setStatus(''); setCat(''); setPri(''); }}
                className="flex items-center gap-1 text-xs text-primary hover:underline px-2">
                <X size={11} /> Clear
              </button>
            )}

        )}

        {/* Bulk actions */}
        {selected.size > 0 && (

            {selected.size} selected
            <button onClick={bulkDone} className="btn-primary py-1 text-xs flex items-center gap-1">
              <CheckSquare size={11} /> Mark done
            </button>
            <button onClick={() => setSelected(new Set())} className="btn-ghost text-xs">Clear</button>

        )}

      {/* Content area */}
      {loading ? (

          {[...Array(8)].map((_, i) =>
)}

      ) : tasks.length === 0 ? (

          <CheckSquare size={40} className="text-gray-200 dark:text-gray-700" />

No tasks found

          {(search || hasFilters) && (
            <button onClick={() => { setSearch(''); setStatus(''); setCat(''); setPri(''); }} className="btn-secondary text-sm">
              Clear filters
            </button>
          )}

      ) : viewMode === 'grid' ? (
        /* ── GRID view ─────────────────────────────────── */

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

            {tasks.map(task => (

                <input type="checkbox" className="absolute top-3 left-3 z-10 w-3.5 h-3.5 accent-primary cursor-pointer rounded"
                  checked={selected.has(task.id)} onChange={() => toggleSelect(task.id)} />

                  <TaskCard task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />

            ))}

      ) : (
        /* ── KANBAN / BOARD view ────────────────────────── */

          {KANBAN_COLS.map(status => {
            const col = STATUS_COLS.find(c => c.id === status);
            const colTasks = byStatus[status] || [];
            return (

{status}

                    <span className={`badge text-[10px] py-0.5 ${col?.color}`}>{colTasks.length}

                  <button onClick={() => setShowNew(true)}
                    className="w-6 h-6 rounded-lg bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 flex items-center justify-center text-gray-400 hover:text-primary hover:border-primary transition-all">
                    <Plus size={12} />
                  </button>

                  {colTasks.map(task => (
                    <TaskCard key={task.id} task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />
                  ))}
                  {colTasks.length === 0 && (

No tasks

                  )}

            );
          })}

      )}

      {(showNew || editTask) && (
        <TaskModal task={editTask} projects={projects} onSave={handleSave} onClose={() => { setShowNew(false); setEditTask(null); }} />
      )}
      {deleteTask && (
        <ConfirmDialog title="Delete task?" message={`"${deleteTask.title}"`} onConfirm={handleDelete} onCancel={() => setDeleteTask(null)} />
      )}

  );
}

-import { Plus, Search, SlidersHorizontal, CheckSquare, X } from 'lucide-react';

+import { Plus, Search, SlidersHorizontal, CheckSquare, X, Check, Calendar, User, AlertTriangle } from 'lucide-react';


Edit

import { CATEGORIES, STATUSES, PRIORITIES } from '../utils';

import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass, formatDate, isOverdue } from '../utils';

const PRIORITY_BORDER = {
  Urgent: 'border-l-red-500',
  High:   'border-l-amber-400',
  Medium: 'border-l-blue-400',
  Low:    'border-l-green-400',
};


import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass, formatDate, isOverdue } from '../utils';

const PRIORITY_BORDER = {
  Urgent: 'border-l-red-500',
  High:   'border-l-amber-400',
  Medium: 'border-l-blue-400',
  Low:    'border-l-green-400',
};

import { useState, useEffect, useRef } from 'react';
import { Plus, Search, SlidersHorizontal, CheckSquare, X, Check, Calendar, User, AlertTriangle } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import TaskCard from './TaskCard';
import TaskModal from './TaskModal';
import ConfirmDialog from './ConfirmDialog';
import { CATEGORIES, STATUSES, PRIORITIES } from '../utils';

function useDebounce(v, d = 300) {
  const [dv, setDv] = useState(v);
  useEffect(() => { const t = setTimeout(() => setDv(v), d); return () => clearTimeout(t); }, [v, d]);
  return dv;
}

// Status columns for horizontal kanban-style layout
const STATUS_COLS = [
  { id: '',          label: 'All',         color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'Open',      label: 'Open',        color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'In Progress',label:'In Progress', color: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' },
  { id: 'Waiting',   label: 'Waiting',     color: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300' },
  { id: 'Done',      label: 'Done',        color: 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300' },
];

export default function Tasks() {
  const [tasks, setTasks]           = useState([]);
  const [projects, setProjects]     = useState([]);
  const [loading, setLoading]       = useState(true);
  const [search, setSearch]         = useState('');
  const [statusFilter, setStatus]   = useState('');
  const [catFilter, setCat]         = useState('');
  const [priorityFilter, setPri]    = useState('');
  const [showFilters, setShowFilters] = useState(false);
  const [editTask, setEditTask]     = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [showNew, setShowNew]       = useState(false);
  const [selected, setSelected]     = useState(new Set());
  const [viewMode, setViewMode]     = useState('grid'); // 'grid' | 'kanban'
  const debouncedSearch = useDebounce(search);

  const load = async () => {
    setLoading(true);
    const p = new URLSearchParams();
    if (debouncedSearch)  p.set('search',   debouncedSearch);
    if (statusFilter)     p.set('status',   statusFilter);
    if (catFilter)        p.set('category', catFilter);
    if (priorityFilter)   p.set('priority', priorityFilter);
    try {
      const [t, pr] = await Promise.all([api.get('/tasks?' + p), api.get('/projects')]);
      setTasks(t); setProjects(pr);
    } finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [debouncedSearch, statusFilter, catFilter, priorityFilter]);

  const handleSave = async (form) => {
    try {
      if (editTask?.id) { await api.put(`/tasks/${editTask.id}`, form); toast.success('Task updated'); }
      else              { await api.post('/tasks', form);               toast.success('Task added');   }
      setEditTask(null); setShowNew(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleDelete = async () => {
    await api.delete(`/tasks/${deleteTask.id}`); toast.success('Deleted');
    setDeleteTask(null); load();
  };

  const toggleFocus = async (task) => { await api.patch(`/tasks/${task.id}/focus`); load(); };

  const toggleSelect = (id) => setSelected(s => {
    const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n;
  });

  const bulkDone = async () => {
    await Promise.all([...selected].map(id => api.patch(`/tasks/${id}/status`, { status: 'Done' })));
    toast.success(`${selected.size} tasks done`);
    setSelected(new Set()); load();
  };

  const hasFilters = statusFilter || catFilter || priorityFilter;

  // Kanban grouping by status
  const KANBAN_COLS = ['Open', 'In Progress', 'Waiting', 'Done'];
  const byStatus = KANBAN_COLS.reduce((acc, s) => {
    acc[s] = tasks.filter(t => t.status === s);
    return acc;
  }, {});

  return (

      {/* Header */}

Tasks

            {/* View toggle */}

              {[{ id:'grid', label:'Grid' }, { id:'kanban', label:'Board' }].map(v => (
                <button key={v.id} onClick={() => setViewMode(v.id)}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
                    viewMode === v.id ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm' : 'text-gray-500'
                  }`}>
                  {v.label}
                </button>
              ))}

            <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">
              <Plus size={14} /> New Task
            </button>

        {/* Search + filter row */}

            <Search size={13} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
            <input className="input pl-8 py-2 text-sm" placeholder="Search tasks…" value={search} onChange={e => setSearch(e.target.value)} />

          <button onClick={() => setShowFilters(!showFilters)}
            className={`btn-secondary flex items-center gap-1.5 py-2 text-sm ${hasFilters ? 'border-primary text-primary' : ''}`}>
            <SlidersHorizontal size={13} />
            {hasFilters ? 'Filtered' : 'Filter'}
          </button>

        {/* Filter chips */}
        {showFilters && (

            <select className="select text-xs py-1.5 w-auto" value={statusFilter} onChange={e => setStatus(e.target.value)}>
              <option value="">All Status</option>
              {STATUSES.map(s => <option key={s}>{s}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={catFilter} onChange={e => setCat(e.target.value)}>
              <option value="">All Categories</option>
              {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={priorityFilter} onChange={e => setPri(e.target.value)}>
              <option value="">All Priorities</option>
              {PRIORITIES.map(p => <option key={p}>{p}</option>)}
            </select>
            {hasFilters && (
              <button onClick={() => { setStatus(''); setCat(''); setPri(''); }}
                className="flex items-center gap-1 text-xs text-primary hover:underline px-2">
                <X size={11} /> Clear
              </button>
            )}

        )}

        {/* Bulk actions */}
        {selected.size > 0 && (

            {selected.size} selected
            <button onClick={bulkDone} className="btn-primary py-1 text-xs flex items-center gap-1">
              <CheckSquare size={11} /> Mark done
            </button>
            <button onClick={() => setSelected(new Set())} className="btn-ghost text-xs">Clear</button>

        )}

      {/* Content area */}
      {loading ? (

          {[...Array(8)].map((_, i) =>
)}

      ) : tasks.length === 0 ? (

          <CheckSquare size={40} className="text-gray-200 dark:text-gray-700" />

No tasks found

          {(search || hasFilters) && (
            <button onClick={() => { setSearch(''); setStatus(''); setCat(''); setPri(''); }} className="btn-secondary text-sm">
              Clear filters
            </button>
          )}

      ) : viewMode === 'grid' ? (
        /* ── GRID view ─────────────────────────────────── */

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

            {tasks.map(task => (

                <input type="checkbox" className="absolute top-3 left-3 z-10 w-3.5 h-3.5 accent-primary cursor-pointer rounded"
                  checked={selected.has(task.id)} onChange={() => toggleSelect(task.id)} />

                  <TaskCard task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />

            ))}

      ) : (
        /* ── KANBAN / BOARD view ────────────────────────── */

          {KANBAN_COLS.map(status => {
            const col = STATUS_COLS.find(c => c.id === status);
            const colTasks = byStatus[status] || [];
            return (

{status}

                    <span className={`badge text-[10px] py-0.5 ${col?.color}`}>{colTasks.length}

                  <button onClick={() => setShowNew(true)}
                    className="w-6 h-6 rounded-lg bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 flex items-center justify-center text-gray-400 hover:text-primary hover:border-primary transition-all">
                    <Plus size={12} />
                  </button>

                  {colTasks.map(task => (
                    <TaskCard key={task.id} task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />
                  ))}
                  {colTasks.length === 0 && (

No tasks

                  )}

            );
          })}

      )}

      {(showNew || editTask) && (
        <TaskModal task={editTask} projects={projects} onSave={handleSave} onClose={() => { setShowNew(false); setEditTask(null); }} />
      )}
      {deleteTask && (
        <ConfirmDialog title="Delete task?" message={`"${deleteTask.title}"`} onConfirm={handleDelete} onCancel={() => setDeleteTask(null)} />
      )}

  );
}

-import { CATEGORIES, STATUSES, PRIORITIES } from '../utils';

+import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass, formatDate, isOverdue } from '../utils';


Now replace the grid card rendering to have the checkbox inside:


            {tasks.map(task => (

                <input type="checkbox" className="absolute top-3 left-3 z-10 w-3.5 h-3.5 accent-primary cursor-pointer rounded"
                  checked={selected.has(task.id)} onChange={() => toggleSelect(task.id)} />

                  <TaskCard task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />

            ))}

            {tasks.map(task => {
              const overdue = isOverdue(task.due_date) && task.status !== 'Done';
              const isDone = task.status === 'Done';
              const isSelected = selected.has(task.id);
              return (

 setEditTask(task)}
                >

                      {/* Green checkbox inside card */}
                      <button
                        onClick={e => { e.stopPropagation(); toggleSelect(task.id); }}
                        className={`shrink-0 mt-0.5 w-5 h-5 rounded-md border-2 flex items-center justify-center transition-all ${
                          isSelected || isDone
                            ? 'bg-green-500 border-green-500 shadow-sm'
                            : 'border-gray-300 dark:border-gray-600 hover:border-green-400'
                        }`}
                      >
                        {(isSelected || isDone) && <Check size={11} className="text-white" />}
                      </button>

                        <p className={`text-sm font-semibold leading-snug ${isDone ? 'line-through text-gray-400' : 'text-gray-800 dark:text-gray-100'}`}>
                          {task.title}

                        {task.notes && (

{task.notes}

                        )}

                          <span className={`badge text-[10px] py-0.5 ${getPriorityClass(task.priority)}`}>{task.priority}
                          <span className={`badge text-[10px] py-0.5 ${getCategoryClass(task.category)}`}>
                            {CATEGORIES[task.category]?.label?.split(' ')[0] || task.category}

                          <span className={`badge text-[10px] py-0.5 ${getStatusClass(task.status)}`}>{task.status}

                        {(task.assignee || task.due_date) && (

                            {task.assignee && (

                                <User size={10} />{task.assignee}

                            )}
                            {task.due_date && (
                              <span className={`flex items-center gap-1 ${overdue ? 'text-red-500 font-medium' : ''}`}>
                                {overdue && <AlertTriangle size={10} />}
                                <Calendar size={10} />{formatDate(task.due_date)}

                            )}

                        )}

              );
            })}


            {tasks.map(task => {
              const overdue = isOverdue(task.due_date) && task.status !== 'Done';
              const isDone = task.status === 'Done';
              const isSelected = selected.has(task.id);
              return (

 setEditTask(task)}
                >

                      {/* Green checkbox inside card */}
                      <button
                        onClick={e => { e.stopPropagation(); toggleSelect(task.id); }}
                        className={`shrink-0 mt-0.5 w-5 h-5 rounded-md border-2 flex items-center justify-center transition-all ${
                          isSelected || isDone
                            ? 'bg-green-500 border-green-500 shadow-sm'
                            : 'border-gray-300 dark:border-gray-600 hover:border-green-400'
                        }`}
                      >
                        {(isSelected || isDone) && <Check size={11} className="text-white" />}
                      </button>

                        <p className={`text-sm font-semibold leading-snug ${isDone ? 'line-through text-gray-400' : 'text-gray-800 dark:text-gray-100'}`}>
                          {task.title}

                        {task.notes && (

{task.notes}

                        )}

                          <span className={`badge text-[10px] py-0.5 ${getPriorityClass(task.priority)}`}>{task.priority}
                          <span className={`badge text-[10px] py-0.5 ${getCategoryClass(task.category)}`}>
                            {CATEGORIES[task.category]?.label?.split(' ')[0] || task.category}

                          <span className={`badge text-[10px] py-0.5 ${getStatusClass(task.status)}`}>{task.status}

                        {(task.assignee || task.due_date) && (

                            {task.assignee && (

                                <User size={10} />{task.assignee}

                            )}
                            {task.due_date && (
                              <span className={`flex items-center gap-1 ${overdue ? 'text-red-500 font-medium' : ''}`}>
                                {overdue && <AlertTriangle size={10} />}
                                <Calendar size={10} />{formatDate(task.due_date)}

                            )}

                        )}

              );
            })}

import { useState, useEffect, useRef } from 'react';
import { Plus, Search, SlidersHorizontal, CheckSquare, X, Check, Calendar, User, AlertTriangle } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import TaskCard from './TaskCard';
import TaskModal from './TaskModal';
import ConfirmDialog from './ConfirmDialog';
import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass, formatDate, isOverdue } from '../utils';

const PRIORITY_BORDER = {
  Urgent: 'border-l-red-500',
  High:   'border-l-amber-400',
  Medium: 'border-l-blue-400',
  Low:    'border-l-green-400',
};

function useDebounce(v, d = 300) {
  const [dv, setDv] = useState(v);
  useEffect(() => { const t = setTimeout(() => setDv(v), d); return () => clearTimeout(t); }, [v, d]);
  return dv;
}

// Status columns for horizontal kanban-style layout
const STATUS_COLS = [
  { id: '',          label: 'All',         color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'Open',      label: 'Open',        color: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' },
  { id: 'In Progress',label:'In Progress', color: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' },
  { id: 'Waiting',   label: 'Waiting',     color: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300' },
  { id: 'Done',      label: 'Done',        color: 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300' },
];

export default function Tasks() {
  const [tasks, setTasks]           = useState([]);
  const [projects, setProjects]     = useState([]);
  const [loading, setLoading]       = useState(true);
  const [search, setSearch]         = useState('');
  const [statusFilter, setStatus]   = useState('');
  const [catFilter, setCat]         = useState('');
  const [priorityFilter, setPri]    = useState('');
  const [showFilters, setShowFilters] = useState(false);
  const [editTask, setEditTask]     = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [showNew, setShowNew]       = useState(false);
  const [selected, setSelected]     = useState(new Set());
  const [viewMode, setViewMode]     = useState('grid'); // 'grid' | 'kanban'
  const debouncedSearch = useDebounce(search);

  const load = async () => {
    setLoading(true);
    const p = new URLSearchParams();
    if (debouncedSearch)  p.set('search',   debouncedSearch);
    if (statusFilter)     p.set('status',   statusFilter);
    if (catFilter)        p.set('category', catFilter);
    if (priorityFilter)   p.set('priority', priorityFilter);
    try {
      const [t, pr] = await Promise.all([api.get('/tasks?' + p), api.get('/projects')]);
      setTasks(t); setProjects(pr);
    } finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [debouncedSearch, statusFilter, catFilter, priorityFilter]);

  const handleSave = async (form) => {
    try {
      if (editTask?.id) { await api.put(`/tasks/${editTask.id}`, form); toast.success('Task updated'); }
      else              { await api.post('/tasks', form);               toast.success('Task added');   }
      setEditTask(null); setShowNew(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleDelete = async () => {
    await api.delete(`/tasks/${deleteTask.id}`); toast.success('Deleted');
    setDeleteTask(null); load();
  };

  const toggleFocus = async (task) => { await api.patch(`/tasks/${task.id}/focus`); load(); };

  const toggleSelect = (id) => setSelected(s => {
    const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n;
  });

  const bulkDone = async () => {
    await Promise.all([...selected].map(id => api.patch(`/tasks/${id}/status`, { status: 'Done' })));
    toast.success(`${selected.size} tasks done`);
    setSelected(new Set()); load();
  };

  const hasFilters = statusFilter || catFilter || priorityFilter;

  // Kanban grouping by status
  const KANBAN_COLS = ['Open', 'In Progress', 'Waiting', 'Done'];
  const byStatus = KANBAN_COLS.reduce((acc, s) => {
    acc[s] = tasks.filter(t => t.status === s);
    return acc;
  }, {});

  return (

      {/* Header */}

Tasks

            {/* View toggle */}

              {[{ id:'grid', label:'Grid' }, { id:'kanban', label:'Board' }].map(v => (
                <button key={v.id} onClick={() => setViewMode(v.id)}
                  className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
                    viewMode === v.id ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm' : 'text-gray-500'
                  }`}>
                  {v.label}
                </button>
              ))}

            <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">
              <Plus size={14} /> New Task
            </button>

        {/* Search + filter row */}

            <Search size={13} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
            <input className="input pl-8 py-2 text-sm" placeholder="Search tasks…" value={search} onChange={e => setSearch(e.target.value)} />

          <button onClick={() => setShowFilters(!showFilters)}
            className={`btn-secondary flex items-center gap-1.5 py-2 text-sm ${hasFilters ? 'border-primary text-primary' : ''}`}>
            <SlidersHorizontal size={13} />
            {hasFilters ? 'Filtered' : 'Filter'}
          </button>

        {/* Filter chips */}
        {showFilters && (

            <select className="select text-xs py-1.5 w-auto" value={statusFilter} onChange={e => setStatus(e.target.value)}>
              <option value="">All Status</option>
              {STATUSES.map(s => <option key={s}>{s}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={catFilter} onChange={e => setCat(e.target.value)}>
              <option value="">All Categories</option>
              {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
            </select>
            <select className="select text-xs py-1.5 w-auto" value={priorityFilter} onChange={e => setPri(e.target.value)}>
              <option value="">All Priorities</option>
              {PRIORITIES.map(p => <option key={p}>{p}</option>)}
            </select>
            {hasFilters && (
              <button onClick={() => { setStatus(''); setCat(''); setPri(''); }}
                className="flex items-center gap-1 text-xs text-primary hover:underline px-2">
                <X size={11} /> Clear
              </button>
            )}

        )}

        {/* Bulk actions */}
        {selected.size > 0 && (

            {selected.size} selected
            <button onClick={bulkDone} className="btn-primary py-1 text-xs flex items-center gap-1">
              <CheckSquare size={11} /> Mark done
            </button>
            <button onClick={() => setSelected(new Set())} className="btn-ghost text-xs">Clear</button>

        )}

      {/* Content area */}
      {loading ? (

          {[...Array(8)].map((_, i) =>
)}

      ) : tasks.length === 0 ? (

          <CheckSquare size={40} className="text-gray-200 dark:text-gray-700" />

No tasks found

          {(search || hasFilters) && (
            <button onClick={() => { setSearch(''); setStatus(''); setCat(''); setPri(''); }} className="btn-secondary text-sm">
              Clear filters
            </button>
          )}

      ) : viewMode === 'grid' ? (
        /* ── GRID view ─────────────────────────────────── */

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

            {tasks.map(task => (

                <input type="checkbox" className="absolute top-3 left-3 z-10 w-3.5 h-3.5 accent-primary cursor-pointer rounded"
                  checked={selected.has(task.id)} onChange={() => toggleSelect(task.id)} />

                  <TaskCard task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />

            ))}

      ) : (
        /* ── KANBAN / BOARD view ────────────────────────── */

          {KANBAN_COLS.map(status => {
            const col = STATUS_COLS.find(c => c.id === status);
            const colTasks = byStatus[status] || [];
            return (

{status}

                    <span className={`badge text-[10px] py-0.5 ${col?.color}`}>{colTasks.length}

                  <button onClick={() => setShowNew(true)}
                    className="w-6 h-6 rounded-lg bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 flex items-center justify-center text-gray-400 hover:text-primary hover:border-primary transition-all">
                    <Plus size={12} />
                  </button>

                  {colTasks.map(task => (
                    <TaskCard key={task.id} task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />
                  ))}
                  {colTasks.length === 0 && (

No tasks

                  )}

            );
          })}

      )}

      {(showNew || editTask) && (
        <TaskModal task={editTask} projects={projects} onSave={handleSave} onClose={() => { setShowNew(false); setEditTask(null); }} />
      )}
      {deleteTask && (
        <ConfirmDialog title="Delete task?" message={`"${deleteTask.title}"`} onConfirm={handleDelete} onCancel={() => setDeleteTask(null)} />
      )}

  );
}

<div className="flex-1 overflow-y-auto p-4">

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">

-              <div key={task.id} className="relative">

-                <input type="checkbox" className="absolute top-3 left-3 z-10 w-3.5 h-3.5 accent-primary cursor-pointer rounded"

-                  checked={selected.has(task.id)} onChange={() => toggleSelect(task.id)} />

-                  <TaskCard task={task} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />

+              const overdue = isOverdue(task.due_date) && task.status !== 'Done';

+              const isDone = task.status === 'Done';

+              const isSelected = selected.has(task.id);

+                  className={`bg-white dark:bg-gray-900 rounded-xl border border-gray-100 dark:border-gray-800 border-l-4 ${PRIORITY_BORDER[task.priority] || 'border-l-gray-200'} shadow-card hover:shadow-hover transition-all duration-150 group cursor-pointer ${isDone ? 'opacity-60' : ''}`}

+                  onClick={() => setEditTask(task)}

+                  <div className="p-3">

+                    <div className="flex items-start gap-2.5">

+                      {/* Green checkbox inside card */}

+                        onClick={e => { e.stopPropagation(); toggleSelect(task.id); }}

+                        className={`shrink-0 mt-0.5 w-5 h-5 rounded-md border-2 flex items-center justify-center transition-all ${

+                          isSelected || isDone

+                            ? 'bg-green-500 border-green-500 shadow-sm'

+                            : 'border-gray-300 dark:border-gray-600 hover:border-green-400'

+                        {(isSelected || isDone) && <Check size={11} className="text-white" />}

+                      <div className="flex-1 min-w-0">

+                        <p className={`text-sm font-semibold leading-snug ${isDone ? 'line-through text-gray-400' : 'text-gray-800 dark:text-gray-100'}`}>

+                        {task.notes && (

+                        <div className="flex flex-wrap gap-1 mt-2">

+                          <span className={`badge text-[10px] py-0.5 ${getPriorityClass(task.priority)}`}>{task.priority}

+                          <span className={`badge text-[10px] py-0.5 ${getCategoryClass(task.category)}`}>

+                            {CATEGORIES[task.category]?.label?.split(' ')[0] || task.category}

+                          <span className={`badge text-[10px] py-0.5 ${getStatusClass(task.status)}`}>{task.status}

+                        {(task.assignee || task.due_date) && (

+                          <div className="flex items-center gap-3 mt-2 pt-2 border-t border-gray-100 dark:border-gray-800 text-xs text-gray-400">

+                            {task.assignee && (

+                              <span className="flex items-center gap-1">

+                                <User size={10} />{task.assignee}

+                            {task.due_date && (

+                              <span className={`flex items-center gap-1 ${overdue ? 'text-red-500 font-medium' : ''}`}>

+                                {overdue && <AlertTriangle size={10} />}

+                                <Calendar size={10} />{formatDate(task.due_date)}


Now update Sidebar.jsx — rename People → My Team, add Projects and History to NAV:


  CalendarDays, PenLine, FolderKanban, CheckSquare, FileText,
  Bell, Users, BarChart2, Search, Moon, Sun, Zap,
  ChevronDown, ChevronRight, Settings, LogOut

  CalendarDays, PenLine, FolderKanban, CheckSquare, FileText,
  Bell, Users, BarChart2, Search, Moon, Sun, Zap,
  ChevronDown, ChevronRight, Settings, LogOut, History


The file /Users/khalidbinkalban/my-workspace/client/src/components/Sidebar.jsx has been updated successfully.

  CalendarDays, PenLine, FolderKanban, CheckSquare, FileText,
  Bell, Users, BarChart2, Search, Moon, Sun, Zap,
  ChevronDown, ChevronRight, Settings, LogOut, History

import { useState, useEffect } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import {
  CalendarDays, PenLine, FolderKanban, CheckSquare, FileText,
  Bell, Users, BarChart2, Search, Moon, Sun, Zap,
  ChevronDown, ChevronRight, Settings, LogOut
} from 'lucide-react';
import { useApp } from '../App';
import api from '../api';

const CATEGORY_DOT = {
  ai:        'bg-blue-500',
  vendor:    'bg-purple-500',
  gov:       'bg-amber-500',
  people:    'bg-teal-500',
  events:    'bg-orange-500',
  strategic: 'bg-green-500',
  adhoc:     'bg-red-500',
};
const CATEGORY_LABEL = {
  ai:        'AI & Strategy',
  vendor:    'Vendors',
  gov:       'Governance',
  people:    'People',
  events:    'Events',
  strategic: 'Strategic',
  adhoc:     'CAIO / EVP',
};

const NAV = [
  { to: '/today',         icon: CalendarDays, label: 'Dashboard'     },
  { to: '/inbox',         icon: PenLine,      label: 'Quick Note'    },
  { to: '/tasks',         icon: CheckSquare,  label: 'Tasks'         },
  { to: '/notes',         icon: FileText,     label: 'Notes'         },
  { to: '/follow-ups',    icon: Bell,         label: 'Follow-ups'    },
  { to: '/people',        icon: Users,        label: 'People'        },
  { to: '/weekly-review', icon: BarChart2,    label: 'Weekly Review' },
];

export default function Sidebar({ onSearchOpen }) {
  const { darkMode, setDarkMode } = useApp();
  const [projects, setProjects] = useState([]);
  const [openCats, setOpenCats] = useState({ ai: true, vendor: true });
  const navigate = useNavigate();

  useEffect(() => {
    api.get('/projects').then(setProjects).catch(() => {});
  }, []);

  const grouped = projects.reduce((acc, p) => {
    if (!acc[p.category]) acc[p.category] = [];
    acc[p.category].push(p);
    return acc;
  }, {});

  const toggleCat = (cat) => setOpenCats(s => ({ ...s, [cat]: !s[cat] }));

  return (

      {/* Logo */}

            <Zap size={15} className="text-white" />

My Workspace

DEWA · Senior Manager

      {/* Search */}
      <button
        onClick={onSearchOpen}
        className="mx-3 mt-3 flex items-center gap-2 px-3 py-2 rounded-xl bg-gray-50 dark:bg-gray-800 text-gray-400 text-xs hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors group border border-gray-100 dark:border-gray-700"
      >
        <Search size={12} />
        Search…
        ⌘K
      </button>

      {/* Main nav */}

        {NAV.map(({ to, icon: Icon, label }) => (
          <NavLink key={to} to={to} className={({ isActive }) =>
            isActive ? 'nav-item-active flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium bg-primary/10 text-primary'
                     : 'nav-item flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 hover:text-gray-900 dark:hover:text-white transition-all'
          }>
            <Icon size={15} />
            {label}
          </NavLink>
        ))}

      {/* Projects grouped */}

Projects

        {Object.entries(grouped).map(([cat, items]) => (

            <button
              onClick={() => toggleCat(cat)}
              className="flex items-center gap-2 w-full px-2 py-1.5 text-xs font-semibold text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white transition-colors rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800"
            >
              <div className={`w-2 h-2 rounded-full shrink-0 ${CATEGORY_DOT[cat]}`} />
              {CATEGORY_LABEL[cat]}
              {items.length}
              {openCats[cat] ? <ChevronDown size={11} /> : <ChevronRight size={11} />}
            </button>
            {openCats[cat] && (

                {items.slice(0, 5).map(p => (
                  <button
                    key={p.id}
                    onClick={() => navigate(`/projects/${p.id}`)}
                    className="flex items-center gap-1.5 w-full px-2 py-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg transition-colors text-left"
                  >
                    <div className={`w-1.5 h-1.5 rounded-full shrink-0 ${CATEGORY_DOT[cat]} opacity-60`} />
                    {p.name}
                  </button>
                ))}
                {items.length > 5 && (
                  <button onClick={() => navigate('/projects')} className="text-[10px] text-gray-400 hover:text-primary px-2 py-0.5 transition-colors">
                    +{items.length - 5} more
                  </button>
                )}

            )}

        ))}

      {/* Bottom */}

        <button
          onClick={() => setDarkMode(!darkMode)}
          className="flex items-center gap-2 w-full px-3 py-2 rounded-xl text-xs text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
        >
          {darkMode ? <Sun size={13} /> : <Moon size={13} />}
          {darkMode ? 'Light mode' : 'Dark mode'}
        </button>

  );
}

-  ChevronDown, ChevronRight, Settings, LogOut

+  ChevronDown, ChevronRight, Settings, LogOut, History


const NAV = [
  { to: '/today',         icon: CalendarDays, label: 'Dashboard'     },
  { to: '/inbox',         icon: PenLine,      label: 'Quick Note'    },
  { to: '/tasks',         icon: CheckSquare,  label: 'Tasks'         },
  { to: '/notes',         icon: FileText,     label: 'Notes'         },
  { to: '/follow-ups',    icon: Bell,         label: 'Follow-ups'    },
  { to: '/people',        icon: Users,        label: 'People'        },
  { to: '/weekly-review', icon: BarChart2,    label: 'Weekly Review' },
];

const NAV = [
  { to: '/today',         icon: CalendarDays, label: 'Dashboard'     },
  { to: '/inbox',         icon: PenLine,      label: 'Quick Note'    },
  { to: '/projects',      icon: FolderKanban, label: 'Projects'      },
  { to: '/tasks',         icon: CheckSquare,  label: 'Tasks'         },
  { to: '/notes',         icon: FileText,     label: 'Notes'         },
  { to: '/follow-ups',    icon: Bell,         label: 'Follow-ups'    },
  { to: '/people',        icon: Users,        label: 'My Team'       },
  { to: '/weekly-review', icon: BarChart2,    label: 'Weekly Review' },
  { to: '/history',       icon: History,      label: 'History'       },
];


const NAV = [
  { to: '/today',         icon: CalendarDays, label: 'Dashboard'     },
  { to: '/inbox',         icon: PenLine,      label: 'Quick Note'    },
  { to: '/projects',      icon: FolderKanban, label: 'Projects'      },
  { to: '/tasks',         icon: CheckSquare,  label: 'Tasks'         },
  { to: '/notes',         icon: FileText,     label: 'Notes'         },
  { to: '/follow-ups',    icon: Bell,         label: 'Follow-ups'    },
  { to: '/people',        icon: Users,        label: 'My Team'       },
  { to: '/weekly-review', icon: BarChart2,    label: 'Weekly Review' },
  { to: '/history',       icon: History,      label: 'History'       },
];

import { useState, useEffect } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import {
  CalendarDays, PenLine, FolderKanban, CheckSquare, FileText,
  Bell, Users, BarChart2, Search, Moon, Sun, Zap,
  ChevronDown, ChevronRight, Settings, LogOut, History
} from 'lucide-react';
import { useApp } from '../App';
import api from '../api';

const CATEGORY_DOT = {
  ai:        'bg-blue-500',
  vendor:    'bg-purple-500',
  gov:       'bg-amber-500',
  people:    'bg-teal-500',
  events:    'bg-orange-500',
  strategic: 'bg-green-500',
  adhoc:     'bg-red-500',
};
const CATEGORY_LABEL = {
  ai:        'AI & Strategy',
  vendor:    'Vendors',
  gov:       'Governance',
  people:    'People',
  events:    'Events',
  strategic: 'Strategic',
  adhoc:     'CAIO / EVP',
};

const NAV = [
  { to: '/today',         icon: CalendarDays, label: 'Dashboard'     },
  { to: '/inbox',         icon: PenLine,      label: 'Quick Note'    },
  { to: '/tasks',         icon: CheckSquare,  label: 'Tasks'         },
  { to: '/notes',         icon: FileText,     label: 'Notes'         },
  { to: '/follow-ups',    icon: Bell,         label: 'Follow-ups'    },
  { to: '/people',        icon: Users,        label: 'People'        },
  { to: '/weekly-review', icon: BarChart2,    label: 'Weekly Review' },
];

export default function Sidebar({ onSearchOpen }) {
  const { darkMode, setDarkMode } = useApp();
  const [projects, setProjects] = useState([]);
  const [openCats, setOpenCats] = useState({ ai: true, vendor: true });
  const navigate = useNavigate();

  useEffect(() => {
    api.get('/projects').then(setProjects).catch(() => {});
  }, []);

  const grouped = projects.reduce((acc, p) => {
    if (!acc[p.category]) acc[p.category] = [];
    acc[p.category].push(p);
    return acc;
  }, {});

  const toggleCat = (cat) => setOpenCats(s => ({ ...s, [cat]: !s[cat] }));

  return (

      {/* Logo */}

            <Zap size={15} className="text-white" />

My Workspace

DEWA · Senior Manager

      {/* Search */}
      <button
        onClick={onSearchOpen}
        className="mx-3 mt-3 flex items-center gap-2 px-3 py-2 rounded-xl bg-gray-50 dark:bg-gray-800 text-gray-400 text-xs hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors group border border-gray-100 dark:border-gray-700"
      >
        <Search size={12} />
        Search…
        ⌘K
      </button>

      {/* Main nav */}

        {NAV.map(({ to, icon: Icon, label }) => (
          <NavLink key={to} to={to} className={({ isActive }) =>
            isActive ? 'nav-item-active flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium bg-primary/10 text-primary'
                     : 'nav-item flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 hover:text-gray-900 dark:hover:text-white transition-all'
          }>
            <Icon size={15} />
            {label}
          </NavLink>
        ))}

      {/* Projects grouped */}

Projects

        {Object.entries(grouped).map(([cat, items]) => (

            <button
              onClick={() => toggleCat(cat)}
              className="flex items-center gap-2 w-full px-2 py-1.5 text-xs font-semibold text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white transition-colors rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800"
            >
              <div className={`w-2 h-2 rounded-full shrink-0 ${CATEGORY_DOT[cat]}`} />
              {CATEGORY_LABEL[cat]}
              {items.length}
              {openCats[cat] ? <ChevronDown size={11} /> : <ChevronRight size={11} />}
            </button>
            {openCats[cat] && (

                {items.slice(0, 5).map(p => (
                  <button
                    key={p.id}
                    onClick={() => navigate(`/projects/${p.id}`)}
                    className="flex items-center gap-1.5 w-full px-2 py-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg transition-colors text-left"
                  >
                    <div className={`w-1.5 h-1.5 rounded-full shrink-0 ${CATEGORY_DOT[cat]} opacity-60`} />
                    {p.name}
                  </button>
                ))}
                {items.length > 5 && (
                  <button onClick={() => navigate('/projects')} className="text-[10px] text-gray-400 hover:text-primary px-2 py-0.5 transition-colors">
                    +{items.length - 5} more
                  </button>
                )}

            )}

        ))}

      {/* Bottom */}

        <button
          onClick={() => setDarkMode(!darkMode)}
          className="flex items-center gap-2 w-full px-3 py-2 rounded-xl text-xs text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
        >
          {darkMode ? <Sun size={13} /> : <Moon size={13} />}
          {darkMode ? 'Light mode' : 'Dark mode'}
        </button>

  );
}

+  { to: '/projects',      icon: FolderKanban, label: 'Projects'      },

-  { to: '/people',        icon: Users,        label: 'People'        },

+  { to: '/people',        icon: Users,        label: 'My Team'       },

+  { to: '/history',       icon: History,      label: 'History'       },


Now update BottomNav:


import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2 } from 'lucide-react';

const MAIN = [
  { to: '/today',    icon: CalendarDays, label: 'Today'      },
  { to: '/inbox',    icon: PenLine,      label: 'Quick Note' },
  { to: '/projects', icon: FolderKanban, label: 'Projects'   },
  { to: '/tasks',    icon: CheckSquare,  label: 'Tasks'      },
];

const MORE = [
  { to: '/notes',        icon: FileText,  label: 'Notes'        },
  { to: '/follow-ups',   icon: Bell,      label: 'Follow-ups'   },
  { to: '/people',       icon: Users,     label: 'People'       },
  { to: '/weekly-review',icon: BarChart2, label: 'Weekly Review'},
];

import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2, History } from 'lucide-react';

const MAIN = [
  { to: '/today',    icon: CalendarDays, label: 'Today'      },
  { to: '/inbox',    icon: PenLine,      label: 'Quick Note' },
  { to: '/projects', icon: FolderKanban, label: 'Projects'   },
  { to: '/tasks',    icon: CheckSquare,  label: 'Tasks'      },
];

const MORE = [
  { to: '/notes',        icon: FileText,  label: 'Notes'        },
  { to: '/follow-ups',   icon: Bell,      label: 'Follow-ups'   },
  { to: '/people',       icon: Users,     label: 'My Team'      },
  { to: '/weekly-review',icon: BarChart2, label: 'Weekly Review'},
  { to: '/history',      icon: History,   label: 'History'      },
];


The file /Users/khalidbinkalban/my-workspace/client/src/components/BottomNav.jsx has been updated successfully.

import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2, History } from 'lucide-react';

const MAIN = [
  { to: '/today',    icon: CalendarDays, label: 'Today'      },
  { to: '/inbox',    icon: PenLine,      label: 'Quick Note' },
  { to: '/projects', icon: FolderKanban, label: 'Projects'   },
  { to: '/tasks',    icon: CheckSquare,  label: 'Tasks'      },
];

const MORE = [
  { to: '/notes',        icon: FileText,  label: 'Notes'        },
  { to: '/follow-ups',   icon: Bell,      label: 'Follow-ups'   },
  { to: '/people',       icon: Users,     label: 'My Team'      },
  { to: '/weekly-review',icon: BarChart2, label: 'Weekly Review'},
  { to: '/history',      icon: History,   label: 'History'      },
];

import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2 } from 'lucide-react';

const MAIN = [
  { to: '/today',    icon: CalendarDays, label: 'Today'      },
  { to: '/inbox',    icon: PenLine,      label: 'Quick Note' },
  { to: '/projects', icon: FolderKanban, label: 'Projects'   },
  { to: '/tasks',    icon: CheckSquare,  label: 'Tasks'      },
];

const MORE = [
  { to: '/notes',        icon: FileText,  label: 'Notes'        },
  { to: '/follow-ups',   icon: Bell,      label: 'Follow-ups'   },
  { to: '/people',       icon: Users,     label: 'People'       },
  { to: '/weekly-review',icon: BarChart2, label: 'Weekly Review'},
];

export default function BottomNav() {
  const [moreOpen, setMoreOpen] = useState(false);

  return (
    <>
      {/* More drawer */}
      {moreOpen && (

 setMoreOpen(false)}>

 e.stopPropagation()}
          >

              {MORE.map(({ to, icon: Icon, label }) => (
                <NavLink
                  key={to}
                  to={to}
                  onClick={() => setMoreOpen(false)}
                  className={({ isActive }) =>
                    `flex flex-col items-center gap-1 py-2 px-1 rounded-lg text-center ${
                      isActive ? 'text-primary' : 'text-gray-500 dark:text-gray-400'
                    }`
                  }
                >
                  <Icon size={20} />
                  {label}
                </NavLink>
              ))}

      )}

      {/* Bottom bar */}

        {MAIN.map(({ to, icon: Icon, label }) => (
          <NavLink
            key={to}
            to={to}
            className={({ isActive }) =>
              `flex-1 flex flex-col items-center justify-center py-2 gap-1 text-[10px] font-medium transition-colors ${
                isActive ? 'text-primary' : 'text-gray-500 dark:text-gray-400'
              }`
            }
          >
            <Icon size={20} />
            {label}
          </NavLink>
        ))}
        <button
          onClick={() => setMoreOpen(!moreOpen)}
          className={`flex-1 flex flex-col items-center justify-center py-2 gap-1 text-[10px] font-medium transition-colors ${
            moreOpen ? 'text-primary' : 'text-gray-500 dark:text-gray-400'
          }`}
        >
          {moreOpen ? <X size={20} /> : <MoreHorizontal size={20} />}
          More
        </button>

    </>
  );
}

-import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2 } from 'lucide-react';

+import { CalendarDays, PenLine, FolderKanban, CheckSquare, MoreHorizontal, X, FileText, Bell, Users, BarChart2, History } from 'lucide-react';

-  { to: '/people',       icon: Users,     label: 'People'       },

+  { to: '/people',       icon: Users,     label: 'My Team'      },

+  { to: '/history',      icon: History,   label: 'History'      },


Now add the History route to App.jsx:


import WeeklyReview from './components/WeeklyReview';

import WeeklyReview from './components/WeeklyReview';
import History from './components/History';


The file /Users/khalidbinkalban/my-workspace/client/src/App.jsx has been updated successfully.

import WeeklyReview from './components/WeeklyReview';
import History from './components/History';

import { useState, useEffect, createContext, useContext } from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import Sidebar from './components/Sidebar';
import BottomNav from './components/BottomNav';
import RightPanel from './components/RightPanel';
import Search from './components/Search';
import Today from './components/Today';
import Inbox from './components/Inbox';
import Projects from './components/Projects';
import ProjectDetail from './components/ProjectDetail';
import Tasks from './components/Tasks';
import Notes from './components/Notes';
import FollowUps from './components/FollowUps';
import People from './components/People';
import WeeklyReview from './components/WeeklyReview';
import { Toaster } from 'react-hot-toast';

export const AppContext = createContext({});
export const useApp = () => useContext(AppContext);

// Pages that show the right panel
const RIGHT_PANEL_ROUTES = ['/today', '/'];

export default function App() {
  const [darkMode, setDarkMode] = useState(() => localStorage.getItem('darkMode') === 'true');
  const [searchOpen, setSearchOpen] = useState(false);

  useEffect(() => {
    document.documentElement.classList.toggle('dark', darkMode);
    localStorage.setItem('darkMode', darkMode);
  }, [darkMode]);

  useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setSearchOpen(true); }
      if (e.key === 'Escape') setSearchOpen(false);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return (
    <AppContext.Provider value={{ darkMode, setDarkMode, setSearchOpen }}>
      <BrowserRouter>
        <div className="flex h-screen overflow-hidden bg-[#F0F2F5] dark:bg-gray-950">
          {/* Left sidebar */}
          <Sidebar onSearchOpen={() => setSearchOpen(true)} />

          {/* Main content */}
          <main className="flex-1 overflow-y-auto pb-20 md:pb-0 min-w-0">
            <Routes>
              <Route path="/"               element={<Navigate to="/today" replace />} />
              <Route path="/today"          element={<Today />} />
              <Route path="/inbox"          element={<Inbox />} />
              <Route path="/projects"       element={<Projects />} />
              <Route path="/projects/:id"   element={<ProjectDetail />} />
              <Route path="/tasks"          element={<Tasks />} />
              <Route path="/notes"          element={<Notes />} />
              <Route path="/follow-ups"     element={<FollowUps />} />
              <Route path="/people"         element={<People />} />
              <Route path="/weekly-review"  element={<WeeklyReview />} />
            </Routes>
          </main>

          {/* Right executive panel (Today only, desktop XL) */}
          <Routes>
            <Route path="/"      element={<RightPanel />} />
            <Route path="/today" element={<RightPanel />} />
          </Routes>

          {/* Mobile bottom nav */}
          <BottomNav />

          {/* Search overlay */}
          {searchOpen && <Search onClose={() => setSearchOpen(false)} />}
        </div>

        <Toaster
          position="top-right"
          toastOptions={{
            duration: 3000,
            style: { borderRadius: '12px', fontSize: '13px', fontFamily: 'Inter, sans-serif' },
          }}
        />
      </BrowserRouter>
    </AppContext.Provider>
  );
}

+import History from './components/History';


<Route path="/weekly-review"  element={<WeeklyReview />} />

              <Route path="/weekly-review"  element={<WeeklyReview />} />
              <Route path="/history"        element={<History />} />


              <Route path="/weekly-review"  element={<WeeklyReview />} />
              <Route path="/history"        element={<History />} />

import { useState, useEffect, createContext, useContext } from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import Sidebar from './components/Sidebar';
import BottomNav from './components/BottomNav';
import RightPanel from './components/RightPanel';
import Search from './components/Search';
import Today from './components/Today';
import Inbox from './components/Inbox';
import Projects from './components/Projects';
import ProjectDetail from './components/ProjectDetail';
import Tasks from './components/Tasks';
import Notes from './components/Notes';
import FollowUps from './components/FollowUps';
import People from './components/People';
import WeeklyReview from './components/WeeklyReview';
import History from './components/History';
import { Toaster } from 'react-hot-toast';

export const AppContext = createContext({});
export const useApp = () => useContext(AppContext);

// Pages that show the right panel
const RIGHT_PANEL_ROUTES = ['/today', '/'];

export default function App() {
  const [darkMode, setDarkMode] = useState(() => localStorage.getItem('darkMode') === 'true');
  const [searchOpen, setSearchOpen] = useState(false);

  useEffect(() => {
    document.documentElement.classList.toggle('dark', darkMode);
    localStorage.setItem('darkMode', darkMode);
  }, [darkMode]);

  useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setSearchOpen(true); }
      if (e.key === 'Escape') setSearchOpen(false);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return (
    <AppContext.Provider value={{ darkMode, setDarkMode, setSearchOpen }}>
      <BrowserRouter>
        <div className="flex h-screen overflow-hidden bg-[#F0F2F5] dark:bg-gray-950">
          {/* Left sidebar */}
          <Sidebar onSearchOpen={() => setSearchOpen(true)} />

          {/* Main content */}
          <main className="flex-1 overflow-y-auto pb-20 md:pb-0 min-w-0">
            <Routes>
              <Route path="/"               element={<Navigate to="/today" replace />} />
              <Route path="/today"          element={<Today />} />
              <Route path="/inbox"          element={<Inbox />} />
              <Route path="/projects"       element={<Projects />} />
              <Route path="/projects/:id"   element={<ProjectDetail />} />
              <Route path="/tasks"          element={<Tasks />} />
              <Route path="/notes"          element={<Notes />} />
              <Route path="/follow-ups"     element={<FollowUps />} />
              <Route path="/people"         element={<People />} />
              <Route path="/weekly-review"  element={<WeeklyReview />} />
            </Routes>
          </main>

          {/* Right executive panel (Today only, desktop XL) */}
          <Routes>
            <Route path="/"      element={<RightPanel />} />
            <Route path="/today" element={<RightPanel />} />
          </Routes>

          {/* Mobile bottom nav */}
          <BottomNav />

          {/* Search overlay */}
          {searchOpen && <Search onClose={() => setSearchOpen(false)} />}
        </div>

        <Toaster
          position="top-right"
          toastOptions={{
            duration: 3000,
            style: { borderRadius: '12px', fontSize: '13px', fontFamily: 'Inter, sans-serif' },
          }}
        />
      </BrowserRouter>
    </AppContext.Provider>
  );
}

+              <Route path="/history"        element={<History />} />


Now redesign Projects.jsx to be full-height and add it properly, plus add "Link existing tasks" to ProjectDetail. Let me update Projects.jsx layout:


return (

      {/* Header */}

Projects

        <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5">
          <Plus size={15} /> New Project
        </button>

      {/* Category pills */}

        {ALL_CATS.map(c => (
          <button
            key={c.id}
            onClick={() => setCatFilter(c.id)}
            className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
              catFilter === c.id
                ? 'bg-primary text-white'
                : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
            }`}
          >
            {c.label}
          </button>
        ))}

      {/* Status filter */}

        {ALL_STATUSES.map(s => (
          <button
            key={s}
            onClick={() => setStatusFilter(s)}
            className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${
              statusFilter === s
                ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'
                : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
            }`}
          >
            {s}
          </button>
        ))}

      {/* Grid */}
      {loading ? (

          {[...Array(9)].map((_, i) =>
)}

      ) : projects.length === 0 ? (

          <FolderKanban size={40} className="text-gray-300 dark:text-gray-700 mx-auto mb-3" />

No projects found

          <button onClick={() => setShowNew(true)} className="btn-primary mt-4">Create a project</button>

      ) : (

          {projects.map(p => (
            <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

                <span className={`badge ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}
                <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

{p.name}

                <span className={`badge ${getPriorityClass(p.priority)}`}>{p.priority}
                <span className={`badge ${getStatusClass(p.status)}`}>{p.status}

                {p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}
                {p.updated_at && {formatDate(p.updated_at)}}

            </Link>
          ))}

      )}

      {(showNew || editProject) && (
        <ProjectModal
          project={editProject}
          onSave={handleSave}
          onClose={() => { setShowNew(false); setEditProject(null); }}
        />
      )}
      {deleteProject && (
        <ConfirmDialog
          title="Delete project?"
          message={`"${deleteProject.name}" and its associations will be removed.`}
          onConfirm={handleDelete}
          onCancel={() => setDeleteProject(null)}
        />
      )}

  );

return (

      {/* Header */}

Projects

            {!loading &&
{projects.length} project{projects.length !== 1 ? 's' : ''}
}

          <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">
            <Plus size={14} /> New Project
          </button>

        {/* Category pills */}

          {ALL_CATS.map(c => (
            <button
              key={c.id}
              onClick={() => setCatFilter(c.id)}
              className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
                catFilter === c.id
                  ? 'bg-primary text-white'
                  : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
              }`}
            >
              {c.label}
            </button>
          ))}

        {/* Status tabs */}

          {ALL_STATUSES.map(s => (
            <button
              key={s}
              onClick={() => setStatusFilter(s)}
              className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${
                statusFilter === s
                  ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'
                  : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
              }`}
            >
              {s}
            </button>
          ))}

      {/* Grid */}

        {loading ? (

            {[...Array(9)].map((_, i) =>
)}

        ) : projects.length === 0 ? (

            <FolderKanban size={44} className="text-gray-200 dark:text-gray-700" />

No projects found

            <button onClick={() => setShowNew(true)} className="btn-primary">Create a project</button>

        ) : (

            {projects.map(p => (
              <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

                  <span className={`badge text-[10px] ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}
                  <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

{p.name}

                  <span className={`badge text-[10px] ${getPriorityClass(p.priority)}`}>{p.priority}
                  <span className={`badge text-[10px] ${getStatusClass(p.status)}`}>{p.status}

                  {p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}
                  {p.updated_at && {formatDate(p.updated_at)}}

              </Link>
            ))}

        )}

      {(showNew || editProject) && (
        <ProjectModal
          project={editProject}
          onSave={handleSave}
          onClose={() => { setShowNew(false); setEditProject(null); }}
        />
      )}
      {deleteProject && (
        <ConfirmDialog
          title="Delete project?"
          message={`"${deleteProject.name}" and its associations will be removed.`}
          onConfirm={handleDelete}
          onCancel={() => setDeleteProject(null)}
        />
      )}

  );


The file /Users/khalidbinkalban/my-workspace/client/src/components/Projects.jsx has been updated successfully.

return (

      {/* Header */}

Projects

            {!loading &&
{projects.length} project{projects.length !== 1 ? 's' : ''}
}

          <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">
            <Plus size={14} /> New Project
          </button>

        {/* Category pills */}

          {ALL_CATS.map(c => (
            <button
              key={c.id}
              onClick={() => setCatFilter(c.id)}
              className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
                catFilter === c.id
                  ? 'bg-primary text-white'
                  : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
              }`}
            >
              {c.label}
            </button>
          ))}

        {/* Status tabs */}

          {ALL_STATUSES.map(s => (
            <button
              key={s}
              onClick={() => setStatusFilter(s)}
              className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${
                statusFilter === s
                  ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'
                  : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
              }`}
            >
              {s}
            </button>
          ))}

      {/* Grid */}

        {loading ? (

            {[...Array(9)].map((_, i) =>
)}

        ) : projects.length === 0 ? (

            <FolderKanban size={44} className="text-gray-200 dark:text-gray-700" />

No projects found

            <button onClick={() => setShowNew(true)} className="btn-primary">Create a project</button>

        ) : (

            {projects.map(p => (
              <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

                  <span className={`badge text-[10px] ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}
                  <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

{p.name}

                  <span className={`badge text-[10px] ${getPriorityClass(p.priority)}`}>{p.priority}
                  <span className={`badge text-[10px] ${getStatusClass(p.status)}`}>{p.status}

                  {p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}
                  {p.updated_at && {formatDate(p.updated_at)}}

              </Link>
            ))}

        )}

      {(showNew || editProject) && (
        <ProjectModal
          project={editProject}
          onSave={handleSave}
          onClose={() => { setShowNew(false); setEditProject(null); }}
        />
      )}
      {deleteProject && (
        <ConfirmDialog
          title="Delete project?"
          message={`"${deleteProject.name}" and its associations will be removed.`}
          onConfirm={handleDelete}
          onCancel={() => setDeleteProject(null)}
        />
      )}

  );

import { useState, useEffect } from 'react';
import { Plus, FolderKanban, ChevronRight } from 'lucide-react';
import { Link } from 'react-router-dom';
import toast from 'react-hot-toast';
import api from '../api';
import ConfirmDialog from './ConfirmDialog';
import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass, formatDate } from '../utils';

const ALL_CATS = [{ id: '', label: 'All' }, ...Object.entries(CATEGORIES).map(([id, v]) => ({ id, label: v.label }))];
const ALL_STATUSES = ['All', ...STATUSES.filter(s => s !== 'Done'), 'Done'];

function ProjectModal({ project, onSave, onClose }) {
  const [form, setForm] = useState({
    name: '', category: 'ai', status: 'Open', priority: 'Medium',
    description: '', last_update: '', next_step: '',
    ...project,
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const submit = async (e) => {
    e.preventDefault();
    onSave(form);
  };
  return (

 e.stopPropagation()}>

{project?.id ? 'Edit Project' : 'New Project'}

        <form onSubmit={submit} className="px-5 py-4 space-y-3">

            Project Name *
            <input className="input" required value={form.name} onChange={e => set('name', e.target.value)} autoFocus />

              Category
              <select className="select" value={form.category} onChange={e => set('category', e.target.value)}>
                {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
              </select>

              Priority
              <select className="select" value={form.priority} onChange={e => set('priority', e.target.value)}>
                {PRIORITIES.map(p => <option key={p}>{p}</option>)}
              </select>

            Status
            <select className="select" value={form.status} onChange={e => set('status', e.target.value)}>
              {STATUSES.map(s => <option key={s}>{s}</option>)}
            </select>

            Description
            <textarea className="input resize-none" rows={2} value={form.description} onChange={e => set('description', e.target.value)} />

            <button type="button" onClick={onClose} className="btn-secondary">Cancel</button>
            <button type="submit" className="btn-primary">{project?.id ? 'Save' : 'Create Project'}</button>

        </form>

  );
}

export default function Projects() {
  const [projects, setProjects] = useState([]);
  const [loading, setLoading] = useState(true);
  const [catFilter, setCatFilter] = useState('');
  const [statusFilter, setStatusFilter] = useState('All');
  const [editProject, setEditProject] = useState(null);
  const [deleteProject, setDeleteProject] = useState(null);
  const [showNew, setShowNew] = useState(false);

  const load = async () => {
    setLoading(true);
    const params = new URLSearchParams();
    if (catFilter) params.set('category', catFilter);
    if (statusFilter !== 'All') params.set('status', statusFilter);
    try {
      setProjects(await api.get('/projects?' + params));
    } finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [catFilter, statusFilter]);

  const handleSave = async (form) => {
    try {
      if (form.id) { await api.put(`/projects/${form.id}`, form); toast.success('Project updated'); }
      else { await api.post('/projects', form); toast.success('Project created'); }
      setEditProject(null); setShowNew(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleDelete = async () => {
    try {
      await api.delete(`/projects/${deleteProject.id}`);
      toast.success('Project deleted');
      setDeleteProject(null);
      load();
    } catch (e) { toast.error(e.message); }
  };

  return (

      {/* Header */}

Projects

        <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5">
          <Plus size={15} /> New Project
        </button>

      {/* Category pills */}

        {ALL_CATS.map(c => (
          <button
            key={c.id}
            onClick={() => setCatFilter(c.id)}
            className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
              catFilter === c.id
                ? 'bg-primary text-white'
                : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
            }`}
          >
            {c.label}
          </button>
        ))}

      {/* Status filter */}

        {ALL_STATUSES.map(s => (
          <button
            key={s}
            onClick={() => setStatusFilter(s)}
            className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${
              statusFilter === s
                ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'
                : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
            }`}
          >
            {s}
          </button>
        ))}

      {/* Grid */}
      {loading ? (

          {[...Array(9)].map((_, i) =>
)}

      ) : projects.length === 0 ? (

          <FolderKanban size={40} className="text-gray-300 dark:text-gray-700 mx-auto mb-3" />

No projects found

          <button onClick={() => setShowNew(true)} className="btn-primary mt-4">Create a project</button>

      ) : (

          {projects.map(p => (
            <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

                <span className={`badge ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}
                <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

{p.name}

                <span className={`badge ${getPriorityClass(p.priority)}`}>{p.priority}
                <span className={`badge ${getStatusClass(p.status)}`}>{p.status}

                {p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}
                {p.updated_at && {formatDate(p.updated_at)}}

            </Link>
          ))}

      )}

      {(showNew || editProject) && (
        <ProjectModal
          project={editProject}
          onSave={handleSave}
          onClose={() => { setShowNew(false); setEditProject(null); }}
        />
      )}
      {deleteProject && (
        <ConfirmDialog
          title="Delete project?"
          message={`"${deleteProject.name}" and its associations will be removed.`}
          onConfirm={handleDelete}
          onCancel={() => setDeleteProject(null)}
        />
      )}

  );
}

-    <div className="max-w-4xl mx-auto px-4 py-6">

+    <div className="flex flex-col h-full overflow-hidden">

-        <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5">

-          <Plus size={15} /> New Project

-      <div className="flex gap-2 overflow-x-auto pb-2 mb-4 scrollbar-none">

-            onClick={() => setCatFilter(c.id)}

-            className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${

-                ? 'bg-primary text-white'

-                : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'

+      <div className="shrink-0 px-4 pt-4 pb-3 bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800">

+        <div className="flex items-center justify-between mb-3">

+            {!loading &&
{projects.length} project{projects.length !== 1 ? 's' : ''}
}

+          <button onClick={() => setShowNew(true)} className="btn-primary flex items-center gap-1.5 py-2">

+            <Plus size={14} /> New Project

-      <div className="flex gap-2 mb-5">

-            onClick={() => setStatusFilter(s)}

-            className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${

-                ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'

-                : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'

-        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">

-          {[...Array(9)].map((_, i) => <div key={i} className="skeleton h-32 rounded-lg" />)}

+        <div className="flex gap-1.5 overflow-x-auto pb-1 scrollbar-none">

+              onClick={() => setCatFilter(c.id)}

+              className={`shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${

+                  ? 'bg-primary text-white'

+                  : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'

-        <div className="text-center py-16">

-          <FolderKanban size={40} className="text-gray-300 dark:text-gray-700 mx-auto mb-3" />

-          <button onClick={() => setShowNew(true)} className="btn-primary mt-4">Create a project</button>

-            <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

-              <div className="flex items-start justify-between mb-2">

-                <span className={`badge ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}

-                <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

-              <div className="flex flex-wrap gap-1.5 mb-3">

-                <span className={`badge ${getPriorityClass(p.priority)}`}>{p.priority}

-                <span className={`badge ${getStatusClass(p.status)}`}>{p.status}

-              <div className="flex items-center justify-between text-xs text-gray-400 dark:text-gray-500">

-                <span>{p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}</span>

-                {p.updated_at && <span>{formatDate(p.updated_at)}</span>}

+        <div className="flex gap-1 mt-2">

+              onClick={() => setStatusFilter(s)}

+              className={`px-3 py-1 rounded-lg text-xs font-medium transition-colors ${

+                  ? 'bg-gray-800 dark:bg-white text-white dark:text-gray-900'

+                  : 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'

+      <div className="flex-1 overflow-y-auto p-4">

+          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">

+            {[...Array(9)].map((_, i) => <div key={i} className="skeleton h-32 rounded-xl" />)}

+          <div className="flex flex-col items-center justify-center h-full gap-3 py-16">

+            <FolderKanban size={44} className="text-gray-200 dark:text-gray-700" />

+            <button onClick={() => setShowNew(true)} className="btn-primary">Create a project</button>

+              <Link to={`/projects/${p.id}`} key={p.id} className="card-hover block group">

+                <div className="flex items-start justify-between mb-2">

+                  <span className={`badge text-[10px] ${getCategoryClass(p.category)}`}>{CATEGORIES[p.category]?.label || p.category}

+                  <ChevronRight size={14} className="text-gray-400 mt-0.5 opacity-0 group-hover:opacity-100 transition-opacity" />

+                <div className="flex flex-wrap gap-1.5 mb-3">

+                  <span className={`badge text-[10px] ${getPriorityClass(p.priority)}`}>{p.priority}

+                  <span className={`badge text-[10px] ${getStatusClass(p.status)}`}>{p.status}

+                <div className="flex items-center justify-between text-[10px] text-gray-400">

+                  <span>{p.open_task_count || 0} open task{p.open_task_count !== 1 ? 's' : ''}</span>

+                  {p.updated_at && <span>{formatDate(p.updated_at)}</span>}


Now add "Link existing tasks" to ProjectDetail.jsx:


import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare } from 'lucide-react';

import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare, Link2, Search, X } from 'lucide-react';


The file /Users/khalidbinkalban/my-workspace/client/src/components/ProjectDetail.jsx has been updated successfully.

import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare, Link2, Search, X } from 'lucide-react';

import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import TaskCard from './TaskCard';
import TaskModal from './TaskModal';
import ConfirmDialog from './ConfirmDialog';
import { CATEGORIES, STATUSES, PRIORITIES, getCategoryClass, getPriorityClass, getStatusClass } from '../utils';

function InlineEdit({ value, onSave, multiline = false, placeholder = '' }) {
  const [editing, setEditing] = useState(false);
  const [val, setVal] = useState(value || '');
  useEffect(() => setVal(value || ''), [value]);
  const save = () => { setEditing(false); if (val !== value) onSave(val); };
  if (!editing) return (
     setEditing(true)}
      className="group cursor-text text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white flex items-center gap-1"
    >
      {val || placeholder}
      <Pencil size={11} className="opacity-0 group-hover:opacity-50 shrink-0" />

  );
  return multiline
    ? <textarea autoFocus className="input w-full resize-none" rows={3} value={val} onChange={e => setVal(e.target.value)} onBlur={save} />
    : <input autoFocus className="input w-full" value={val} onChange={e => setVal(e.target.value)} onBlur={save} onKeyDown={e => e.key === 'Enter' && save()} />;
}

function NoteForm({ projectId, onSave, onCancel }) {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const submit = async (e) => {
    e.preventDefault();
    if (!title.trim()) return;
    await onSave({ title, body, project_id: projectId, date: new Date().toISOString().split('T')[0] });
    setTitle(''); setBody('');
  };
  return (
    <form onSubmit={submit} className="card border-dashed space-y-2">
      <input className="input" placeholder="Note title" value={title} onChange={e => setTitle(e.target.value)} autoFocus required />
      <textarea className="input resize-none" rows={3} placeholder="Note body…" value={body} onChange={e => setBody(e.target.value)} />

        <button type="button" onClick={onCancel} className="btn-secondary text-xs py-1 px-3">Cancel</button>
        <button type="submit" className="btn-primary text-xs py-1 px-3">Save Note</button>

    </form>
  );
}

export default function ProjectDetail() {
  const { id } = useParams();
  const navigate = useNavigate();
  const [project, setProject] = useState(null);
  const [tasks, setTasks] = useState([]);
  const [notes, setNotes] = useState([]);
  const [projects, setProjects] = useState([]);
  const [tab, setTab] = useState('tasks');
  const [loading, setLoading] = useState(true);
  const [editTask, setEditTask] = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [deleteNote, setDeleteNote] = useState(null);
  const [showNewTask, setShowNewTask] = useState(false);
  const [showNewNote, setShowNewNote] = useState(false);

  const load = async () => {
    try {
      const [p, t, n, pr] = await Promise.all([
        api.get(`/projects/${id}`),
        api.get(`/tasks?project_id=${id}`),
        api.get(`/notes?project_id=${id}`),
        api.get('/projects'),
      ]);
      setProject(p); setTasks(t); setNotes(n); setProjects(pr);
    } catch { navigate('/projects'); }
    finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [id]);

  const updateProject = async (field, value) => {
    const updated = { ...project, [field]: value };
    setProject(updated);
    await api.put(`/projects/${id}`, updated);
  };

  const handleSaveTask = async (form) => {
    try {
      if (editTask?.id) { await api.put(`/tasks/${editTask.id}`, { ...form, project_id: id }); toast.success('Task updated'); }
      else { await api.post('/tasks', { ...form, project_id: id }); toast.success('Task added'); }
      setEditTask(null); setShowNewTask(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleSaveNote = async (form) => {
    try {
      await api.post('/notes', form); toast.success('Note saved');
      setShowNewNote(false); load();
    } catch (e) { toast.error(e.message); }
  };

  const handleDeleteTask = async () => {
    await api.delete(`/tasks/${deleteTask.id}`); toast.success('Task deleted');
    setDeleteTask(null); load();
  };

  const handleDeleteNote = async () => {
    await api.delete(`/notes/${deleteNote.id}`); toast.success('Note deleted');
    setDeleteNote(null); load();
  };

  const toggleFocus = async (task) => { await api.patch(`/tasks/${task.id}/focus`); load(); };

  if (loading) return (

  );

  if (!project) return null;

  return (

      {/* Back */}
      <button onClick={() => navigate('/projects')} className="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-800 dark:hover:text-white mb-4 transition-colors">
        <ArrowLeft size={15} /> Projects
      </button>

      {/* Project header */}

          <select
            className="badge cursor-pointer border-0 outline-none bg-transparent p-0"
            style={{ minWidth: 0 }}
            value={project.category}
            onChange={e => updateProject('category', e.target.value)}
          >
            {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
          </select>
          <select
            className={`badge cursor-pointer border-0 outline-none bg-transparent p-0 ${getPriorityClass(project.priority)}`}
            value={project.priority}
            onChange={e => updateProject('priority', e.target.value)}
          >
            {PRIORITIES.map(p => <option key={p}>{p}</option>)}
          </select>
          <select
            className={`badge cursor-pointer border-0 outline-none bg-transparent p-0 ${getStatusClass(project.status)}`}
            value={project.status}
            onChange={e => updateProject('status', e.target.value)}
          >
            {STATUSES.map(s => <option key={s}>{s}</option>)}
          </select>

          <InlineEdit value={project.name} onSave={v => updateProject('name', v)} placeholder="Project name" />

Description

            <InlineEdit value={project.description} onSave={v => updateProject('description', v)} multiline placeholder="Add description…" />

Last Update

            <InlineEdit value={project.last_update} onSave={v => updateProject('last_update', v)} placeholder="What happened last?" />

Next Step

            <InlineEdit value={project.next_step} onSave={v => updateProject('next_step', v)} placeholder="What needs to happen next?" />

      {/* Tabs */}

        <button
          onClick={() => setTab('tasks')}
          className={`flex-1 flex items-center justify-center gap-1.5 py-2 px-3 rounded-md text-sm font-medium transition-colors ${
            tab === 'tasks' ? 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow-sm' : 'text-gray-500 hover:text-gray-700 dark:hover:text-gray-300'
          }`}
        >
          <CheckSquare size={14} /> Tasks ({tasks.filter(t => t.status !== 'Done').length})
        </button>
        <button
          onClick={() => setTab('notes')}
          className={`flex-1 flex items-center justify-center gap-1.5 py-2 px-3 rounded-md text-sm font-medium transition-colors ${
            tab === 'notes' ? 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow-sm' : 'text-gray-500 hover:text-gray-700 dark:hover:text-gray-300'
          }`}
        >
          <FileText size={14} /> Notes ({notes.length})
        </button>

      {/* Tab content */}
      {tab === 'tasks' && (

            <button onClick={() => setShowNewTask(true)} className="btn-secondary flex items-center gap-1.5 text-xs">
              <Plus size={13} /> Add Task
            </button>

          {tasks.length === 0
            ?
No tasks yet. Add one above.

            : tasks.map(t => (
                <TaskCard key={t.id} task={t} onEdit={setEditTask} onDelete={setDeleteTask} onToggleFocus={toggleFocus} />
              ))
          }

      )}

      {tab === 'notes' && (

            <button onClick={() => setShowNewNote(!showNewNote)} className="btn-secondary flex items-center gap-1.5 text-xs">
              <Plus size={13} /> Add Note
            </button>

          {showNewNote && <NoteForm projectId={id} onSave={handleSaveNote} onCancel={() => setShowNewNote(false)} />}
          {notes.length === 0 && !showNewNote
            ?
No notes yet.

            : notes.map(n => (

{n.title}

{n.date}

                      {n.body &&
{n.body}
}

                    <button onClick={() => setDeleteNote(n)} className="p-1.5 rounded hover:bg-red-50 text-gray-400 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-all ml-2">
                      <Trash2 size={13} />
                    </button>

              ))
          }

      )}

      {/* Modals */}
      {(showNewTask || editTask) && (
        <TaskModal task={editTask} projects={projects} onSave={handleSaveTask} onClose={() => { setShowNewTask(false); setEditTask(null); }} />
      )}
      {deleteTask && <ConfirmDialog title="Delete task?" message={`"${deleteTask.title}"`} onConfirm={handleDeleteTask} onCancel={() => setDeleteTask(null)} />}
      {deleteNote && <ConfirmDialog title="Delete note?" message={`"${deleteNote.title}"`} onConfirm={handleDeleteNote} onCancel={() => setDeleteNote(null)} />}

  );
}

-import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare } from 'lucide-react';

+import { ArrowLeft, Pencil, Check, Plus, Trash2, FileText, CheckSquare, Link2, Search, X } from 'lucide-react';


  const [tab, setTab] = useState('tasks');
  const [loading, setLoading] = useState(true);
  const [editTask, setEditTask] = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [deleteNote, setDeleteNote] = useState(null);
  const [showNewTask, setShowNewTask] = useState(false);
  const [showNewNote, setShowNewNote] = useState(false);

  const [tab, setTab] = useState('tasks');
  const [loading, setLoading] = useState(true);
  const [editTask, setEditTask] = useState(null);
  const [deleteTask, setDeleteTask] = useState(null);
  const [deleteNote, setDeleteNote] = useState(null);
  const [showNewTask, setShowNewTask] = useState(false);
  const [showNewNote, setShowNewNote] = useState(false);
  const [showLinkTask, setShowLinkTask] = useState(false);
  const [allTasks, setAllTasks] = useState([]);
  const [linkSearch, setLinkSearch] = useState('');