Skip to content

Commit

Permalink
Admin Pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
A-Hazzard committed Nov 5, 2024
1 parent 0d094d0 commit a3a87ab
Showing 4 changed files with 88 additions and 30 deletions.
29 changes: 25 additions & 4 deletions components/DepositManagement.tsx
Original file line number Diff line number Diff line change
@@ -10,9 +10,10 @@ import {
TableCell,
TableColumn,
TableHeader,
TableRow
TableRow,
Pagination
} from "@nextui-org/react";
import { collection, doc, getDoc, onSnapshot, orderBy, query, runTransaction, Timestamp, updateDoc } from "firebase/firestore";
import { collection, doc, getDoc, limit, onSnapshot, orderBy, query, runTransaction, Timestamp, updateDoc } from "firebase/firestore";
import { gsap } from "gsap";
import { useEffect, useState } from "react";
import { toast } from "react-toastify";
@@ -26,21 +27,30 @@ type Deposit = {
createdAt: Timestamp;
};

const ITEMS_PER_PAGE = 50;

const DepositManagement = () => {
const [deposits, setDeposits] = useState<Deposit[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);

useEffect(() => {
const depositsCollection = collection(db, "deposits");
const q = query(depositsCollection, orderBy("createdAt", "desc"));
const q = query(
depositsCollection,
orderBy("createdAt", "desc"),
limit(ITEMS_PER_PAGE)
);

const unsubscribe = onSnapshot(q, (snapshot) => {
const depositsData = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as Deposit[];
setDeposits(depositsData);
setTotalPages(Math.ceil(snapshot.size / ITEMS_PER_PAGE));
setLoading(false);
}, (err) => {
setError("Failed to fetch deposits: " + err.message);
@@ -49,7 +59,7 @@ const DepositManagement = () => {
});

return () => unsubscribe();
}, []);
}, [currentPage]);

