'use client'; import { useState, useRef } from 'react'; import { Send, Upload, Check, AlertCircle, FileText, Plus } from 'lucide-react'; const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'; interface LogResponse { success: boolean; file_path: string; timestamp: string; message: string; } interface UploadResponse { success: boolean; file_path: string; filename: string; size_bytes: number; message: string; } export default function CapturePage() { // Log state const [logContent, setLogContent] = useState(''); const [logTitle, setLogTitle] = useState(''); const [logTags, setLogTags] = useState(''); const [logStatus, setLogStatus] = useState<'idle' | 'sending' | 'success' | 'error'>('idle'); const [logMessage, setLogMessage] = useState(''); // Upload state const [uploadStatus, setUploadStatus] = useState<'idle' | 'uploading' | 'success' | 'error'>('idle'); const [uploadMessage, setUploadMessage] = useState(''); const [uploadFolder, setUploadFolder] = useState('documents'); const [uploadTags, setUploadTags] = useState(''); const fileInputRef = useRef(null); const handleLogSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!logContent.trim()) return; setLogStatus('sending'); setLogMessage(''); try { const tags = logTags.split(',').map(t => t.trim()).filter(Boolean); const res = await fetch(`${API_BASE}/api/v1/capture/log`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: logContent, title: logTitle || undefined, tags: tags.length > 0 ? tags : undefined, }), }); if (!res.ok) throw new Error(`Failed: ${res.status}`); const data: LogResponse = await res.json(); setLogStatus('success'); setLogMessage(data.message); setLogContent(''); setLogTitle(''); setLogTags(''); // Reset status after 3s setTimeout(() => setLogStatus('idle'), 3000); } catch (err) { setLogStatus('error'); setLogMessage(err instanceof Error ? err.message : 'Failed to save log'); } }; const handleFileUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setUploadStatus('uploading'); setUploadMessage(''); try { const formData = new FormData(); formData.append('file', file); formData.append('folder', uploadFolder); if (uploadTags) { formData.append('tags', uploadTags); } const res = await fetch(`${API_BASE}/api/v1/capture/upload`, { method: 'POST', body: formData, }); if (!res.ok) { const errData = await res.json().catch(() => ({})); throw new Error(errData.detail || `Upload failed: ${res.status}`); } const data: UploadResponse = await res.json(); setUploadStatus('success'); setUploadMessage(`${data.filename} uploaded (${(data.size_bytes / 1024).toFixed(1)} KB)`); // Reset if (fileInputRef.current) fileInputRef.current.value = ''; setTimeout(() => setUploadStatus('idle'), 3000); } catch (err) { setUploadStatus('error'); setUploadMessage(err instanceof Error ? err.message : 'Upload failed'); } }; return (

Quick Capture

Add notes to your Second Brain or upload documents for indexing.

{/* Quick Log Section */}

Quick Log

setLogTitle(e.target.value)} className="flex-1 bg-slate-700 border border-slate-600 rounded-lg px-4 py-2 text-white placeholder-slate-400 focus:outline-none focus:border-brain-500" /> setLogTags(e.target.value)} className="w-64 bg-slate-700 border border-slate-600 rounded-lg px-4 py-2 text-white placeholder-slate-400 focus:outline-none focus:border-brain-500" />