1	import { useState, useEffect, useRef } from 'react';
2	import {
3	  Mic, MicOff, Sparkles, Save, Trash2, Lightbulb,
4	  CheckSquare, FileText, FolderKanban, Clock, ChevronDown, ChevronUp,
5	  User, Calendar, Tag, AlertCircle, Zap, ArrowRight
6	} from 'lucide-react';
7	import toast from 'react-hot-toast';
8	import api from '../api';
9	import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';
10
11	const HISTORY_KEY = 'quicknote_history';
12	function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
13	function pushHistory(item) {
14	  const h = loadHistory();
15	  h.unshift({ ...item, savedAt: new Date().toISOString() });
16	  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
17	}
18
19	const TYPE_CONFIG = {
20	  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
21	  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
22	  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
23	};
24
25	const EXAMPLES = [
26	  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
27	  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
28	  'Note: Google NDA meeting happened — next step is Legal Affairs review',
29	  'New project: AI Ethics workshop for Champions Program, strategic initiative',
30	];
31
32	// ── Parsed result card ───────────────────────────────────────────────────────
33	function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
34	  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
35	  const TypeIcon = TypeCfg.icon;
36
37	  return (
38

39	      {/* Card header */}
40

41	        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
42	          <TypeIcon size={15} className={TypeCfg.color} />
43

44

45
AI Parsed Result

46
Review and edit before saving

47

48	        <select
49	          value={data.type}
50	          onChange={e => onChange('type', e.target.value)}
51	          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
52	        >
53	          <option value="task">Task</option>
54	          <option value="note">Note</option>
55	          <option value="project">Project</option>
56	        </select>
57

58
59

60	        {/* Title */}
61

62	          Title
63	          <input
64	            className="input font-semibold text-base"
65	            value={data.title}
66	            onChange={e => onChange('title', e.target.value)}
67	            placeholder="Title…"
68	          />
69

70
71	        {/* Category + Priority */}
72

73

74	            Category
75	            <select className="select text-sm" value={data.category} onChange={e => onChange('category', e.target.value)}>
76	              {Object.entries(CATEGORIES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
77	            </select>
78

79

80	            Priority
81	            <select className="select text-sm" value={data.priority} onChange={e => onChange('priority', e.target.value)}>
82	              {PRIORITIES.map(p => <option key={p}>{p}</option>)}
83	            </select>
84

85

86
87	        {/* Task-specific fields */}
88	        {data.type === 'task' && (
89

90

91	              <User size={10} /> Assignee
92	              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />
93

94

95	              <Calendar size={10} /> Due Date
96	              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />
97

98

99	        )}
100
101	        {/* Details */}
102

103	          Details / Notes
104	          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />
105

106
107	        {/* Task checkboxes */}
108	        {data.type === 'task' && (
109

110
111	              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
112	              Follow-up needed
113
114
115	              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
116	              Pin to today
117
118

119	        )}
120
121	        {/* Project hint */}
122	        {data.projectHint && (
123

124	            <Lightbulb size={13} className="text-amber-600 shrink-0" />
125

126	              Suggested project: {data.projectHint}
127

128

129	        )}
130

131
132	      {/* Actions */}
133

134	        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
135	          <Trash2 size={13} /> Discard
136	        </button>
137

138	        <button onClick={onSave} className="btn-primary flex items-center gap-2">
139	          <Save size={14} /> Save to Workspace
140	        </button>
141

142

143	  );
144	}
145
146	// ── History card ─────────────────────────────────────────────────────────────
147	function HistoryItem({ item }) {
148	  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
149	  const TypeIcon = TypeCfg.icon;
150	  const when = new Date(item.savedAt);
151	  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
152
153	  return (
154

155	      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
156	        <TypeIcon size={14} className={TypeCfg.color} />
157

158

159
{item.title}

160

161	          {item.category && (
162	            <span className={`badge text-[10px] py-0 ${getCategoryClass(item.category)}`}>
163	              {CATEGORIES[item.category]?.label?.split(' ')[0]}
164
165	          )}
166	          {item.priority && (
167	            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
168	          )}
169	          {timeStr}
170

171

172

173	  );
174	}
175
176	// ── Main component ────────────────────────────────────────────────────────────
177	export default function QuickNote() {
178	  const [text, setText]           = useState('');
179	  const [listening, setListening] = useState(false);
180	  const [processing, setProcessing] = useState(false);
181	  const [parsed, setParsed]       = useState(null);
182	  const [editData, setEditData]   = useState(null);
183	  const [projects, setProjects]   = useState([]);
184	  const [history, setHistory]     = useState(loadHistory);
185	  const [showExamples, setShowEx] = useState(false);
186	  const recognitionRef = useRef(null);
187	  const textareaRef    = useRef(null);
188
189	  useEffect(() => { api.get('/projects').then(setProjects).catch(() => {}); }, []);
190
191	  // Voice
192	  const startVoice = () => {
193	    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
194	    if (!SR) { toast.error('Voice input not supported in this browser'); return; }
195	    const r = new SR();
196	    r.lang = 'en-US'; r.interimResults = false;
197	    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };
198	    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };
199	    r.onend    = () => setListening(false);
200	    recognitionRef.current = r;
201	    r.start(); setListening(true);
202	  };
203	  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };
204
205	  // Process with AI
206	  const process = async () => {
207	    if (!text.trim()) { toast.error('Type or speak something first'); return; }
208	    setProcessing(true);
209	    try {
210	      const result = await api.post('/ai/parse', { text });
211	      setParsed(result);
212	      setEditData({ ...result });
213	    } catch (e) {
214	      toast.error('AI parsing failed: ' + e.message);
215	    } finally { setProcessing(false); }
216	  };
217
218	  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));
219
220	  // Save to workspace
221	  const save = async () => {
222	    if (!editData) return;
223	    try {
224	      const d = editData;
225	      if (d.type === 'task') {
226	        await api.post('/tasks', {
227	          title: d.title, notes: d.details, category: d.category, priority: d.priority,
228	          assignee: d.assignee || '', due_date: d.due || '',
229	          is_follow_up: d.isFollowUp ? 1 : 0,
230	          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
231	        });
232	        toast.success('Task saved!');
233	      } else if (d.type === 'note') {
234	        await api.post('/notes', { title: d.title, body: d.details });
235	        toast.success('Note saved!');
236	      } else {
237	        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
238	        toast.success('Project created!');
239	      }
240	      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
241	      setHistory(loadHistory());
242	      setParsed(null); setEditData(null); setText('');
243	      textareaRef.current?.focus();
244	    } catch (e) { toast.error(e.message); }
245	  };
246
247	  const discard = () => { setParsed(null); setEditData(null); };
248
249	  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };
250
251	  return (
252

253	      {/* Header */}
254

255

256

257	            <Zap size={16} className="text-white" />
258

259

260
Quick Note

261
Speak or type — AI structures it instantly

262

263

264

265
266	      {/* Main content — horizontal split on desktop */}
267

268
269	        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}
270

