diff --git a/src/pages/AuditLogs.jsx b/src/pages/AuditLogs.jsx
index 7b3f741..37078a3 100644
--- a/src/pages/AuditLogs.jsx
+++ b/src/pages/AuditLogs.jsx
@@ -8,6 +8,10 @@ const AuditLogs = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ // Pagination states
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemsPerPage, setItemsPerPage] = useState(10);
+
useEffect(() => {
const fetchLogs = async () => {
try {
@@ -20,6 +24,7 @@ const AuditLogs = () => {
if (!res.ok) throw new Error('Failed to fetch system audit logs');
const data = await res.json();
setLogs(data);
+ setCurrentPage(1); // reset to page 1 on fetch
} catch (err) {
setError(err.message);
} finally {
@@ -29,6 +34,13 @@ const AuditLogs = () => {
fetchLogs();
}, [token]);
+ // Compute pagination details
+ const totalItems = logs.length;
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
+ const startIdx = totalItems === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1;
+ const endIdx = Math.min(currentPage * itemsPerPage, totalItems);
+ const currentLogs = logs.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
+
return (
Admin System Audit Logs
@@ -39,48 +51,105 @@ const AuditLogs = () => {
) : error ? (
Error: {error}
) : (
-
-
-
-
- | Log ID |
- Admin User |
- Action |
- Target Object |
- Operation Details |
- Timestamp |
-
-
-
- {logs.map(log => (
-
- | #{log.id} |
- {log.admin_username || log.admin || 'system'} |
-
-
- {log.action}
-
- |
-
- {log.target_type} #{log.target_id || ''}
- |
- {typeof log.details === 'object' ? JSON.stringify(log.details) : log.details} |
-
- {log.performed_at ? new Date(log.performed_at).toLocaleString() : log.time}
- |
+ <>
+
+
+
+
+ | Log ID |
+ Admin User |
+ Action |
+ Target Object |
+ Operation Details |
+ Timestamp |
- ))}
-
-
-
+
+
+ {currentLogs.map(log => (
+
+ | #{log.id} |
+ {log.admin_username || log.admin || 'system'} |
+
+
+ {log.action}
+
+ |
+
+ {log.target_type} #{log.target_id || ''}
+ |
+ {typeof log.details === 'object' ? JSON.stringify(log.details) : log.details} |
+
+ {log.performed_at ? new Date(log.performed_at).toLocaleString() : log.time}
+ |
+
+ ))}
+
+
+
+
+ {/* Pagination Controls */}
+
+
+ Showing {startIdx} to {endIdx} of {totalItems} items
+
+
+
+
+ Items per page:
+
+
+
+
+
+
+ Page {currentPage} of {totalPages || 1}
+
+
+
+
+
+ >
)}
diff --git a/src/pages/customers/CustomerList.jsx b/src/pages/customers/CustomerList.jsx
index b9d3d4f..a410d54 100644
--- a/src/pages/customers/CustomerList.jsx
+++ b/src/pages/customers/CustomerList.jsx
@@ -12,6 +12,10 @@ const CustomerList = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ // Pagination states
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemsPerPage, setItemsPerPage] = useState(10);
+
useEffect(() => {
const fetchCustomers = async () => {
try {
@@ -32,6 +36,7 @@ const CustomerList = () => {
if (!res.ok) throw new Error('Failed to fetch customers');
const data = await res.json();
setCustomers(data);
+ setCurrentPage(1); // Reset page to 1 on filter/search change
} catch (err) {
setError(err.message);
} finally {
@@ -42,6 +47,13 @@ const CustomerList = () => {
fetchCustomers();
}, [searchTerm, filter, token]);
+ // Compute pagination details
+ const totalItems = customers.length;
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
+ const startIdx = totalItems === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1;
+ const endIdx = Math.min(currentPage * itemsPerPage, totalItems);
+ const currentCustomers = customers.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
+
return (
Customer Management
@@ -75,36 +87,93 @@ const CustomerList = () => {
) : error ? (
Error: {error}
) : (
-
-
-
-
- | Customer ID |
- Name |
- Email |
- Phone |
- Status |
- Actions |
-
-
-
- {customers.map(cust => (
-
- | #{cust.id} |
- {cust.name} |
- {cust.email} |
- {cust.phone} |
- |
-
-
- 👁️ View Detail
-
- |
+ <>
+
+
+
+
+ | Customer ID |
+ Name |
+ Email |
+ Phone |
+ Status |
+ Actions |
- ))}
-
-
-
+
+
+ {currentCustomers.map(cust => (
+
+ | #{cust.id} |
+ {cust.name} |
+ {cust.email} |
+ {cust.phone} |
+ |
+
+
+ 👁️ View Detail
+
+ |
+
+ ))}
+
+
+
+
+ {/* Pagination Controls */}
+
+
+ Showing {startIdx} to {endIdx} of {totalItems} items
+
+
+
+
+ Items per page:
+
+
+
+
+
+
+ Page {currentPage} of {totalPages || 1}
+
+
+
+
+
+ >
)}
diff --git a/src/pages/products/ProductList.jsx b/src/pages/products/ProductList.jsx
index 8113b6f..8a740a7 100644
--- a/src/pages/products/ProductList.jsx
+++ b/src/pages/products/ProductList.jsx
@@ -13,6 +13,10 @@ const ProductList = () => {
const [error, setError] = useState(null);
const [selectedProduct, setSelectedProduct] = useState(null);
+ // Pagination states
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemsPerPage, setItemsPerPage] = useState(10);
+
const fetchProducts = async () => {
try {
setLoading(true);
@@ -32,6 +36,7 @@ const ProductList = () => {
if (!res.ok) throw new Error('Failed to fetch products');
const data = await res.json();
setProducts(data);
+ setCurrentPage(1); // Reset page to 1 when filters change
} catch (err) {
setError(err.message);
} finally {
@@ -83,6 +88,18 @@ const ProductList = () => {
(p.supplier_name && p.supplier_name.toLowerCase().includes(searchTerm.toLowerCase()))
);
+ // Reset page when search term changes
+ useEffect(() => {
+ setCurrentPage(1);
+ }, [searchTerm]);
+
+ // Compute pagination details
+ const totalItems = filteredProducts.length;
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
+ const startIdx = totalItems === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1;
+ const endIdx = Math.min(currentPage * itemsPerPage, totalItems);
+ const currentProducts = filteredProducts.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
+
return (
Product Review & Management
@@ -142,73 +159,130 @@ const ProductList = () => {
) : error ? (
Error: {error}
) : (
-
-
-
-
- | ID |
- Product Title |
- Seller |
- Price |
- Stock |
- Status |
- Actions |
-
-
-
- {filteredProducts.map(prod => (
-
- | #{prod.id} |
- setSelectedProduct(prod)}
- >
- {prod.name}
- |
- {prod.supplier_name || 'N/A'} |
- ₹{parseFloat(prod.price).toLocaleString('en-IN')} |
- {prod.stock} items |
- |
-
-
- {(prod.status === 'pending' || prod.status === 'pending_approval') && (
- <>
-
-
-
- >
- )}
- {prod.status === 'approved' && (
- <>
-
-
- >
- )}
- {(prod.status === 'hold' || prod.status === 'on_hold' || prod.status === 'rejected') && (
-
- )}
-
-
- |
+ <>
+
+
+
+
+ | ID |
+ Product Title |
+ Seller |
+ Price |
+ Stock |
+ Status |
+ Actions |
- ))}
-
-
-
+
+
+ {currentProducts.map(prod => (
+
+ | #{prod.id} |
+ setSelectedProduct(prod)}
+ >
+ {prod.name}
+ |
+ {prod.supplier_name || 'N/A'} |
+ ₹{parseFloat(prod.price).toLocaleString('en-IN')} |
+ {prod.stock} items |
+ |
+
+
+ {(prod.status === 'pending' || prod.status === 'pending_approval') && (
+ <>
+
+
+
+ >
+ )}
+ {prod.status === 'approved' && (
+ <>
+
+
+ >
+ )}
+ {(prod.status === 'hold' || prod.status === 'on_hold' || prod.status === 'rejected') && (
+
+ )}
+
+
+ |
+
+ ))}
+
+
+
+
+ {/* Pagination Controls */}
+
+
+ Showing {startIdx} to {endIdx} of {totalItems} items
+
+
+
+
+ Items per page:
+
+
+
+
+
+
+ Page {currentPage} of {totalPages || 1}
+
+
+
+
+
+ >
)}
diff --git a/src/pages/sellers/SellerList.jsx b/src/pages/sellers/SellerList.jsx
index 6588743..d394eae 100644
--- a/src/pages/sellers/SellerList.jsx
+++ b/src/pages/sellers/SellerList.jsx
@@ -12,6 +12,10 @@ const SellerList = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ // Pagination states
+ const [currentPage, setCurrentPage] = useState(1);
+ const [itemsPerPage, setItemsPerPage] = useState(10);
+
useEffect(() => {
const fetchSellers = async () => {
try {
@@ -28,6 +32,7 @@ const SellerList = () => {
if (!res.ok) throw new Error('Failed to fetch sellers');
const data = await res.json();
setSellers(data);
+ setCurrentPage(1); // Reset page to 1 when filter changes
} catch (err) {
setError(err.message);
} finally {
@@ -44,6 +49,18 @@ const SellerList = () => {
return matchesSearch;
});
+ // Reset page when search term changes
+ useEffect(() => {
+ setCurrentPage(1);
+ }, [searchTerm]);
+
+ // Compute pagination details
+ const totalItems = filteredSellers.length;
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
+ const startIdx = totalItems === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1;
+ const endIdx = Math.min(currentPage * itemsPerPage, totalItems);
+ const currentSellers = filteredSellers.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
+
return (
@@ -75,40 +92,97 @@ const SellerList = () => {
{loading ? (
-
Loading seller profiles...
+
Loading seller profiles...
) : error ? (
Error: {error}
) : (
-
-
-
-
- | Seller Name |
- Email |
- Status |
- Joined Date |
- Actions |
-
-
-
- {filteredSellers.map((seller) => (
-
- | {seller.name} |
- {seller.email} |
-
-
- |
- {seller.joined_at ? new Date(seller.joined_at).toLocaleDateString() : 'N/A'} |
-
-
- 👁️ View Details
-
- |
+ <>
+
+
+
+
+ | Seller Name |
+ Email |
+ Status |
+ Joined Date |
+ Actions |
- ))}
-
-
-
+
+
+ {currentSellers.map((seller) => (
+
+ | {seller.name} |
+ {seller.email} |
+
+
+ |
+ {seller.joined_at ? new Date(seller.joined_at).toLocaleDateString() : 'N/A'} |
+
+
+ 👁️ View Details
+
+ |
+
+ ))}
+
+
+
+
+ {/* Pagination Controls */}
+
+
+ Showing {startIdx} to {endIdx} of {totalItems} items
+
+
+
+
+ Items per page:
+
+
+
+
+
+
+ Page {currentPage} of {totalPages || 1}
+
+
+
+
+
+ >
)}