154 lines
5.4 KiB
JavaScript
154 lines
5.4 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { useAuth } from '../../hooks/useAuth';
|
|
import { getSharedDocuments } from '../../services/api';
|
|
import { format } from 'date-fns';
|
|
import { FiFolder, FiFile, FiDownload, FiChevronRight, FiLoader } from 'react-icons/fi';
|
|
import { downloadDocument } from '../../services/api';
|
|
|
|
function Dashboard() {
|
|
const [documents, setDocuments] = useState({});
|
|
const [expandedFolders, setExpandedFolders] = useState({});
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState('');
|
|
const { user } = useAuth();
|
|
|
|
useEffect(() => {
|
|
const fetchDocuments = async () => {
|
|
try {
|
|
if (!user?.id) return;
|
|
|
|
const response = await getSharedDocuments(user.id);
|
|
// Group the documents by company and date
|
|
const groupedDocs = groupDocumentsByCompanyAndDate(response.data);
|
|
setDocuments(groupedDocs);
|
|
} catch (err) {
|
|
console.error('Error fetching documents:', err);
|
|
setError('Failed to fetch documents');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchDocuments();
|
|
}, [user]);
|
|
|
|
const groupDocumentsByCompanyAndDate = (docs) => {
|
|
if (!Array.isArray(docs)) {
|
|
console.error('Expected array of documents, received:', docs);
|
|
return {};
|
|
}
|
|
|
|
return docs.reduce((acc, doc) => {
|
|
const folderName = `${doc.sharedWith?.name || 'Unknown'}-${format(new Date(doc.createdAt), 'yyyy-MM-dd')}`;
|
|
if (!acc[folderName]) {
|
|
acc[folderName] = [];
|
|
}
|
|
acc[folderName].push(doc);
|
|
return acc;
|
|
}, {});
|
|
};
|
|
|
|
const handleDownload = async (s3Key, fileName) => {
|
|
try {
|
|
await downloadDocument(s3Key);
|
|
} catch (err) {
|
|
console.error('Error downloading document:', err);
|
|
alert('Failed to download document. Please try again.');
|
|
}
|
|
};
|
|
|
|
const toggleFolder = (folderName) => {
|
|
setExpandedFolders(prev => ({
|
|
...prev,
|
|
[folderName]: !prev[folderName]
|
|
}));
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-gray-900">
|
|
<div className="flex items-center space-x-3 text-blue-500">
|
|
<FiLoader className="w-6 h-6 animate-spin" />
|
|
<span className="text-lg font-medium">Loading documents...</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-gray-900">
|
|
<div className="p-4 bg-red-500/10 border border-red-500/20 rounded-lg text-red-200">
|
|
{error}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800 p-6">
|
|
<div className="max-w-7xl mx-auto">
|
|
<header className="mb-8 mt-20">
|
|
<h1 className="text-3xl font-bold text-white mb-2">Your Documents</h1>
|
|
<p className="text-gray-400">Access and manage your shared documents</p>
|
|
</header>
|
|
|
|
<div className="grid gap-6">
|
|
{Object.entries(documents).length > 0 ? (
|
|
Object.entries(documents).map(([folderName, docs]) => (
|
|
<div
|
|
key={folderName}
|
|
className="bg-white/5 backdrop-blur-lg rounded-xl overflow-hidden transition-all duration-200 hover:bg-white/10"
|
|
>
|
|
<button
|
|
onClick={() => toggleFolder(folderName)}
|
|
className="w-full px-6 py-4 flex items-center justify-between text-white hover:bg-white/5 transition-colors"
|
|
>
|
|
<div className="flex items-center space-x-3">
|
|
<FiFolder className="w-5 h-5 text-blue-400" />
|
|
<span className="font-medium">{folderName}</span>
|
|
<span className="text-sm text-gray-400">({docs.length} files)</span>
|
|
</div>
|
|
<FiChevronRight
|
|
className={`w-5 h-5 transition-transform duration-200 ${
|
|
expandedFolders[folderName] ? 'rotate-90' : ''
|
|
}`}
|
|
/>
|
|
</button>
|
|
|
|
{expandedFolders[folderName] && (
|
|
<div className="border-t border-gray-700">
|
|
{docs.map((doc) => (
|
|
<div
|
|
key={doc.id}
|
|
className="px-6 py-3 flex items-center justify-between hover:bg-white/5 transition-colors"
|
|
>
|
|
<div className="flex items-center space-x-3">
|
|
<FiFile className="w-4 h-4 text-gray-400" />
|
|
<span className="text-gray-200">{doc.title}</span>
|
|
</div>
|
|
<button
|
|
onClick={() => handleDownload(doc.s3Key)}
|
|
className="p-2 text-gray-400 hover:text-blue-400 rounded-lg hover:bg-blue-500/10 transition-colors"
|
|
title="Download document"
|
|
>
|
|
<FiDownload className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
))
|
|
) : (
|
|
<div className="text-center py-12">
|
|
<p className="text-gray-400">No documents available</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default Dashboard; |