271
272	          {/* Input card */}
273

274	            {/* Textarea */}
275	            <textarea
276	              ref={textareaRef}
277	              value={text}
278	              onChange={e => setText(e.target.value)}
279	              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
280	              disabled={listening}
281	              rows={5}
282	              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
283	              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
284	            />
285
286	            {/* Toolbar */}
287

288	              {/* Voice */}
289	              <button
290	                onClick={listening ? stopVoice : startVoice}
291	                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
292	                  listening
293	                    ? 'bg-red-500 text-white animate-pulse shadow-md'
294	                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
295	                }`}
296	              >
297	                {listening ? <MicOff size={14} /> : <Mic size={14} />}
298	                {listening ? 'Stop' : 'Voice'}
299	              </button>
300
301	              {/* Examples */}
302	              <button
303	                onClick={() => setShowEx(!showExamples)}
304	                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
305	              >
306	                <Lightbulb size={13} />
307	                Examples
308	              </button>
309
310

311
312	              {text.trim() && !processing && !parsed && (
313	                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
314	                  Clear
315	                </button>
316	              )}
317
318	              <button
319	                onClick={process}
320	                disabled={!text.trim() || processing || !!parsed}
321	                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
322	              >
323	                {processing ? (
324	                  <> Parsing…</>
325	                ) : (
326	                  <><Sparkles size={14} /> Process ⌘↵</>
327	                )}
328	              </button>
329

330
331	            {/* Example suggestions */}
332	            {showExamples && (
333

334
Try these

335	                {EXAMPLES.map((ex, i) => (
336	                  <button key={i} onClick={() => useExample(ex)}
337	                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
338	                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
339	                    {ex}
340	                  </button>
341	                ))}
342

343	            )}
344

345
346	          {/* Parsed result */}
347	          {editData && (
348	            <ParsedCard
349	              data={editData}
350	              onChange={changeField}
351	              projects={projects}
352	              onSave={save}
353	              onDiscard={discard}
354	            />
355	          )}
356
357	          {/* Empty state when no parsed result */}
358	          {!editData && !processing && (
359

360	              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />
361
Type or speak, then click Process

362
Claude will parse it into a task, note, or project

363

364	          )}
365

366
367	        {/* ── RIGHT: History ──────────────────────────────────────────── */}
368

369

370
Recent Captures

371
Last {history.length} items saved via Quick Note

372

373
374	          {history.length === 0 ? (
375

376	              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />
377
Nothing captured yet

378
Your saved items will appear here

379

380	          ) : (
381

382	              {history.map((item, i) => <HistoryItem key={i} item={item} />)}
383

384	          )}
385
386	          {/* Tip box */}
387

388
Pro tip

389

390	              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.
391

392

393

394

395

396	  );
397	}
398

import { useState, useEffect, useRef } from 'react';
import {
  Mic, MicOff, Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock, ChevronDown, ChevronUp,
  User, Calendar, Tag, AlertCircle, Zap, ArrowRight
} from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';

const HISTORY_KEY = 'quicknote_history';
function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
function pushHistory(item) {
  const h = loadHistory();
  h.unshift({ ...item, savedAt: new Date().toISOString() });
  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
}

const TYPE_CONFIG = {
  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
};

const EXAMPLES = [
  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
  'Note: Google NDA meeting happened — next step is Legal Affairs review',
  'New project: AI Ethics workshop for Champions Program, strategic initiative',
];

// ── Parsed result card ───────────────────────────────────────────────────────
function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;

  return (

      {/* Card header */}

        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
          <TypeIcon size={15} className={TypeCfg.color} />

AI Parsed Result

Review and edit before saving

        <select
          value={data.type}
          onChange={e => onChange('type', e.target.value)}
          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
        >
          <option value="task">Task</option>
          <option value="note">Note</option>
          <option value="project">Project</option>
        </select>

        {/* Title */}

          Title
          <input
            className="input font-semibold text-base"
            value={data.title}
            onChange={e => onChange('title', e.target.value)}
            placeholder="Title…"
          />

        {/* Category + Priority */}

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

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

        {/* Task-specific fields */}
        {data.type === 'task' && (

              <User size={10} /> Assignee
              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />

              <Calendar size={10} /> Due Date
              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />

        )}

        {/* Details */}

          Details / Notes
          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />

        {/* Task checkboxes */}
        {data.type === 'task' && (

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
              Follow-up needed

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
              Pin to today

        )}

        {/* Project hint */}
        {data.projectHint && (

            <Lightbulb size={13} className="text-amber-600 shrink-0" />

              Suggested project: {data.projectHint}

        )}

      {/* Actions */}

        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
          <Trash2 size={13} /> Discard
        </button>

        <button onClick={onSave} className="btn-primary flex items-center gap-2">
          <Save size={14} /> Save to Workspace
        </button>

  );
}

// ── History card ─────────────────────────────────────────────────────────────
function HistoryItem({ item }) {
  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;
  const when = new Date(item.savedAt);
  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });

  return (

      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
        <TypeIcon size={14} className={TypeCfg.color} />

{item.title}

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

          )}
          {item.priority && (
            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
          )}
          {timeStr}

  );
}

// ── Main component ────────────────────────────────────────────────────────────
export default function QuickNote() {
  const [text, setText]           = useState('');
  const [listening, setListening] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]       = useState(null);
  const [editData, setEditData]   = useState(null);
  const [projects, setProjects]   = useState([]);
  const [history, setHistory]     = useState(loadHistory);
  const [showExamples, setShowEx] = useState(false);
  const recognitionRef = useRef(null);
  const textareaRef    = useRef(null);

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

  // Voice
  const startVoice = () => {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { toast.error('Voice input not supported in this browser'); return; }
    const r = new SR();
    r.lang = 'en-US'; r.interimResults = false;
    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };
    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };
    r.onend    = () => setListening(false);
    recognitionRef.current = r;
    r.start(); setListening(true);
  };
  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type or speak something first'); return; }
    setProcessing(true);
    try {
      const result = await api.post('/ai/parse', { text });
      setParsed(result);
      setEditData({ ...result });
    } catch (e) {
      toast.error('AI parsing failed: ' + e.message);
    } finally { setProcessing(false); }
  };

  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));

  // Save to workspace
  const save = async () => {
    if (!editData) return;
    try {
      const d = editData;
      if (d.type === 'task') {
        await api.post('/tasks', {
          title: d.title, notes: d.details, category: d.category, priority: d.priority,
          assignee: d.assignee || '', due_date: d.due || '',
          is_follow_up: d.isFollowUp ? 1 : 0,
          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
        });
        toast.success('Task saved!');
      } else if (d.type === 'note') {
        await api.post('/notes', { title: d.title, body: d.details });
        toast.success('Note saved!');
      } else {
        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
        toast.success('Project created!');
      }
      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
      setHistory(loadHistory());
      setParsed(null); setEditData(null); setText('');
      textareaRef.current?.focus();
    } catch (e) { toast.error(e.message); }
  };

  const discard = () => { setParsed(null); setEditData(null); };

  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };

  return (

      {/* Header */}

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

Quick Note

Speak or type — AI structures it instantly

      {/* Main content — horizontal split on desktop */}

        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}

          {/* Input card */}

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Toolbar */}

              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}
              <button
                onClick={() => setShowEx(!showExamples)}
                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
              >
                <Lightbulb size={13} />
                Examples
              </button>

              {text.trim() && !processing && !parsed && (
                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
                  Clear
                </button>
              )}

              <button
                onClick={process}
                disabled={!text.trim() || processing || !!parsed}
                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
              >
                {processing ? (
                  <> Parsing…</>
                ) : (
                  <><Sparkles size={14} /> Process ⌘↵</>
                )}
              </button>

            {/* Example suggestions */}
            {showExamples && (

Try these

                {EXAMPLES.map((ex, i) => (
                  <button key={i} onClick={() => useExample(ex)}
                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
                    {ex}
                  </button>
                ))}

            )}

          {/* Parsed result */}
          {editData && (
            <ParsedCard
              data={editData}
              onChange={changeField}
              projects={projects}
              onSave={save}
              onDiscard={discard}
            />
          )}

          {/* Empty state when no parsed result */}
          {!editData && !processing && (

              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />

Type or speak, then click Process

Claude will parse it into a task, note, or project

          )}

        {/* ── RIGHT: History ──────────────────────────────────────────── */}

Recent Captures

Last {history.length} items saved via Quick Note

          {history.length === 0 ? (

              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />

Nothing captured yet

Your saved items will appear here

          ) : (

              {history.map((item, i) => <HistoryItem key={i} item={item} />)}

          )}

          {/* Tip box */}

Pro tip

              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.

  );
}


Edit

import { useState, useEffect, useRef } from 'react';
import {
  Mic, MicOff, Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock, ChevronDown, ChevronUp,
  User, Calendar, Tag, AlertCircle, Zap, ArrowRight
} from 'lucide-react';

import { useState, useEffect, useRef } from 'react';
import {
  Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock,
  User, Calendar, Zap, ArrowRight
} from 'lucide-react';


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

import { useState, useEffect, useRef } from 'react';
import {
  Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock,
  User, Calendar, Zap, ArrowRight
} from 'lucide-react';

import { useState, useEffect, useRef } from 'react';
import {
  Mic, MicOff, Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock, ChevronDown, ChevronUp,
  User, Calendar, Tag, AlertCircle, Zap, ArrowRight
} from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';

const HISTORY_KEY = 'quicknote_history';
function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
function pushHistory(item) {
  const h = loadHistory();
  h.unshift({ ...item, savedAt: new Date().toISOString() });
  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
}

const TYPE_CONFIG = {
  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
};

const EXAMPLES = [
  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
  'Note: Google NDA meeting happened — next step is Legal Affairs review',
  'New project: AI Ethics workshop for Champions Program, strategic initiative',
];

// ── Parsed result card ───────────────────────────────────────────────────────
function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;

  return (

      {/* Card header */}

        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
          <TypeIcon size={15} className={TypeCfg.color} />

AI Parsed Result

Review and edit before saving

        <select
          value={data.type}
          onChange={e => onChange('type', e.target.value)}
          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
        >
          <option value="task">Task</option>
          <option value="note">Note</option>
          <option value="project">Project</option>
        </select>

        {/* Title */}

          Title
          <input
            className="input font-semibold text-base"
            value={data.title}
            onChange={e => onChange('title', e.target.value)}
            placeholder="Title…"
          />

        {/* Category + Priority */}

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

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

        {/* Task-specific fields */}
        {data.type === 'task' && (

              <User size={10} /> Assignee
              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />

              <Calendar size={10} /> Due Date
              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />

        )}

        {/* Details */}

          Details / Notes
          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />

        {/* Task checkboxes */}
        {data.type === 'task' && (

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
              Follow-up needed

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
              Pin to today

        )}

        {/* Project hint */}
        {data.projectHint && (

            <Lightbulb size={13} className="text-amber-600 shrink-0" />

              Suggested project: {data.projectHint}

        )}

      {/* Actions */}

        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
          <Trash2 size={13} /> Discard
        </button>

        <button onClick={onSave} className="btn-primary flex items-center gap-2">
          <Save size={14} /> Save to Workspace
        </button>

  );
}

// ── History card ─────────────────────────────────────────────────────────────
function HistoryItem({ item }) {
  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;
  const when = new Date(item.savedAt);
  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });

  return (

      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
        <TypeIcon size={14} className={TypeCfg.color} />

{item.title}

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

          )}
          {item.priority && (
            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
          )}
          {timeStr}

  );
}

// ── Main component ────────────────────────────────────────────────────────────
export default function QuickNote() {
  const [text, setText]           = useState('');
  const [listening, setListening] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]       = useState(null);
  const [editData, setEditData]   = useState(null);
  const [projects, setProjects]   = useState([]);
  const [history, setHistory]     = useState(loadHistory);
  const [showExamples, setShowEx] = useState(false);
  const recognitionRef = useRef(null);
  const textareaRef    = useRef(null);

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

  // Voice
  const startVoice = () => {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { toast.error('Voice input not supported in this browser'); return; }
    const r = new SR();
    r.lang = 'en-US'; r.interimResults = false;
    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };
    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };
    r.onend    = () => setListening(false);
    recognitionRef.current = r;
    r.start(); setListening(true);
  };
  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type or speak something first'); return; }
    setProcessing(true);
    try {
      const result = await api.post('/ai/parse', { text });
      setParsed(result);
      setEditData({ ...result });
    } catch (e) {
      toast.error('AI parsing failed: ' + e.message);
    } finally { setProcessing(false); }
  };

  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));

  // Save to workspace
  const save = async () => {
    if (!editData) return;
    try {
      const d = editData;
      if (d.type === 'task') {
        await api.post('/tasks', {
          title: d.title, notes: d.details, category: d.category, priority: d.priority,
          assignee: d.assignee || '', due_date: d.due || '',
          is_follow_up: d.isFollowUp ? 1 : 0,
          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
        });
        toast.success('Task saved!');
      } else if (d.type === 'note') {
        await api.post('/notes', { title: d.title, body: d.details });
        toast.success('Note saved!');
      } else {
        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
        toast.success('Project created!');
      }
      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
      setHistory(loadHistory());
      setParsed(null); setEditData(null); setText('');
      textareaRef.current?.focus();
    } catch (e) { toast.error(e.message); }
  };

  const discard = () => { setParsed(null); setEditData(null); };

  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };

  return (

      {/* Header */}

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

Quick Note

Speak or type — AI structures it instantly

      {/* Main content — horizontal split on desktop */}

        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}

          {/* Input card */}

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Toolbar */}

              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}
              <button
                onClick={() => setShowEx(!showExamples)}
                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
              >
                <Lightbulb size={13} />
                Examples
              </button>

              {text.trim() && !processing && !parsed && (
                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
                  Clear
                </button>
              )}

              <button
                onClick={process}
                disabled={!text.trim() || processing || !!parsed}
                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
              >
                {processing ? (
                  <> Parsing…</>
                ) : (
                  <><Sparkles size={14} /> Process ⌘↵</>
                )}
              </button>

            {/* Example suggestions */}
            {showExamples && (

Try these

                {EXAMPLES.map((ex, i) => (
                  <button key={i} onClick={() => useExample(ex)}
                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
                    {ex}
                  </button>
                ))}

            )}

          {/* Parsed result */}
          {editData && (
            <ParsedCard
              data={editData}
              onChange={changeField}
              projects={projects}
              onSave={save}
              onDiscard={discard}
            />
          )}

          {/* Empty state when no parsed result */}
          {!editData && !processing && (

              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />

Type or speak, then click Process

Claude will parse it into a task, note, or project

          )}

        {/* ── RIGHT: History ──────────────────────────────────────────── */}

Recent Captures

Last {history.length} items saved via Quick Note

          {history.length === 0 ? (

              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />

Nothing captured yet

Your saved items will appear here

          ) : (

              {history.map((item, i) => <HistoryItem key={i} item={item} />)}

          )}

          {/* Tip box */}

Pro tip

              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.

  );
}

-  Mic, MicOff, Sparkles, Save, Trash2, Lightbulb,

-  CheckSquare, FileText, FolderKanban, Clock, ChevronDown, ChevronUp,

-  User, Calendar, Tag, AlertCircle, Zap, ArrowRight

+  CheckSquare, FileText, FolderKanban, Clock,


  const [text, setText]           = useState('');
  const [listening, setListening] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]       = useState(null);
  const [editData, setEditData]   = useState(null);
  const [projects, setProjects]   = useState([]);
  const [history, setHistory]     = useState(loadHistory);
  const [showExamples, setShowEx] = useState(false);
  const recognitionRef = useRef(null);
  const textareaRef    = useRef(null);

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

  // Voice
  const startVoice = () => {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { toast.error('Voice input not supported in this browser'); return; }
    const r = new SR();
    r.lang = 'en-US'; r.interimResults = false;
    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };
    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };
    r.onend    = () => setListening(false);
    recognitionRef.current = r;
    r.start(); setListening(true);
  };
  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };

  const [text, setText]             = useState('');
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]         = useState(null);
  const [editData, setEditData]     = useState(null);
  const [projects, setProjects]     = useState([]);
  const [history, setHistory]       = useState(loadHistory);
  const [showExamples, setShowEx]   = useState(false);
  const textareaRef = useRef(null);

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


  const [text, setText]             = useState('');
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]         = useState(null);
  const [editData, setEditData]     = useState(null);
  const [projects, setProjects]     = useState([]);
  const [history, setHistory]       = useState(loadHistory);
  const [showExamples, setShowEx]   = useState(false);
  const textareaRef = useRef(null);

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

import { useState, useEffect, useRef } from 'react';
import {
  Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock,
  User, Calendar, Zap, ArrowRight
} from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';

const HISTORY_KEY = 'quicknote_history';
function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
function pushHistory(item) {
  const h = loadHistory();
  h.unshift({ ...item, savedAt: new Date().toISOString() });
  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
}

const TYPE_CONFIG = {
  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
};

const EXAMPLES = [
  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
  'Note: Google NDA meeting happened — next step is Legal Affairs review',
  'New project: AI Ethics workshop for Champions Program, strategic initiative',
];

// ── Parsed result card ───────────────────────────────────────────────────────
function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;

  return (

      {/* Card header */}

        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
          <TypeIcon size={15} className={TypeCfg.color} />

AI Parsed Result

Review and edit before saving

        <select
          value={data.type}
          onChange={e => onChange('type', e.target.value)}
          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
        >
          <option value="task">Task</option>
          <option value="note">Note</option>
          <option value="project">Project</option>
        </select>

        {/* Title */}

          Title
          <input
            className="input font-semibold text-base"
            value={data.title}
            onChange={e => onChange('title', e.target.value)}
            placeholder="Title…"
          />

        {/* Category + Priority */}

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

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

        {/* Task-specific fields */}
        {data.type === 'task' && (

              <User size={10} /> Assignee
              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />

              <Calendar size={10} /> Due Date
              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />

        )}

        {/* Details */}

          Details / Notes
          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />

        {/* Task checkboxes */}
        {data.type === 'task' && (

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
              Follow-up needed

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
              Pin to today

        )}

        {/* Project hint */}
        {data.projectHint && (

            <Lightbulb size={13} className="text-amber-600 shrink-0" />

              Suggested project: {data.projectHint}

        )}

      {/* Actions */}

        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
          <Trash2 size={13} /> Discard
        </button>

        <button onClick={onSave} className="btn-primary flex items-center gap-2">
          <Save size={14} /> Save to Workspace
        </button>

  );
}

// ── History card ─────────────────────────────────────────────────────────────
function HistoryItem({ item }) {
  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;
  const when = new Date(item.savedAt);
  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });

  return (

      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
        <TypeIcon size={14} className={TypeCfg.color} />

{item.title}

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

          )}
          {item.priority && (
            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
          )}
          {timeStr}

  );
}

// ── Main component ────────────────────────────────────────────────────────────
export default function QuickNote() {
  const [text, setText]           = useState('');
  const [listening, setListening] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]       = useState(null);
  const [editData, setEditData]   = useState(null);
  const [projects, setProjects]   = useState([]);
  const [history, setHistory]     = useState(loadHistory);
  const [showExamples, setShowEx] = useState(false);
  const recognitionRef = useRef(null);
  const textareaRef    = useRef(null);

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

  // Voice
  const startVoice = () => {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { toast.error('Voice input not supported in this browser'); return; }
    const r = new SR();
    r.lang = 'en-US'; r.interimResults = false;
    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };
    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };
    r.onend    = () => setListening(false);
    recognitionRef.current = r;
    r.start(); setListening(true);
  };
  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type or speak something first'); return; }
    setProcessing(true);
    try {
      const result = await api.post('/ai/parse', { text });
      setParsed(result);
      setEditData({ ...result });
    } catch (e) {
      toast.error('AI parsing failed: ' + e.message);
    } finally { setProcessing(false); }
  };

  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));

  // Save to workspace
  const save = async () => {
    if (!editData) return;
    try {
      const d = editData;
      if (d.type === 'task') {
        await api.post('/tasks', {
          title: d.title, notes: d.details, category: d.category, priority: d.priority,
          assignee: d.assignee || '', due_date: d.due || '',
          is_follow_up: d.isFollowUp ? 1 : 0,
          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
        });
        toast.success('Task saved!');
      } else if (d.type === 'note') {
        await api.post('/notes', { title: d.title, body: d.details });
        toast.success('Note saved!');
      } else {
        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
        toast.success('Project created!');
      }
      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
      setHistory(loadHistory());
      setParsed(null); setEditData(null); setText('');
      textareaRef.current?.focus();
    } catch (e) { toast.error(e.message); }
  };

  const discard = () => { setParsed(null); setEditData(null); };

  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };

  return (

      {/* Header */}

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

Quick Note

Speak or type — AI structures it instantly

      {/* Main content — horizontal split on desktop */}

        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}

          {/* Input card */}

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Toolbar */}

              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}
              <button
                onClick={() => setShowEx(!showExamples)}
                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
              >
                <Lightbulb size={13} />
                Examples
              </button>

              {text.trim() && !processing && !parsed && (
                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
                  Clear
                </button>
              )}

              <button
                onClick={process}
                disabled={!text.trim() || processing || !!parsed}
                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
              >
                {processing ? (
                  <> Parsing…</>
                ) : (
                  <><Sparkles size={14} /> Process ⌘↵</>
                )}
              </button>

            {/* Example suggestions */}
            {showExamples && (

Try these

                {EXAMPLES.map((ex, i) => (
                  <button key={i} onClick={() => useExample(ex)}
                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
                    {ex}
                  </button>
                ))}

            )}

          {/* Parsed result */}
          {editData && (
            <ParsedCard
              data={editData}
              onChange={changeField}
              projects={projects}
              onSave={save}
              onDiscard={discard}
            />
          )}

          {/* Empty state when no parsed result */}
          {!editData && !processing && (

              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />

Type or speak, then click Process

Claude will parse it into a task, note, or project

          )}

        {/* ── RIGHT: History ──────────────────────────────────────────── */}

Recent Captures

Last {history.length} items saved via Quick Note

          {history.length === 0 ? (

              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />

Nothing captured yet

Your saved items will appear here

          ) : (

              {history.map((item, i) => <HistoryItem key={i} item={item} />)}

          )}

          {/* Tip box */}

Pro tip

              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.

  );
}

-  const [text, setText]           = useState('');

-  const [listening, setListening] = useState(false);

+  const [text, setText]             = useState('');

-  const [parsed, setParsed]       = useState(null);

-  const [editData, setEditData]   = useState(null);

-  const [projects, setProjects]   = useState([]);

-  const [history, setHistory]     = useState(loadHistory);

-  const [showExamples, setShowEx] = useState(false);

+  const [parsed, setParsed]         = useState(null);

+  const [editData, setEditData]     = useState(null);

+  const [projects, setProjects]     = useState([]);

+  const [history, setHistory]       = useState(loadHistory);

+  const [showExamples, setShowEx]   = useState(false);

-    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;

-    if (!SR) { toast.error('Voice input not supported in this browser'); return; }

-    r.lang = 'en-US'; r.interimResults = false;

-    r.onresult = e => { setText(e.results[0][0].transcript); toast.success('Voice captured!'); };

-    r.onerror  = () => { setListening(false); toast.error('Voice capture failed'); };

-    r.onend    = () => setListening(false);

-  const stopVoice = () => { recognitionRef.current?.stop(); setListening(false); };


  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type or speak something first'); return; }

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type something first'); return; }


  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type something first'); return; }

import { useState, useEffect, useRef } from 'react';
import {
  Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock,
  User, Calendar, Zap, ArrowRight
} from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';

const HISTORY_KEY = 'quicknote_history';
function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
function pushHistory(item) {
  const h = loadHistory();
  h.unshift({ ...item, savedAt: new Date().toISOString() });
  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
}

const TYPE_CONFIG = {
  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
};

const EXAMPLES = [
  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
  'Note: Google NDA meeting happened — next step is Legal Affairs review',
  'New project: AI Ethics workshop for Champions Program, strategic initiative',
];

// ── Parsed result card ───────────────────────────────────────────────────────
function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;

  return (

      {/* Card header */}

        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
          <TypeIcon size={15} className={TypeCfg.color} />

AI Parsed Result

Review and edit before saving

        <select
          value={data.type}
          onChange={e => onChange('type', e.target.value)}
          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
        >
          <option value="task">Task</option>
          <option value="note">Note</option>
          <option value="project">Project</option>
        </select>

        {/* Title */}

          Title
          <input
            className="input font-semibold text-base"
            value={data.title}
            onChange={e => onChange('title', e.target.value)}
            placeholder="Title…"
          />

        {/* Category + Priority */}

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

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

        {/* Task-specific fields */}
        {data.type === 'task' && (

              <User size={10} /> Assignee
              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />

              <Calendar size={10} /> Due Date
              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />

        )}

        {/* Details */}

          Details / Notes
          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />

        {/* Task checkboxes */}
        {data.type === 'task' && (

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
              Follow-up needed

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
              Pin to today

        )}

        {/* Project hint */}
        {data.projectHint && (

            <Lightbulb size={13} className="text-amber-600 shrink-0" />

              Suggested project: {data.projectHint}

        )}

      {/* Actions */}

        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
          <Trash2 size={13} /> Discard
        </button>

        <button onClick={onSave} className="btn-primary flex items-center gap-2">
          <Save size={14} /> Save to Workspace
        </button>

  );
}

// ── History card ─────────────────────────────────────────────────────────────
function HistoryItem({ item }) {
  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;
  const when = new Date(item.savedAt);
  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });

  return (

      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
        <TypeIcon size={14} className={TypeCfg.color} />

{item.title}

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

          )}
          {item.priority && (
            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
          )}
          {timeStr}

  );
}

// ── Main component ────────────────────────────────────────────────────────────
export default function QuickNote() {
  const [text, setText]             = useState('');
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]         = useState(null);
  const [editData, setEditData]     = useState(null);
  const [projects, setProjects]     = useState([]);
  const [history, setHistory]       = useState(loadHistory);
  const [showExamples, setShowEx]   = useState(false);
  const textareaRef = useRef(null);

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

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type or speak something first'); return; }
    setProcessing(true);
    try {
      const result = await api.post('/ai/parse', { text });
      setParsed(result);
      setEditData({ ...result });
    } catch (e) {
      toast.error('AI parsing failed: ' + e.message);
    } finally { setProcessing(false); }
  };

  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));

  // Save to workspace
  const save = async () => {
    if (!editData) return;
    try {
      const d = editData;
      if (d.type === 'task') {
        await api.post('/tasks', {
          title: d.title, notes: d.details, category: d.category, priority: d.priority,
          assignee: d.assignee || '', due_date: d.due || '',
          is_follow_up: d.isFollowUp ? 1 : 0,
          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
        });
        toast.success('Task saved!');
      } else if (d.type === 'note') {
        await api.post('/notes', { title: d.title, body: d.details });
        toast.success('Note saved!');
      } else {
        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
        toast.success('Project created!');
      }
      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
      setHistory(loadHistory());
      setParsed(null); setEditData(null); setText('');
      textareaRef.current?.focus();
    } catch (e) { toast.error(e.message); }
  };

  const discard = () => { setParsed(null); setEditData(null); };

  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };

  return (

      {/* Header */}

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

Quick Note

Speak or type — AI structures it instantly

      {/* Main content — horizontal split on desktop */}

        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}

          {/* Input card */}

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Toolbar */}

              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}
              <button
                onClick={() => setShowEx(!showExamples)}
                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
              >
                <Lightbulb size={13} />
                Examples
              </button>

              {text.trim() && !processing && !parsed && (
                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
                  Clear
                </button>
              )}

              <button
                onClick={process}
                disabled={!text.trim() || processing || !!parsed}
                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
              >
                {processing ? (
                  <> Parsing…</>
                ) : (
                  <><Sparkles size={14} /> Process ⌘↵</>
                )}
              </button>

            {/* Example suggestions */}
            {showExamples && (

Try these

                {EXAMPLES.map((ex, i) => (
                  <button key={i} onClick={() => useExample(ex)}
                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
                    {ex}
                  </button>
                ))}

            )}

          {/* Parsed result */}
          {editData && (
            <ParsedCard
              data={editData}
              onChange={changeField}
              projects={projects}
              onSave={save}
              onDiscard={discard}
            />
          )}

          {/* Empty state when no parsed result */}
          {!editData && !processing && (

              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />

Type or speak, then click Process

Claude will parse it into a task, note, or project

          )}

        {/* ── RIGHT: History ──────────────────────────────────────────── */}

Recent Captures

Last {history.length} items saved via Quick Note

          {history.length === 0 ? (

              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />

Nothing captured yet

Your saved items will appear here

          ) : (

              {history.map((item, i) => <HistoryItem key={i} item={item} />)}

          )}

          {/* Tip box */}

Pro tip

              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.

  );
}

-    if (!text.trim()) { toast.error('Type or speak something first'); return; }

+    if (!text.trim()) { toast.error('Type something first'); return; }


            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              rows={5}
              placeholder={"Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />


            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              rows={5}
              placeholder={"Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

import { useState, useEffect, useRef } from 'react';
import {
  Sparkles, Save, Trash2, Lightbulb,
  CheckSquare, FileText, FolderKanban, Clock,
  User, Calendar, Zap, ArrowRight
} from 'lucide-react';
import toast from 'react-hot-toast';
import api from '../api';
import { CATEGORIES, PRIORITIES, STATUSES, getCategoryClass, getPriorityClass } from '../utils';

const HISTORY_KEY = 'quicknote_history';
function loadHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); } catch { return []; } }
function pushHistory(item) {
  const h = loadHistory();
  h.unshift({ ...item, savedAt: new Date().toISOString() });
  localStorage.setItem(HISTORY_KEY, JSON.stringify(h.slice(0, 8)));
}

const TYPE_CONFIG = {
  task:    { icon: CheckSquare,  color: 'text-primary',   bg: 'bg-primary/10',   label: 'Task'    },
  note:    { icon: FileText,     color: 'text-teal-600',  bg: 'bg-teal-50 dark:bg-teal-900/20',   label: 'Note'    },
  project: { icon: FolderKanban, color: 'text-violet-600',bg: 'bg-violet-50 dark:bg-violet-900/20',label: 'Project' },
};

const EXAMPLES = [
  'Follow up with Hamid about WEF Lighthouse document, urgent by end of week',
  'Benchmark presentation meeting with Shabeer on 13 Apr, high priority',
  'Note: Google NDA meeting happened — next step is Legal Affairs review',
  'New project: AI Ethics workshop for Champions Program, strategic initiative',
];

// ── Parsed result card ───────────────────────────────────────────────────────
function ParsedCard({ data, onChange, projects, onSave, onDiscard }) {
  const TypeCfg = TYPE_CONFIG[data.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;

  return (

      {/* Card header */}

        <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center`}>
          <TypeIcon size={15} className={TypeCfg.color} />

