DocumentTable Component¶
Overview¶
The DocumentTable component is a comprehensive interface for managing documents within a project. It provides a rich UI for viewing, editing, and collaborating on documents, with features like status tracking, search functionality, and pagination.
Features¶
- Document Management: View, edit, and manage documents within a project
- Status Tracking: Track document status (In Progress, Completed) with visual progress indicators
- Search Functionality: Filter documents by name
- Pagination: Navigate through multiple pages of documents
- Collaboration: Manage document collaborators
- Responsive Design: Adapts to different screen sizes with a clean, modern interface
Implementation¶
The component is built using React with Framer Motion for animations and integrates with the BidScript API for document management.
import React, { useEffect, useState, useMemo, useRef } from "react";
import { useRouter } from "next/navigation";
import { motion, AnimatePresence } from "framer-motion";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { CollaboratorCard } from "./collaboratorCard";
import { useLoadingFetch } from "@/hooks/useLoadingFetch";
import { useLoading } from "@/components/LoadingContext";
import { LoadingOverlay } from "@/components/LoadingOverlay";
import { Card, CardContent } from "@/components/ui/card";
import {
FileText,
Users,
Calendar,
Clock,
Edit3,
Eye,
UserPlus,
ArrowLeft,
} from "lucide-react";
// Component implementation...
Props¶
| Prop | Type | Description |
|---|---|---|
userID |
string | The ID of the current user |
projectID |
string | null | The ID of the current project |
selectedProjectName |
string | The name of the current project |
onBackToProjects |
function | Callback function to navigate back to projects view |
State Management¶
The component manages several state variables:
| State Variable | Type | Description |
|---|---|---|
documents |
array | Stores the list of documents in the project |
currentPage |
number | Current page in pagination |
totalPages |
number | Total number of pages |
editingDocument |
string | null | ID of document being edited, or null |
searchTerm |
string | Current search filter |
collaborators |
array | List of document collaborators |
isCollaboratorCardOpen |
boolean | Controls visibility of collaborator management UI |
Document Operations¶
Fetching Documents¶
useEffect(() => {
const fetchDocuments = async () => {
try {
const response = await fetch("/app/api/documents/getProjectDocuments", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ userID, projectID }),
});
if (!response.ok) {
throw new Error("Failed to fetch documents.");
}
const data = await response.json();
setDocuments(data);
setTotalPages(Math.ceil(data.length / rowsPerPage));
} catch (error) {
console.error("Error fetching documents:", error);
} finally {
setIsLoading(false);
}
};
if (userID && projectID) {
fetchDocuments();
}
}, [userID, projectID]);
Editing Documents¶
const handleConfirmEdit = async (documentID: string) => {
try {
const updatedDocument = await fetchWithLoading(async () => {
const response = await fetch("/app/api/documents/updateDocumentInfo", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
documentId: documentID,
userId: userID,
documentName: editedDocumentName,
clientName: editedClientName,
}),
});
if (!response.ok) {
throw new Error("Failed to update document.");
}
return response.json();
});
setDocuments((prev) =>
prev.map((doc) => (doc.DocumentID === documentID ? updatedDocument : doc))
);
setEditingDocument(null);
} catch (error) {
console.error("Error updating document:", error);
}
};
Changing Document Status¶
const handleStatusChange = async (documentID: string, newStatus: string) => {
try {
const updatedDocument = await fetchWithLoading(async () => {
const response = await fetch("/app/api/documents/setDocumentStatus", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
DocumentID: documentID,
UserID: userID,
Status: newStatus,
}),
});
if (response.status === 403) {
setShowUserNotAuthorisedError(true);
return null;
}
if (!response.ok) {
throw new Error("Failed to update status.");
}
return response.json();
});
if (updatedDocument) {
setDocuments((prev) =>
prev.map((doc) =>
doc.DocumentID === documentID ? updatedDocument : doc
)
);
setDropdownOpenDocumentID(null);
}
} catch (error) {
console.error("Error updating status:", error);
}
};
UI Components¶
The DocumentTable consists of several key UI elements:
- Project Header: Displays project name with back navigation
- Progress Bar: Visual indicator of project completion status
- Search Bar: Filter documents by name
- Document Cards: Display document information with actions
- Edit document name and client
- Change document status
- View document
- Manage collaborators
- Pagination Controls: Navigate through multiple pages of documents
Animations¶
The component uses Framer Motion for smooth animations:
- Fade and slide animations for document cards
- Progress bar animations
- Dropdown menu animations for status changes
Usage¶
import { DocumentTableComponent } from "@/components/resourceHub/document-table";
const ProjectView = ({ userID, projectID, projectName }) => {
const handleBackToProjects = () => {
// Navigation logic
};
return (
<div className="project-container">
<DocumentTableComponent
userID={userID}
projectID={projectID}
selectedProjectName={projectName}
onBackToProjects={handleBackToProjects}
/>
</div>
);
};
Integration with Other Components¶
- Uses
CollaboratorCardfor managing document collaborators - Integrates with
LoadingContextandLoadingOverlayfor loading states - Uses custom UI components from the application's component library