ScanHistoryTable
A compact, sortable table component for displaying completed scan history. Built with TanStack Table for performance and includes hover actions, relative dates, and card count displays.
Design Principles
- Compact Density: Efficient space usage for scanning large lists
- Sortable Columns: Click headers to sort by date, title, or card count
- Hover Actions: Actions appear on row hover to reduce visual clutter
- Relative Dates: Human-friendly "Today", "Yesterday", "2 days ago" formatting
- Status Badges: Subtle, color-coded status indicators
- Mobile Responsive: Adapts to smaller screens with always-visible actions
Example
Complete History Table
Scan Title | Status | Cards | Uploaded | Actions |
|---|---|---|---|---|
| Pokemon Collection Batch 1 | completed | 12 | Oct 22, 2025 | |
| Vintage Cards Scan | review pending | 8 | Oct 19, 2025 | |
| Japanese Cards Test | completed | 6 | Oct 17, 2025 | |
| Cancelled Upload | cancelled | — | Oct 10, 2025 |
Usage
import { ScanHistoryTable } from '@/components/ui/ScanHistoryTable';
// Basic usage
<ScanHistoryTable
uploads={historyUploads}
onRename={handleRename}
onDelete={handleDelete}
/>Interface
interface ScanUpload {
id: string;
created_at: string;
scan_title: string;
processing_status: 'queued' | 'processing' | 'review_pending' | 'failed' | 'timeout' | 'cancelled' | 'completed';
results?: {
summary_image_path?: string;
total_cards_detected?: number;
};
error_message?: string;
}
interface ScanHistoryTableProps {
uploads: ScanUpload[];
onRename?: (upload: ScanUpload) => void;
onDelete?: (uploadId: string, title: string) => void;
}TanStack Table Integration
// Built-in TanStack Table features
const table = useReactTable({
data: uploads,
columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
onSortingChange: setSorting,
state: { sorting },
});
// Default sorting: Most recent first
const [sorting, setSorting] = useState([
{ id: 'created_at', desc: true }
]);Column Structure
Scan Title
Clickable link to scan details page. Falls back to "Untitled Scan" if empty.
Status
Color-coded badge showing completion state (completed, review_pending, cancelled).
Cards
Number of detected cards with 🃏 icon. Shows "—" if no results available.
Upload Date
Relative time format (Today, Yesterday, Jan 15) for easy scanning.
Actions
Hover-revealed Rename and Delete buttons. Always visible on mobile.
Status Styling
Best Practices
✅ Do
- Use for completed/historical items only
- Filter to appropriate statuses (completed, review_pending, cancelled)
- Provide meaningful scan titles for easy identification
- Implement sorting by date for better UX
- Use in bottom section below priority items
❌ Don't
- Include pending/processing items (use ProcessingQueueCard)
- Show more than 50 items without pagination
- Override hover action behavior
- Use for real-time updating data
- Remove the sortable functionality
Technical Notes
Performance
TanStack Table provides virtual scrolling capabilities for large datasets. Built-in sorting and filtering are highly optimized.
Accessibility
Includes proper ARIA labels, keyboard navigation, and screen reader support through semantic table structure.
Mobile Responsiveness
Actions are always visible on mobile devices to avoid touch interaction issues with hover states.