diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index 20e1496..c7f976e 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState, useCallback, useRef } from 'react'; import { createPortal } from 'react-dom'; import { Layout } from '../components/Layout'; import { DrawingCard } from '../components/DrawingCard'; -import { Plus, Search, Loader2, Inbox, Trash2, Folder, ArrowRight, Copy, Upload } from 'lucide-react'; +import { Plus, Search, Loader2, Inbox, Trash2, Folder, ArrowRight, Copy, Upload, CheckSquare, Square, ArrowUp, ArrowDown, ChevronDown, FileText, Calendar, Clock } from 'lucide-react'; import { useNavigate, useSearchParams, useLocation } from 'react-router-dom'; import * as api from '../api'; import type { DrawingSummary, Collection } from '../types'; @@ -73,6 +73,7 @@ export const Dashboard: React.FC = () => { const [selectedIds, setSelectedIds] = useState>(new Set()); const [lastSelectedId, setLastSelectedId] = useState(null); const [showBulkMoveMenu, setShowBulkMoveMenu] = useState(false); + const [showSortMenu, setShowSortMenu] = useState(false); const [drawingToDelete, setDrawingToDelete] = useState(null); const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false); @@ -256,38 +257,35 @@ export const Dashboard: React.FC = () => { return () => window.removeEventListener('keydown', handleKeyDown); }, [sortedDrawings]); - const handleSort = (field: SortField) => { + const handleSortFieldChange = (field: SortField) => { setSortConfig(current => { - if (current.field === field) return { ...current, direction: current.direction === 'asc' ? 'desc' : 'asc' }; - const defaultDirection = field === 'name' ? 'asc' : 'desc'; - return { field, direction: defaultDirection }; + // If changing field, use default direction for that field + if (current.field !== field) { + const defaultDirection = field === 'name' ? 'asc' : 'desc'; + return { field, direction: defaultDirection }; + } + // If same field, keep current direction + return current; }); + setShowSortMenu(false); }; - const SortButton = ({ field, label }: { field: SortField; label: string }) => { - const isActive = sortConfig.field === field; - return ( - - ); + const handleSortDirectionToggle = () => { + setSortConfig(current => ({ + ...current, + direction: current.direction === 'asc' ? 'desc' : 'asc' + })); }; - - const isTrashView = selectedCollectionId === 'trash'; + const sortOptions: { field: SortField; label: string; icon: React.ReactNode }[] = [ + { field: 'name', label: 'Name', icon: }, + { field: 'createdAt', label: 'Date Created', icon: }, + { field: 'updatedAt', label: 'Date Modified', icon: }, + ]; + + const currentSortOption = sortOptions.find(opt => opt.field === sortConfig.field) || sortOptions[0]; + + const isTrashView = selectedCollectionId === 'trash'; const handleCreateDrawing = async () => { if (isTrashView) return; try { @@ -513,6 +511,19 @@ export const Dashboard: React.FC = () => { }, [selectedCollectionId, collections]); const hasSelection = selectedIds.size > 0; + const allSelected = sortedDrawings.length > 0 && selectedIds.size === sortedDrawings.length; + + const handleSelectAll = () => { + if (allSelected) { + // Deselect all + setSelectedIds(new Set()); + setLastSelectedId(null); + } else { + // Select all + const allIds = new Set(sortedDrawings.map(d => d.id)); + setSelectedIds(allIds); + } + }; const handleDrop = async (e: React.DragEvent, targetCollectionId: string | null) => { e.preventDefault(); @@ -685,15 +696,86 @@ export const Dashboard: React.FC = () => { -
- - - +
+
+ + + {showSortMenu && ( + <> +
setShowSortMenu(false)} /> +
+ {sortOptions.map((option) => ( + + ))} +
+ + )} +
+ +
+ +