"use client"; import { useState, useCallback } from "react"; import type { DocInfo } from "@/app/dashboard/page"; import { api } from "@/lib/api"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Progress } from "@/components/ui/progress"; import { FileText, Upload, Trash2, FileCheck, Clock, AlertCircle, Loader2, FolderOpen, } from "lucide-react"; import { useDropzone } from "react-dropzone"; interface Props { documents: DocInfo[]; activeDoc: DocInfo | null; onSelectDoc: (doc: DocInfo) => void; onDocumentsChange: () => void; } export default function DocumentSidebar({ documents, activeDoc, onSelectDoc, onDocumentsChange }: Props) { const [uploading, setUploading] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [deleting, setDeleting] = useState(null); const onDrop = useCallback( async (acceptedFiles: File[]) => { if (acceptedFiles.length === 0) return; setUploading(true); setUploadProgress(0); try { for (let i = 0; i < acceptedFiles.length; i++) { const formData = new FormData(); formData.append("file", acceptedFiles[i]); await api.postForm("/api/v1/documents/upload", formData); setUploadProgress(((i + 1) / acceptedFiles.length) * 100); } onDocumentsChange(); } catch (err) { console.error("Upload failed:", err); } finally { setUploading(false); setUploadProgress(0); } }, [onDocumentsChange] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: { "application/pdf": [".pdf"], "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"], "text/plain": [".txt"], "text/markdown": [".md"], }, disabled: uploading, }); const handleDelete = async (docId: string, e: React.MouseEvent) => { e.stopPropagation(); if (!confirm("Delete this document and all its data?")) return; setDeleting(docId); try { await api.delete(`/api/v1/documents/${docId}`); onDocumentsChange(); } catch (err) { console.error("Delete failed:", err); } finally { setDeleting(null); } }; const statusIcon = (status: string) => { switch (status) { case "ready": return ; case "processing": return ; case "pending": return ; case "failed": return ; default: return ; } }; const formatSize = (bytes: number) => { if (bytes < 1024) return `${bytes} B`; if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / 1048576).toFixed(1)} MB`; }; return (
{/* ── Upload Zone ─────────────────────────────── */}
{uploading ? (

Uploading...

) : ( <>

{isDragActive ? "Drop files here" : "Drop files or click to upload"}

PDF, DOCX, TXT, MD (max 50MB)

)}
{/* ── Documents List ──────────────────────────── */}

Documents ({documents.length})

{documents.length === 0 ? (

No documents yet

Upload a file to get started

) : (
{documents.map((doc) => (
))}
)} ); }