import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Box,
Typography,
Grid,
Card,
CardContent,
CardActions,
Button,
Chip,
IconButton,
ToggleButton,
ToggleButtonGroup,
TextField,
InputAdornment,
Stack,
Menu,
MenuItem,
ListItemIcon,
ListItemText,
Divider,
CircularProgress,
Alert,
} from '@mui/material';
import {
GridView as GridViewIcon,
ViewList as ListViewIcon,
Search as SearchIcon,
FilterList as FilterIcon,
Sort as SortIcon,
Download as DownloadIcon,
PictureAsPdf as PdfIcon,
Image as ImageIcon,
Description as DocIcon,
TextSnippet as TextIcon,
MoreVert as MoreIcon,
CalendarToday as DateIcon,
Storage as SizeIcon,
Visibility as ViewIcon,
} from '@mui/icons-material';
import { documentService } from '../services/api';
const DocumentsPage = () => {
const navigate = useNavigate();
const [documents, setDocuments] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [viewMode, setViewMode] = useState('grid');
const [searchQuery, setSearchQuery] = useState('');
const [sortBy, setSortBy] = useState('created_at');
const [sortOrder, setSortOrder] = useState('desc');
// Menu states
const [sortMenuAnchor, setSortMenuAnchor] = useState(null);
const [docMenuAnchor, setDocMenuAnchor] = useState(null);
const [selectedDoc, setSelectedDoc] = useState(null);
useEffect(() => {
fetchDocuments();
}, []);
const fetchDocuments = async () => {
try {
setLoading(true);
const response = await documentService.list(100, 0);
setDocuments(response.data);
} catch (err) {
setError('Failed to load documents');
console.error(err);
} finally {
setLoading(false);
}
};
const handleDownload = async (doc) => {
try {
const response = await documentService.download(doc.id);
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', doc.original_filename);
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
} catch (err) {
console.error('Download failed:', err);
}
};
const getFileIcon = (mimeType) => {
if (mimeType.includes('pdf')) return ;
if (mimeType.includes('image')) return ;
if (mimeType.includes('text')) return ;
return ;
};
const formatFileSize = (bytes) => {
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
if (bytes === 0) return '0 Bytes';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
};
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
};
const filteredDocuments = documents.filter(doc =>
doc.original_filename.toLowerCase().includes(searchQuery.toLowerCase()) ||
doc.tags.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase()))
);
const sortedDocuments = [...filteredDocuments].sort((a, b) => {
let aValue = a[sortBy];
let bValue = b[sortBy];
if (sortBy === 'created_at') {
aValue = new Date(aValue);
bValue = new Date(bValue);
}
if (sortOrder === 'asc') {
return aValue > bValue ? 1 : -1;
} else {
return aValue < bValue ? 1 : -1;
}
});
if (loading) {
return (
);
}
if (error) {
return (
{error}
);
}
return (
{/* Header */}
Documents
Manage and explore your document library
{/* Toolbar */}
{/* Search */}
setSearchQuery(e.target.value)}
InputProps={{
startAdornment: (
),
}}
sx={{ minWidth: 300, flexGrow: 1 }}
/>
{/* View Toggle */}
newView && setViewMode(newView)}
size="small"
>
{/* Sort Button */}
}
onClick={(e) => setSortMenuAnchor(e.currentTarget)}
size="small"
>
Sort
{/* Sort Menu */}
{/* Document Menu */}
{/* Documents Grid/List */}
{sortedDocuments.length === 0 ? (
No documents found
{searchQuery ? 'Try adjusting your search terms' : 'Upload your first document to get started'}
) : (
{sortedDocuments.map((doc) => (
theme.shadows[4],
},
}}
>
{viewMode === 'grid' && (
{getFileIcon(doc.mime_type)}
)}
{viewMode === 'list' && (
{getFileIcon(doc.mime_type)}
)}
{doc.original_filename}
{doc.has_ocr_text && (
)}
{doc.tags.length > 0 && (
{doc.tags.slice(0, 3).map((tag, index) => (
))}
{doc.tags.length > 3 && (
)}
)}
{formatDate(doc.created_at)}
{
setSelectedDoc(doc);
setDocMenuAnchor(e.currentTarget);
}}
>
{viewMode === 'grid' && (
}
onClick={() => handleDownload(doc)}
fullWidth
>
Download
)}
))}
)}
{/* Results count */}
Showing {sortedDocuments.length} of {documents.length} documents
{searchQuery && ` matching "${searchQuery}"`}
);
};
export default DocumentsPage;