diff --git a/payment-iq/app/api/dashboard/audits/mockData.ts b/payment-iq/app/api/dashboard/audits/mockData.ts new file mode 100644 index 0000000..596c5cd --- /dev/null +++ b/payment-iq/app/api/dashboard/audits/mockData.ts @@ -0,0 +1,88 @@ +import { GridColDef } from "@mui/x-data-grid"; + +export const AuditColumns: GridColDef[] = [ + { field: "actionType", headerName: "Action Type", width: 130 }, + { + field: "timeStampOfTheAction", + headerName: "Timestamp of the action", + width: 130, + }, + { field: "adminUsername", headerName: "Admin username", width: 130 }, + { field: "adminId", headerName: "Admin ID", width: 130 }, + { field: "affectedUserId", headerName: "Affected user ID", width: 130 }, + { field: "adminIPAddress", headerName: "Admin IP address", width: 130 }, + { field: "reasonNote", headerName: "Reason/Note", width: 130 }, +]; + +export const AuditData = [ + { + id: "1", + actionType: "Create", + timeStampOfTheAction: "2023-03-01T12:00:00", + adminUsername: "admin1", + adminId: "12345", + affectedUserId: "67890", + adminIPAddress: "192.168.1.1", + reasonNote: "New user created", + }, + { + id: "2", + actionType: "Update", + timeStampOfTheAction: "2023-03-02T12:00:00", + adminUsername: "admin2", + adminId: "54321", + affectedUserId: "09876", + adminIPAddress: "192.168.2.2", + reasonNote: "User details updated", + }, + { + id: "3", + actionType: "Delete", + timeStampOfTheAction: "2023-03-03T12:00:00", + adminUsername: "admin3", + adminId: "98765", + affectedUserId: "45678", + adminIPAddress: "192.168.3.3", + reasonNote: "User deleted", + }, + { + id: "4", + actionType: "Create", + timeStampOfTheAction: "2023-03-04T12:00:00", + adminUsername: "admin4", + adminId: "98765", + affectedUserId: "45678", + adminIPAddress: "192.168.3.3", + reasonNote: "New user created", + }, + { + id: "5", + actionType: "Update", + timeStampOfTheAction: "2023-03-05T12:00:00", + adminUsername: "admin2", + adminId: "98765", + affectedUserId: "45678", + adminIPAddress: "192.168.3.3", + reasonNote: "User details updated", + }, +]; + +export const AuditSearchLabels = [ + { label: "Action Type", field: "actionType", type: "text" }, + { label: "Date / Time", field: "dateTime", type: "date" }, + { + label: "affectedUserId", + field: "Affected user ID", + type: "text", + }, + { + label: "Admin ID", + field: "adminId", + type: "text", + }, + { + label: "Admin username", + field: "adminUsername", + type: "text", + }, +]; diff --git a/payment-iq/app/api/dashboard/audits/route.ts b/payment-iq/app/api/dashboard/audits/route.ts new file mode 100644 index 0000000..c73fba3 --- /dev/null +++ b/payment-iq/app/api/dashboard/audits/route.ts @@ -0,0 +1,52 @@ +import { NextRequest, NextResponse } from "next/server"; +import { AuditColumns, AuditData, AuditSearchLabels } from "./mockData"; +import { formatToDateTimeString } from "@/app/utils/formatDate"; + +export async function GET(request: NextRequest) { + const { searchParams } = new URL(request.url); + + const actionType = searchParams.get("actionType"); + const affectedUserId = searchParams.get("affectedUserId"); + const adminId = searchParams.get("adminId"); + const adminUsername = searchParams.get("adminUsername"); + const timeStampOfTheAction = searchParams.get("dateTime"); + + let filteredRows = [...AuditData]; + + if (actionType) { + filteredRows = filteredRows.filter( + (tx) => tx.actionType.toLocaleLowerCase() === actionType.toLocaleLowerCase(), + ); + } + + if (affectedUserId) { + filteredRows = filteredRows.filter( + (tx) => tx.affectedUserId.toLowerCase() === affectedUserId.toLowerCase(), + ); + } + + if (adminId) { + filteredRows = filteredRows.filter( + (tx) => tx.adminId === adminId, + ); + } + if (adminUsername) { + filteredRows = filteredRows.filter( + (tx) => tx.adminUsername === adminUsername, + ); + } + + if (timeStampOfTheAction) { + filteredRows = filteredRows.filter( + (tx) => + tx.timeStampOfTheAction.split(" ")[0] === + formatToDateTimeString(timeStampOfTheAction).split(" ")[0], + ); + } + + return NextResponse.json({ + tableRows: filteredRows, + tableColumns: AuditColumns, + tableSearchLabels: AuditSearchLabels, + }); +} diff --git a/payment-iq/app/api/transactions/deposit/mockData.ts b/payment-iq/app/api/dashboard/transactions/deposits/mockData.ts similarity index 100% rename from payment-iq/app/api/transactions/deposit/mockData.ts rename to payment-iq/app/api/dashboard/transactions/deposits/mockData.ts diff --git a/payment-iq/app/api/transactions/deposit/route.ts b/payment-iq/app/api/dashboard/transactions/deposits/route.ts similarity index 66% rename from payment-iq/app/api/transactions/deposit/route.ts rename to payment-iq/app/api/dashboard/transactions/deposits/route.ts index 1f8d62b..91066cf 100644 --- a/payment-iq/app/api/transactions/deposit/route.ts +++ b/payment-iq/app/api/dashboard/transactions/deposits/route.ts @@ -1,5 +1,9 @@ import { NextRequest, NextResponse } from "next/server"; -import { depositTransactionDummyData, depositTransactionsColumns, depositTransactionsSearchLabels } from "./mockData"; +import { + depositTransactionDummyData, + depositTransactionsColumns, + depositTransactionsSearchLabels, +} from "./mockData"; import { formatToDateTimeString } from "@/app/utils/formatDate"; export async function GET(request: NextRequest) { @@ -12,46 +16,47 @@ export async function GET(request: NextRequest) { const transactionId = searchParams.get("transactionId"); const dateTime = searchParams.get("dateTime"); - let filteredTransactions = [...depositTransactionDummyData]; if (userId) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.userId.toString() === userId + (tx) => tx.userId.toString() === userId, ); } if (status) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.status.toLowerCase() === status.toLowerCase() + (tx) => tx.status.toLowerCase() === status.toLowerCase(), ); } if (depositMethod) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.depositMethod.toLowerCase() === depositMethod.toLowerCase() + (tx) => tx.depositMethod.toLowerCase() === depositMethod.toLowerCase(), ); } if (merchandId) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.merchandId.toString() === merchandId + (tx) => tx.merchandId.toString() === merchandId, ); } if (transactionId) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.transactionId.toString() === transactionId + (tx) => tx.transactionId.toString() === transactionId, ); } if (dateTime) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.dateTime.split(" ")[0] === formatToDateTimeString(dateTime).split(" ")[0] + (tx) => + tx.dateTime.split(" ")[0] === + formatToDateTimeString(dateTime).split(" ")[0], ); } return NextResponse.json({ - filteredTransactions: filteredTransactions, - transactionsSearchLabels: depositTransactionsSearchLabels, - transactionsColumns: depositTransactionsColumns + tableRows: filteredTransactions, + tableSearchLabels: depositTransactionsSearchLabels, + tableColumns: depositTransactionsColumns, }); } diff --git a/payment-iq/app/api/transactions/withdrawal/mockData.ts b/payment-iq/app/api/dashboard/transactions/withdrawal/mockData.ts similarity index 100% rename from payment-iq/app/api/transactions/withdrawal/mockData.ts rename to payment-iq/app/api/dashboard/transactions/withdrawal/mockData.ts diff --git a/payment-iq/app/api/transactions/withdrawal/route.ts b/payment-iq/app/api/dashboard/transactions/withdrawal/route.ts similarity index 59% rename from payment-iq/app/api/transactions/withdrawal/route.ts rename to payment-iq/app/api/dashboard/transactions/withdrawal/route.ts index d0f22cd..885b0fd 100644 --- a/payment-iq/app/api/transactions/withdrawal/route.ts +++ b/payment-iq/app/api/dashboard/transactions/withdrawal/route.ts @@ -1,5 +1,9 @@ import { NextRequest, NextResponse } from "next/server"; -import { withdrawalTransactionDummyData, withdrawalTransactionsColumns, withdrawalTransactionsSearchLabels } from "./mockData" +import { + withdrawalTransactionDummyData, + withdrawalTransactionsColumns, + withdrawalTransactionsSearchLabels, +} from "./mockData"; import { formatToDateTimeString } from "@/app/utils/formatDate"; export async function GET(request: NextRequest) { @@ -10,36 +14,38 @@ export async function GET(request: NextRequest) { const dateTime = searchParams.get("dateTime"); const withdrawalMethod = searchParams.get("withdrawalMethod"); - let filteredTransactions = [...withdrawalTransactionDummyData]; if (userId) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.userId.toString() === userId + (tx) => tx.userId.toString() === userId, ); } if (status) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.status.toLowerCase() === status.toLowerCase() + (tx) => tx.status.toLowerCase() === status.toLowerCase(), ); } if (withdrawalMethod) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.withdrawalMethod.toLowerCase() === withdrawalMethod.toLowerCase() + (tx) => + tx.withdrawalMethod.toLowerCase() === withdrawalMethod.toLowerCase(), ); } if (dateTime) { filteredTransactions = filteredTransactions.filter( - (tx) => tx.dateTime.split(" ")[0] === formatToDateTimeString(dateTime).split(" ")[0] + (tx) => + tx.dateTime.split(" ")[0] === + formatToDateTimeString(dateTime).split(" ")[0], ); } return NextResponse.json({ - filteredTransactions: filteredTransactions, - transactionsColumns: withdrawalTransactionsColumns, - transactionsSearchLabels: withdrawalTransactionsSearchLabels + tableRows: filteredTransactions, + tableSearchLabels: withdrawalTransactionsSearchLabels, + tableColumns: withdrawalTransactionsColumns, }); } diff --git a/payment-iq/app/dashboard/audits/page.tsx b/payment-iq/app/dashboard/audits/page.tsx new file mode 100644 index 0000000..9bec2b5 --- /dev/null +++ b/payment-iq/app/dashboard/audits/page.tsx @@ -0,0 +1,22 @@ +import DataTable from "@/app/features/DataTable/DataTable"; +import { getAudits } from "@/app/services/audits"; + +export default async function AuditPage({ + searchParams, +}: { + searchParams: Promise>; +}) { + // Await searchParams before processing + const params = await searchParams; + // Create a safe query string by filtering only string values + const safeParams: Record = {}; + for (const [key, value] of Object.entries(params)) { + if (typeof value === "string") { + safeParams[key] = value; + } + } + const query = new URLSearchParams(safeParams).toString(); + const data = await getAudits({ query }); + + return ; +} diff --git a/payment-iq/app/dashboard/transactions/deposits/page.tsx b/payment-iq/app/dashboard/transactions/deposits/page.tsx index 3b1a49f..aa589d0 100644 --- a/payment-iq/app/dashboard/transactions/deposits/page.tsx +++ b/payment-iq/app/dashboard/transactions/deposits/page.tsx @@ -1,5 +1,4 @@ - -import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable"; +import DataTable from "@/app/features/DataTable/DataTable"; import { getTransactions } from "@/app/services/transactions"; export default async function DepositTransactionPage({ @@ -17,8 +16,8 @@ export default async function DepositTransactionPage({ } } const query = new URLSearchParams(safeParams).toString(); - const transactionType = 'deposit'; + const transactionType = "deposits"; const data = await getTransactions({ transactionType, query }); - return ; + return ; } diff --git a/payment-iq/app/dashboard/transactions/history/page.tsx b/payment-iq/app/dashboard/transactions/history/page.tsx index 2db697d..78e01bc 100644 --- a/payment-iq/app/dashboard/transactions/history/page.tsx +++ b/payment-iq/app/dashboard/transactions/history/page.tsx @@ -1,23 +1,3 @@ -import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable"; -import { getTransactions } from "@/app/services/transactions"; - -export default async function DepositTransactionPage({ - searchParams, -}: { - searchParams: Promise>; -}) { - // Await searchParams before processing - const params = await searchParams; - // Create a safe query string by filtering only string values - const safeParams: Record = {}; - for (const [key, value] of Object.entries(params)) { - if (typeof value === "string") { - safeParams[key] = value; - } - } - const query = new URLSearchParams(safeParams).toString(); - const transactionType = 'deposit'; - const data = await getTransactions({ transactionType, query }); - - return ; +export default async function HistoryTransactionPage() { + return
History Transactions Page
; } diff --git a/payment-iq/app/dashboard/transactions/withdrawals/page.tsx b/payment-iq/app/dashboard/transactions/withdrawals/page.tsx index 20afed4..e61e9bd 100644 --- a/payment-iq/app/dashboard/transactions/withdrawals/page.tsx +++ b/payment-iq/app/dashboard/transactions/withdrawals/page.tsx @@ -1,4 +1,4 @@ -import TransactionsTable from "@/app/features/pages/transactions/TransactionsTable"; +import DataTable from "@/app/features/DataTable/DataTable"; import { getTransactions } from "@/app/services/transactions"; export default async function WithdrawalTransactionPage({ @@ -16,8 +16,8 @@ export default async function WithdrawalTransactionPage({ } } const query = new URLSearchParams(safeParams).toString(); -const transactionType = 'withdrawal'; -const data = await getTransactions({ transactionType, query }); + const transactionType = "withdrawal"; + const data = await getTransactions({ transactionType, query }); - return ; + return ; } diff --git a/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx index 79db3d2..78948a7 100644 --- a/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx +++ b/payment-iq/app/features/AdvancedSearch/AdvancedSearch.tsx @@ -17,16 +17,9 @@ import SearchIcon from "@mui/icons-material/Search"; import RefreshIcon from "@mui/icons-material/Refresh"; import { useSearchParams, useRouter } from "next/navigation"; import { useState, useEffect, useMemo } from "react"; +import { ISearchLabel } from "../pages/transactions/types"; - -interface ILabel { - label: string; - field: string; - type: string; - options?: string[]; -} - -export default function AdvancedSearch({ labels }: { labels: ILabel[] }) { +export default function AdvancedSearch({ labels }: { labels: ISearchLabel[] }) { const searchParams = useSearchParams(); const router = useRouter(); const [open, setOpen] = useState(false); @@ -37,7 +30,6 @@ export default function AdvancedSearch({ labels }: { labels: ILabel[] }) { setFormValues(initialParams); }, [searchParams]); - const updateURL = useMemo( () => debounce((newValues: Record) => { @@ -47,7 +39,7 @@ export default function AdvancedSearch({ labels }: { labels: ILabel[] }) { }); router.push(`?${updatedParams.toString()}`); }, 500), - [router] + [router], ); const handleFieldChange = (field: string, value: string) => { @@ -61,19 +53,20 @@ export default function AdvancedSearch({ labels }: { labels: ILabel[] }) { router.push("?"); }; - const toggleDrawer = (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { - if ( - event.type === "keydown" && - ((event as React.KeyboardEvent).key === "Tab" || - (event as React.KeyboardEvent).key === "Shift") - ) { - return; - } - setOpen(open); - }; + const toggleDrawer = + (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === "keydown" && + ((event as React.KeyboardEvent).key === "Tab" || + (event as React.KeyboardEvent).key === "Shift") + ) { + return; + } + setOpen(open); + }; return ( - +