AI Parsed Result

Review and edit before saving

        <select
          value={data.type}
          onChange={e => onChange('type', e.target.value)}
          className="text-xs font-semibold border border-primary/30 rounded-lg px-2.5 py-1.5 bg-white dark:bg-gray-800 text-primary focus:outline-none focus:ring-2 focus:ring-primary/30"
        >
          <option value="task">Task</option>
          <option value="note">Note</option>
          <option value="project">Project</option>
        </select>

        {/* Title */}

          Title
          <input
            className="input font-semibold text-base"
            value={data.title}
            onChange={e => onChange('title', e.target.value)}
            placeholder="Title…"
          />

        {/* Category + Priority */}

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

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

        {/* Task-specific fields */}
        {data.type === 'task' && (

              <User size={10} /> Assignee
              <input className="input text-sm" value={data.assignee || ''} onChange={e => onChange('assignee', e.target.value)} placeholder="Person name" />

              <Calendar size={10} /> Due Date
              <input type="date" className="input text-sm" value={data.due || ''} onChange={e => onChange('due', e.target.value)} />

        )}

        {/* Details */}

          Details / Notes
          <textarea className="input resize-none text-sm" rows={3} value={data.details || ''} onChange={e => onChange('details', e.target.value)} placeholder="Context…" />

        {/* Task checkboxes */}
        {data.type === 'task' && (

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.isFollowUp} onChange={e => onChange('isFollowUp', e.target.checked)} />
              Follow-up needed

              <input type="checkbox" className="w-4 h-4 rounded accent-primary" checked={!!data.suggestedTodayFocus} onChange={e => onChange('suggestedTodayFocus', e.target.checked)} />
              Pin to today

        )}

        {/* Project hint */}
        {data.projectHint && (

            <Lightbulb size={13} className="text-amber-600 shrink-0" />

              Suggested project: {data.projectHint}

        )}

      {/* Actions */}

        <button onClick={onDiscard} className="btn-ghost flex items-center gap-1.5 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20">
          <Trash2 size={13} /> Discard
        </button>

        <button onClick={onSave} className="btn-primary flex items-center gap-2">
          <Save size={14} /> Save to Workspace
        </button>

  );
}

