diff --git a/app/(pages)/admin/billing/page.tsx b/app/(pages)/admin/billing/page.tsx
deleted file mode 100644
index 876e6b70..00000000
--- a/app/(pages)/admin/billing/page.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import React from "react";
-
-export default function Billing() {
- return
Overview of financial transactions
;
-}
diff --git a/app/(pages)/admin/components/Sidebar/index.tsx b/app/(pages)/admin/components/Sidebar/index.tsx
index 86baaa33..daf50440 100644
--- a/app/(pages)/admin/components/Sidebar/index.tsx
+++ b/app/(pages)/admin/components/Sidebar/index.tsx
@@ -19,7 +19,7 @@ import { TbCurrencyRupee } from "react-icons/tb";
const SidebarConfig = [
{ title: "Dashboard", uri: "", icon: },
{ title: "Add Admin", uri: "add-admin", icon: },
- { title: "Billing", uri: "billing", icon: },
+ { title: "Transactions", uri: "transactions", icon: },
{ title: "Hospitals", uri: "hospitals", icon: },
{ title: "Users", uri: "users", icon: },
{ title: "Reports", uri: "reports", icon: },
diff --git a/app/(pages)/admin/page.tsx b/app/(pages)/admin/page.tsx
index f525a38f..d06f91c5 100644
--- a/app/(pages)/admin/page.tsx
+++ b/app/(pages)/admin/page.tsx
@@ -57,12 +57,10 @@ export default function Admin() {
const [recentUsers, setRecentUsers] = useState([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
- const [isLoading, setIsLoading] = useState(false);
const observer = useRef(null);
const lastUserElementRef = useCallback(
(node: HTMLDivElement | null) => {
- if (isLoading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
@@ -71,7 +69,7 @@ export default function Admin() {
});
if (node) observer.current.observe(node);
},
- [isLoading, hasMore]
+ [hasMore]
);
useEffect(() => {
@@ -87,8 +85,8 @@ export default function Admin() {
}, [page]);
const fetchRecentUsers = async () => {
- if (isLoading || !hasMore) return;
- setIsLoading(true);
+ if (!hasMore) return;
+
try {
const response = await fetch(
`/api/admin/dashboard/recent-users?page=${page}&limit=10`
@@ -98,8 +96,6 @@ export default function Admin() {
setHasMore(data.page < data.totalPages);
} catch (error) {
console.error("Error fetching recent users:", error);
- } finally {
- setIsLoading(false);
}
};
@@ -189,11 +185,6 @@ export default function Admin() {
{user.timeSince}
))}
- {isLoading && (
-
-
-
- )}
diff --git a/app/(pages)/admin/transactions/page.tsx b/app/(pages)/admin/transactions/page.tsx
new file mode 100644
index 00000000..ebe1ca44
--- /dev/null
+++ b/app/(pages)/admin/transactions/page.tsx
@@ -0,0 +1,357 @@
+"use client";
+
+import React from "react";
+import { getFormattedDate } from "@utils/getDate";
+import {
+ Table,
+ TableHeader,
+ TableColumn,
+ TableBody,
+ TableRow,
+ TableCell,
+ Input,
+ Button,
+ Dropdown,
+ DropdownTrigger,
+ DropdownMenu,
+ DropdownItem,
+ Chip,
+ Pagination,
+ Spacer,
+ ScrollShadow,
+ Card,
+ Image,
+} from "@nextui-org/react";
+import { BiDownArrow, BiPlus, BiSearch } from "react-icons/bi";
+
+const transactions = [
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://marketplace.canva.com/EAE8eSD-Zyo/1/0/1600w/canva-blue%2C-white-and-green-medical-care-logo-oz1ox2GedbU.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 300,
+ status: "Success",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://thumbs.dreamstime.com/b/red-cross-vector-icon-hospital-sign-medical-health-first-aid-symbol-isolated-vhite-modern-gradient-design-141217893.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 500,
+ status: "Failed",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://marketplace.canva.com/EAE8eSD-Zyo/1/0/1600w/canva-blue%2C-white-and-green-medical-care-logo-oz1ox2GedbU.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 300,
+ status: "Success",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://thumbs.dreamstime.com/b/red-cross-vector-icon-hospital-sign-medical-health-first-aid-symbol-isolated-vhite-modern-gradient-design-141217893.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 500,
+ status: "Failed",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://marketplace.canva.com/EAE8eSD-Zyo/1/0/1600w/canva-blue%2C-white-and-green-medical-care-logo-oz1ox2GedbU.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 300,
+ status: "Success",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+ {
+ transaction_id: "6ce5a08c17660df643efbf56",
+ patient_name: "John Doe",
+ hospital_name: "City Hospital",
+ hospital_profile:
+ "https://thumbs.dreamstime.com/b/red-cross-vector-icon-hospital-sign-medical-health-first-aid-symbol-isolated-vhite-modern-gradient-design-141217893.jpg",
+ disease: "Common Cold",
+ description: "Prescription Medication",
+ amount: 500,
+ status: "Failed",
+ date: "2024-04-05T14:23:12.456Z",
+ },
+];
+
+const statusColorMap: any = {
+ Failed: "error",
+ Success: "success",
+};
+
+export default function Transactions() {
+ const [filterValue, setFilterValue] = React.useState("");
+ const [statusFilter, setStatusFilter] = React.useState("all");
+ const [rowsPerPage, setRowsPerPage] = React.useState(5);
+ const [sortDescriptor, setSortDescriptor] = React.useState({
+ column: "date",
+ direction: "ascending",
+ });
+ const [page, setPage] = React.useState(1);
+
+ const hasSearchFilter = Boolean(filterValue);
+
+ const filteredItems = React.useMemo(() => {
+ let filteredTransactions = [...transactions];
+
+ if (hasSearchFilter) {
+ filteredTransactions = filteredTransactions.filter((transaction) =>
+ transaction.patient_name
+ .toLowerCase()
+ .includes(filterValue.toLowerCase())
+ );
+ }
+ if (statusFilter !== "all") {
+ filteredTransactions = filteredTransactions.filter(
+ (transaction) => transaction.status === statusFilter
+ );
+ }
+
+ return filteredTransactions;
+ }, [transactions, filterValue, statusFilter]);
+
+ const pages = Math.ceil(filteredItems.length / rowsPerPage);
+
+ const items = React.useMemo(() => {
+ const start = (page - 1) * rowsPerPage;
+ const end = start + rowsPerPage;
+
+ return filteredItems.slice(start, end);
+ }, [page, filteredItems, rowsPerPage]);
+
+ const sortedItems = React.useMemo(() => {
+ return [...items].sort((a: any, b: any) => {
+ const first = new Date(a[sortDescriptor.column]);
+ const second = new Date(b[sortDescriptor.column]);
+ const cmp = first < second ? -1 : first > second ? 1 : 0;
+
+ return sortDescriptor.direction === "descending" ? -cmp : cmp;
+ });
+ }, [sortDescriptor, items]);
+
+ const renderCell = React.useCallback((transaction: any, columnKey: any) => {
+ switch (columnKey) {
+ case "hospital_name":
+ return (
+
+ );
+ case "status":
+ return (
+
+ {transaction.status}
+
+ );
+ default:
+ return transaction[columnKey];
+ }
+ }, []);
+
+ const onNextPage = React.useCallback(() => {
+ if (page < pages) {
+ setPage(page + 1);
+ }
+ }, [page, pages]);
+
+ const onPreviousPage = React.useCallback(() => {
+ if (page > 1) {
+ setPage(page - 1);
+ }
+ }, [page]);
+
+ const onRowsPerPageChange = React.useCallback((e: any) => {
+ setRowsPerPage(Number(e.target.value));
+ setPage(1);
+ }, []);
+
+ const onSearchChange = React.useCallback((value: any) => {
+ if (value) {
+ setFilterValue(value);
+ setPage(1);
+ } else {
+ setFilterValue("");
+ }
+ }, []);
+
+ const topContent = React.useMemo(() => {
+ return (
+
+
+
}
+ value={filterValue}
+ onClear={() => setFilterValue("")}
+ onValueChange={onSearchChange}
+ />
+
+
+
+ }
+ variant="flat"
+ >
+ Status
+
+
+
+ All
+ Success
+ Failed
+
+
+ }>
+ Add New
+
+
+
+
+
+ Total {transactions.length} transactions
+
+
+
+
+ );
+ }, [
+ filterValue,
+ statusFilter,
+ onRowsPerPageChange,
+ transactions.length,
+ onSearchChange,
+ ]);
+
+ const bottomContent = React.useMemo(() => {
+ return (
+
+
+
+
+
+
+
+ );
+ }, [page, pages]);
+
+ return (
+
+
+
+ Transaction Details
+
+
+
+
+ Sr. No.
+ Transaction ID
+ Hospital
+ Disease
+ Description
+ Amount
+ Status
+ Date
+
+
+ {sortedItems.map((transaction, index) => (
+
+ {index + 1}
+ {transaction.transaction_id}
+
+ {renderCell(transaction, "hospital_name")}
+
+ {transaction.disease}
+ {transaction.description}
+ ₹{transaction.amount}
+ {renderCell(transaction, "status")}
+
+ {getFormattedDate(new Date(transaction.date))}
+
+
+ ))}
+
+
+
+
+
+ );
+}