useEffect(() => {
gsap.from(".deposit-table", { opacity: 0, y: -50, duration: 0.5, stagger: 0.1 });
@@ -119,6 +129,10 @@ const DepositManagement = () => {
}
};

const handlePageChange = (page: number) => {
setCurrentPage(page);
};

if (loading) {
return (
<div className="flex justify-center items-center h-screen">
@@ -202,6 +216,13 @@ const DepositManagement = () => {
)}
</TableBody>
</Table>
<Pagination
total={totalPages}
initialPage={1}
page={currentPage}
onChange={handlePageChange}
className="flex justify-center mt-4"
/>
</div>
</div>
);
54 changes: 32 additions & 22 deletions components/InvoiceManagement.tsx
Original file line number Diff line number Diff line change
@@ -19,17 +19,19 @@ import {
DropdownItem,
DropdownTrigger,
DropdownMenu,
Pagination,
} from "@nextui-org/react";
import {
addDoc,
collection,
DocumentData,
getDocs,
query,
where,
onSnapshot,
doc,
updateDoc,
orderBy,
limit,
} from "firebase/firestore";
import { useEffect, useState } from "react";
import { toast, ToastContainer } from "react-toastify";
@@ -59,6 +61,8 @@ type SortConfig = {
direction: 'asc' | 'desc';
};

const ITEMS_PER_PAGE = 50;

const InvoiceManagement = () => {
const [invoices, setInvoices] = useState<Invoice[]>([]);
const [newInvoice, setNewInvoice] = useState<NewInvoice>({
@@ -80,6 +84,8 @@ const InvoiceManagement = () => {
amountRange: "",
});
const [sortConfig, setSortConfig] = useState<SortConfig>({ field: '', direction: 'asc' });
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);

useEffect(() => {
let unsubscribe: (() => void) | undefined;
@@ -88,25 +94,19 @@ const InvoiceManagement = () => {
setLoading(true);
try {
const invoicesCollection = collection(db, "invoices");
unsubscribe = onSnapshot(invoicesCollection, (snapshot) => {
const invoicesData: Invoice[] = snapshot.docs.map((doc) => {
const data = doc.data() as DocumentData;
return {
id: doc.id,
invoiceNumber: data.invoiceNumber,
description: data.description,
amount: parseFloat(data.amount) || 0,
date: data.date,
status: data.status,
userId: data.userId,
userEmail: data.userEmail,
createdAt: data.createdAt,
username: data.username,
country: data.country,
userName: data.username,
};
});
const q = query(
invoicesCollection,
orderBy("createdAt", "desc"),
limit(ITEMS_PER_PAGE)
);

unsubscribe = onSnapshot(q, (snapshot) => {
const invoicesData = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as Invoice[];
setInvoices(invoicesData);
setTotalPages(Math.ceil(snapshot.size / ITEMS_PER_PAGE));
setLoading(false);
});
} catch (err) {
@@ -117,13 +117,12 @@ const InvoiceManagement = () => {

setupSubscription();

// Cleanup subscription on unmount
return () => {
if (unsubscribe) {
unsubscribe();
}
};
}, []);
}, [currentPage]);

const handleAddInvoice = async () => {
// Validation
@@ -421,6 +420,10 @@ const InvoiceManagement = () => {
</div>
);

const handlePageChange = (page: number) => {
setCurrentPage(page);
};

return (
<div className="max-w-7xl mx-auto px-4 py-6 text-light">
<ToastContainer />
@@ -568,7 +571,7 @@ const InvoiceManagement = () => {
<TableRow key={invoice.id}>
<TableCell className="font-semibold text-light">{invoice.invoiceNumber}</TableCell>
<TableCell>{invoice.description}</TableCell>
<TableCell className="px-4">${invoice.amount.toFixed(2)}</TableCell>
<TableCell className="px-4">${invoice.amount}</TableCell>
<TableCell className="px-4">{formatDate(invoice.createdAt)}</TableCell>
<TableCell className="px-4">
<span className={`px-2 py-1 rounded-full text-xs ${
@@ -596,6 +599,13 @@ const InvoiceManagement = () => {
)}
</TableBody>
</Table>
<Pagination
total={totalPages}
initialPage={1}
page={currentPage}
onChange={handlePageChange}
className="flex justify-center mt-4"
/>
</div>
</div>
);
29 changes: 27 additions & 2 deletions components/UserManagement.tsx
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ import {
TableColumn,
TableHeader,
TableRow,
Pagination,
} from "@nextui-org/react";
import {
collection,
@@ -27,6 +28,8 @@ import {
updateDoc,
where,
writeBatch,
orderBy,
limit,
} from "firebase/firestore";
import { useEffect, useState } from "react";
import { toast, ToastContainer } from "react-toastify";
@@ -40,13 +43,17 @@ type User = {
isAdmin: boolean;
}

const ITEMS_PER_PAGE = 50;

const UserManagement = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [currentUserUid, setCurrentUserUid] = useState<string | null>(null);
const [modalVisible, setModalVisible] = useState(false);
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [isMakingAdmin, setIsMakingAdmin] = useState(true);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);

useEffect(() => {
const unsubscribeAuth = auth.onAuthStateChanged((user) => {
@@ -55,7 +62,12 @@ const UserManagement = () => {
}
});

const usersQuery = query(collection(db, "users"));
const usersQuery = query(
collection(db, "users"),
orderBy("createdAt", "desc"),
limit(ITEMS_PER_PAGE)
);

const unsubscribeUsers = onSnapshot(usersQuery, (snapshot) => {
const usersData = snapshot.docs.map((doc) => ({
uid: doc.id,
@@ -65,14 +77,15 @@ const UserManagement = () => {
isAdmin: doc.data().isAdmin !== undefined ? doc.data().isAdmin : false,
})) as User[];
setUsers(usersData);
setTotalPages(Math.ceil(snapshot.size / ITEMS_PER_PAGE));
setLoading(false);
});

return () => {
unsubscribeAuth();
unsubscribeUsers();
};
}, []);
}, [currentPage]);

const handleToggleDisable = async (
userId: string,
@@ -245,6 +258,10 @@ const UserManagement = () => {
}
};

const handlePageChange = (page: number) => {
setCurrentPage(page);
};

if (loading) {
return <Spinner size="lg" />;
}
@@ -318,6 +335,14 @@ const UserManagement = () => {
</Table>
</div>

<Pagination
total={totalPages}
initialPage={1}
page={currentPage}
onChange={handlePageChange}
className="flex justify-center mt-4"
/>

<Modal
closeButton
isOpen={modalVisible}
6 changes: 4 additions & 2 deletions components/WithdrawalManagement.tsx
Original file line number Diff line number Diff line change
@@ -55,6 +55,8 @@ type WithdrawalRequest = {
userId: string;
}

const ITEMS_PER_PAGE = 50;

const WithdrawalManagement = () => {
const [withdrawals, setWithdrawals] = useState<Withdrawal[]>([]);
const [withdrawalRequests, setWithdrawalRequests] = useState<
@@ -232,7 +234,7 @@ const WithdrawalManagement = () => {
initialPage={1}
page={currentWithdrawalPage}
onChange={handleWithdrawalPageChange}
className="flex justify-center"
className="flex justify-center mt-4"
/>
</div>

@@ -305,7 +307,7 @@ const WithdrawalManagement = () => {
initialPage={1}
page={currentRequestPage}
onChange={handleRequestPageChange}
className="flex justify-center"
className="flex justify-center mt-4"
/>
</div>
</div>

0 comments on commit a3a87ab

Please sign in to comment.