// ── History card ─────────────────────────────────────────────────────────────
function HistoryItem({ item }) {
  const TypeCfg = TYPE_CONFIG[item.type] || TYPE_CONFIG.task;
  const TypeIcon = TypeCfg.icon;
  const when = new Date(item.savedAt);
  const timeStr = when.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });

  return (

      <div className={`w-8 h-8 rounded-xl ${TypeCfg.bg} flex items-center justify-center shrink-0`}>
        <TypeIcon size={14} className={TypeCfg.color} />

{item.title}

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

          )}
          {item.priority && (
            <span className={`badge text-[10px] py-0 ${getPriorityClass(item.priority)}`}>{item.priority}
          )}
          {timeStr}

  );
}

// ── Main component ────────────────────────────────────────────────────────────
export default function QuickNote() {
  const [text, setText]             = useState('');
  const [processing, setProcessing] = useState(false);
  const [parsed, setParsed]         = useState(null);
  const [editData, setEditData]     = useState(null);
  const [projects, setProjects]     = useState([]);
  const [history, setHistory]       = useState(loadHistory);
  const [showExamples, setShowEx]   = useState(false);
  const textareaRef = useRef(null);

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

  // Process with AI
  const process = async () => {
    if (!text.trim()) { toast.error('Type something first'); return; }
    setProcessing(true);
    try {
      const result = await api.post('/ai/parse', { text });
      setParsed(result);
      setEditData({ ...result });
    } catch (e) {
      toast.error('AI parsing failed: ' + e.message);
    } finally { setProcessing(false); }
  };

  const changeField = (k, v) => setEditData(d => ({ ...d, [k]: v }));

  // Save to workspace
  const save = async () => {
    if (!editData) return;
    try {
      const d = editData;
      if (d.type === 'task') {
        await api.post('/tasks', {
          title: d.title, notes: d.details, category: d.category, priority: d.priority,
          assignee: d.assignee || '', due_date: d.due || '',
          is_follow_up: d.isFollowUp ? 1 : 0,
          is_today_focus: d.suggestedTodayFocus ? 1 : 0,
        });
        toast.success('Task saved!');
      } else if (d.type === 'note') {
        await api.post('/notes', { title: d.title, body: d.details });
        toast.success('Note saved!');
      } else {
        await api.post('/projects', { name: d.title, category: d.category, description: d.details, priority: d.priority });
        toast.success('Project created!');
      }
      pushHistory({ type: d.type, title: d.title, category: d.category, priority: d.priority });
      setHistory(loadHistory());
      setParsed(null); setEditData(null); setText('');
      textareaRef.current?.focus();
    } catch (e) { toast.error(e.message); }
  };

  const discard = () => { setParsed(null); setEditData(null); };

  const useExample = (ex) => { setText(ex); setShowEx(false); textareaRef.current?.focus(); };

  return (

      {/* Header */}

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

Quick Note

Speak or type — AI structures it instantly

      {/* Main content — horizontal split on desktop */}

        {/* ── LEFT: Input + Parsed result ────────────────────────────── */}

          {/* Input card */}

            {/* Textarea */}
            <textarea
              ref={textareaRef}
              value={text}
              onChange={e => setText(e.target.value)}
              onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') process(); }}
              disabled={listening}
              rows={5}
              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}
              className="w-full px-5 pt-5 pb-3 text-sm bg-transparent border-none outline-none resize-none text-gray-900 dark:text-white placeholder-gray-300 dark:placeholder-gray-600 font-medium leading-relaxed"
            />

            {/* Toolbar */}

              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}
              <button
                onClick={() => setShowEx(!showExamples)}
                className="flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
              >
                <Lightbulb size={13} />
                Examples
              </button>

              {text.trim() && !processing && !parsed && (
                <button onClick={() => { setText(''); discard(); }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 px-2 transition-colors">
                  Clear
                </button>
              )}

              <button
                onClick={process}
                disabled={!text.trim() || processing || !!parsed}
                className="btn-primary flex items-center gap-2 py-2 text-sm disabled:opacity-40"
              >
                {processing ? (
                  <> Parsing…</>
                ) : (
                  <><Sparkles size={14} /> Process ⌘↵</>
                )}
              </button>

            {/* Example suggestions */}
            {showExamples && (

Try these

                {EXAMPLES.map((ex, i) => (
                  <button key={i} onClick={() => useExample(ex)}
                    className="flex items-center gap-2 w-full text-left px-3 py-2 rounded-xl text-xs text-gray-600 dark:text-gray-400 hover:bg-white dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white transition-colors group">
                    <ArrowRight size={11} className="shrink-0 text-gray-400 group-hover:text-primary transition-colors" />
                    {ex}
                  </button>
                ))}

            )}

          {/* Parsed result */}
          {editData && (
            <ParsedCard
              data={editData}
              onChange={changeField}
              projects={projects}
              onSave={save}
              onDiscard={discard}
            />
          )}

          {/* Empty state when no parsed result */}
          {!editData && !processing && (

              <Sparkles size={32} className="text-gray-300 dark:text-gray-700 mb-3" />

Type or speak, then click Process

Claude will parse it into a task, note, or project

          )}

        {/* ── RIGHT: History ──────────────────────────────────────────── */}

Recent Captures

Last {history.length} items saved via Quick Note

          {history.length === 0 ? (

              <Clock size={28} className="text-gray-200 dark:text-gray-700 mb-3" />

Nothing captured yet

Your saved items will appear here

          ) : (

              {history.map((item, i) => <HistoryItem key={i} item={item} />)}

          )}

          {/* Tip box */}

Pro tip

              Press ⌘ Enter to process instantly. Mention a person's name and AI will auto-assign.

  );
}

-              placeholder={listening ? 'Listening… speak now' : "Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}

+              placeholder={"Type anything — task, idea, follow-up, meeting note…\n\nExample: \"Follow up with Hamid on WEF doc, urgent, this week\""}


            {/* Toolbar */}
            <div className="flex items-center gap-2 px-4 pb-3 pt-1">
              {/* Voice */}
              <button
                onClick={listening ? stopVoice : startVoice}
                className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-sm font-medium transition-all ${
                  listening
                    ? 'bg-red-500 text-white animate-pulse shadow-md'
                    : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700'
                }`}
              >
                {listening ? <MicOff size={14} /> : <Mic size={14} />}
                {listening ? 'Stop' : 'Voice'}
              </button>

              {/* Examples */}

            {/* Toolbar */}
            <div className="flex items-center gap-2 px-4 pb-3 pt-1">
              {/* Examples */}