"use client"; import { useState, useMemo, useCallback } from 'react'; import { DashboardLayout } from '@/components/layout/sidebar'; import { PageHeader } from '@/components/layout/page-header'; // SupabaseTest removed - using API route instead import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Textarea } from '@/components/ui/textarea'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { FileText, Folder, Search, Plus, FileCode, FileType, File as FileIcon, Clock, Tag, Edit3, Trash2, Eye, X, Filter, Save, FolderPlus, Clock3, Hash, LayoutGrid, List, } from 'lucide-react'; import { MarkdownPreviewDialog } from '@/components/MarkdownPreviewDialog'; import { cn } from '@/lib/utils'; import { useDocuments } from '@/hooks/useDocuments'; import { Document, DocumentType, Folder as FolderType, DOCUMENT_TYPE_COLORS } from '@/types/documents'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; const typeIcons: Record = { markdown: FileType, text: FileText, pdf: FileIcon, code: FileCode, }; function formatFileSize(bytes: number): string { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; } function formatDate(dateString: string): string { const date = new Date(dateString); const now = new Date(); const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60); if (diffInHours < 1) return 'Just now'; if (diffInHours < 24) return `${Math.floor(diffInHours)}h ago`; if (diffInHours < 48) return 'Yesterday'; if (diffInHours < 168) return date.toLocaleDateString('en-US', { weekday: 'short' }); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); } // Document Editor Component function DocumentEditor({ document, onSave, onCancel, folders, }: { document: Document | null; onSave: (doc: Partial) => void; onCancel: () => void; folders: FolderType[]; }) { const [title, setTitle] = useState(document?.title || ''); const [content, setContent] = useState(document?.content || ''); const [folder, setFolder] = useState(document?.folder || 'General'); const [tags, setTags] = useState(document?.tags || []); const [tagInput, setTagInput] = useState(''); const [showPreview, setShowPreview] = useState(false); const handleSave = () => { if (!title.trim()) return; onSave({ title: title.trim(), content: content.trim(), folder, tags, type: 'markdown', }); }; const addTag = () => { const trimmed = tagInput.trim().toLowerCase(); if (trimmed && !tags.includes(trimmed)) { setTags([...tags, trimmed]); setTagInput(''); } }; const removeTag = (tagToRemove: string) => { setTags(tags.filter((t) => t !== tagToRemove)); }; return (
setTitle(e.target.value)} className="text-base sm:text-lg font-semibold bg-transparent border-0 border-b rounded-none px-0 focus-visible:ring-0 focus-visible:border-primary" />
{tags.map((tag) => ( {tag} ))}
setTagInput(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addTag(); } }} className="w-24 h-7 text-xs" />
{showPreview ? (
{content || '*No content*'}
) : (