transactions page
This commit is contained in:
parent
2864bf8cdc
commit
b27bef26f2
55
payment-iq/app/api/transactions/deposit/route.ts
Normal file
55
payment-iq/app/api/transactions/deposit/route.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { depositTransactionDummyData } from "@/app/features/Pages/transactions/mockData";
|
||||||
|
import { formatToDateTimeString } from "@/app/utils/formatDate";
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const userId = searchParams.get("userId");
|
||||||
|
const depositMethod = searchParams.get("depositMethod");
|
||||||
|
const merchandId = searchParams.get("merchandId");
|
||||||
|
const transactionId = searchParams.get("transactionId");
|
||||||
|
const dateTime = searchParams.get("dateTime");
|
||||||
|
|
||||||
|
|
||||||
|
let filteredTransactions = [...depositTransactionDummyData];
|
||||||
|
|
||||||
|
console.log(12345, dateTime?.split(" ")[0]);
|
||||||
|
if (userId) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.userId.toString() === userId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.status.toLowerCase() === status.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depositMethod) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.depositMethod.toLowerCase() === depositMethod.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (merchandId) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.merchandId.toString() === merchandId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (transactionId) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.transactionId.toString() === transactionId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(777, dateTime);
|
||||||
|
if (dateTime) {
|
||||||
|
filteredTransactions = filteredTransactions.filter(
|
||||||
|
(tx) => tx.dateTime.split(" ")[0] === formatToDateTimeString(dateTime).split(" ")[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(filteredTransactions);
|
||||||
|
}
|
||||||
7
payment-iq/app/dashboard/transactions/deposits/page.tsx
Normal file
7
payment-iq/app/dashboard/transactions/deposits/page.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import DepositsTransactionsTable from "@/app/features/Pages/transactions/DepositTransactionsTable";
|
||||||
|
|
||||||
|
export default function DepositTransactionPage() {
|
||||||
|
return (
|
||||||
|
<DepositsTransactionsTable />
|
||||||
|
);
|
||||||
|
}
|
||||||
172
payment-iq/app/features/AdvancedSearch/AdvancedSearch1.tsx
Normal file
172
payment-iq/app/features/AdvancedSearch/AdvancedSearch1.tsx
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
TextField,
|
||||||
|
MenuItem,
|
||||||
|
Button,
|
||||||
|
Drawer,
|
||||||
|
FormControl,
|
||||||
|
Select,
|
||||||
|
Typography,
|
||||||
|
Stack,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||||
|
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
||||||
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
|
|
||||||
|
|
||||||
|
interface IForm {
|
||||||
|
userId: string;
|
||||||
|
transactionId: string;
|
||||||
|
transactionReferenceId: string;
|
||||||
|
currency: string;
|
||||||
|
state: string;
|
||||||
|
depositMethod: string;
|
||||||
|
dateTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ILabel {
|
||||||
|
label: string;
|
||||||
|
field: string;
|
||||||
|
type: string;
|
||||||
|
options?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAdvancedSearch {
|
||||||
|
setForm: () => void;
|
||||||
|
form: IForm[];
|
||||||
|
resetForm: () => void;
|
||||||
|
labels: ILabel[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AdvancedSearch1({ setForm, form, resetForm, labels }: IAdvancedSearch) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleChange = (field: string, value: any) => {
|
||||||
|
setForm((prev) => ({ ...prev, [field]: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
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 list = () => (
|
||||||
|
<Box sx={{ width: 400 }} role="presentation">
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<Box p={2}>
|
||||||
|
<Box sx={{ display: "flex", gap: "60px" }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Search
|
||||||
|
</Typography>
|
||||||
|
{/* Buttons */}
|
||||||
|
<Box display="flex" justifyContent="flex-end" gap={2}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
startIcon={<SearchIcon />}
|
||||||
|
onClick={() => console.log("Apply Filter", form)}
|
||||||
|
sx={{ "& .span": { margin: "0px", padding: "0px" } }}
|
||||||
|
>
|
||||||
|
Apply Filter
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<RefreshIcon sx={{ margin: "0px" }} />}
|
||||||
|
onClick={resetForm}
|
||||||
|
sx={{ "& span": { margin: "0px", padding: "0px" } }}
|
||||||
|
></Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Stack spacing={2}>
|
||||||
|
{labels.map(({ label, field, type, options }) => (
|
||||||
|
<Box key={field}>
|
||||||
|
<Typography variant="body2" fontWeight={600} mb={0.5}>
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
{type === "text" && (
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
value={form[field]}
|
||||||
|
onChange={(e) => handleChange(field, e.target.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{type === "select" && (
|
||||||
|
<FormControl fullWidth size="small">
|
||||||
|
<Select
|
||||||
|
value={form[field]}
|
||||||
|
onChange={(e) => handleChange(field, e.target.value)}
|
||||||
|
displayEmpty
|
||||||
|
>
|
||||||
|
<MenuItem value="">
|
||||||
|
<em>{label}</em>
|
||||||
|
</MenuItem>
|
||||||
|
{options.map((option) => (
|
||||||
|
<MenuItem value={option} key={option}>
|
||||||
|
{option}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
{type === "date" && (
|
||||||
|
<DatePicker
|
||||||
|
value={form[field]}
|
||||||
|
onChange={(newValue) => handleChange(field, newValue)}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField fullWidth size="small" {...params} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: '185px' }}>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
borderRadius: "8px",
|
||||||
|
textTransform: "none",
|
||||||
|
backgroundColor: "#f5f5f5",
|
||||||
|
color: "#555",
|
||||||
|
padding: "6px 12px",
|
||||||
|
boxShadow: "inset 0 0 0 1px #ddd",
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: "16px",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
"& .MuiButton-startIcon": {
|
||||||
|
borderRadius: "4px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#e0e0e0",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
startIcon={<SearchIcon />}
|
||||||
|
onClick={toggleDrawer(true)}
|
||||||
|
>
|
||||||
|
Advanced Search
|
||||||
|
</Button>
|
||||||
|
{/* <Button onClick={toggleDrawer(true)}>Open Right Drawer</Button> */}
|
||||||
|
<Drawer anchor="right" open={open} onClose={toggleDrawer(false)}>
|
||||||
|
{list()}
|
||||||
|
</Drawer>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,176 @@
|
|||||||
|
"use client";
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
FormControl,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
FormControlLabel,
|
||||||
|
Checkbox,
|
||||||
|
Stack,
|
||||||
|
Paper,
|
||||||
|
styled,
|
||||||
|
TextField,
|
||||||
|
} from "@mui/material";
|
||||||
|
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
||||||
|
import { DataGrid } from "@mui/x-data-grid";
|
||||||
|
import { depositTransactionsColumns, Labels } from "./constants";
|
||||||
|
import AdvancedSearch1 from "../../AdvancedSearch/AdvancedSearch1";
|
||||||
|
import SearchFilters from "@/app/components/searchFilter/SearchFilters";
|
||||||
|
import { exportData } from "@/app/utils/exportData";
|
||||||
|
import { ITransaction } from "./types";
|
||||||
|
|
||||||
|
const paginationModel = { page: 0, pageSize: 50 };
|
||||||
|
|
||||||
|
export default function DepositsTransactionsTable() {
|
||||||
|
const [form, setForm] = useState({
|
||||||
|
userId: "",
|
||||||
|
transactionId: "",
|
||||||
|
transactionReferenceId: "",
|
||||||
|
currency: "",
|
||||||
|
state: "",
|
||||||
|
depositMethod: "",
|
||||||
|
dateTime: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [fileType, setFileType] = useState<"csv" | "xls" | "xlsx">("csv");
|
||||||
|
const [onlyCurrentTable, setOnlyCurrentTable] = useState(false);
|
||||||
|
const [transactions, setTransactions] = useState<ITransaction[]>([]);
|
||||||
|
|
||||||
|
|
||||||
|
console.log(777, form)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const fetchTransactions = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const stringForm: Record<string, string> = Object.fromEntries(
|
||||||
|
Object.entries(form).map(([key, value]) => [key, value === null ? "" : String(value)])
|
||||||
|
);
|
||||||
|
const query = new URLSearchParams(stringForm).toString();
|
||||||
|
const res = await fetch(`/api/transactions/deposit?${query}`);
|
||||||
|
const data = await res.json();
|
||||||
|
setTransactions(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching transactions:', error);
|
||||||
|
}
|
||||||
|
}, [form]);
|
||||||
|
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
setForm({
|
||||||
|
userId: "",
|
||||||
|
transactionId: "",
|
||||||
|
transactionReferenceId: "",
|
||||||
|
currency: "",
|
||||||
|
state: "",
|
||||||
|
depositMethod: "",
|
||||||
|
dateTime: "",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchTransactions();
|
||||||
|
}, [form, fetchTransactions]);
|
||||||
|
|
||||||
|
const handleDeleteFilter = (key: string) => {
|
||||||
|
setForm((prev) => ({ ...prev, [key]: '' }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClearAll = () => {
|
||||||
|
resetForm()
|
||||||
|
fetchTransactions()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleClickField = (field: string, value: string) => {
|
||||||
|
setForm((prev) => ({ ...prev, [field]: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledPaper>
|
||||||
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
justifyContent="space-between"
|
||||||
|
alignItems="center"
|
||||||
|
p={2}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Search"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
onChange={(e) => console.log(`setSearchQuery(${e.target.value})`)}
|
||||||
|
sx={{ width: 300 }}
|
||||||
|
/>
|
||||||
|
<AdvancedSearch1 form={form} resetForm={resetForm} setForm={setForm} labels={Labels} />
|
||||||
|
<SearchFilters filters={form} onDeleteFilter={handleDeleteFilter} onClearAll={handleClearAll} />
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<FileUploadIcon />}
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
>
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<DataGrid
|
||||||
|
rows={transactions}
|
||||||
|
columns={depositTransactionsColumns}
|
||||||
|
initialState={{ pagination: { paginationModel } }}
|
||||||
|
pageSizeOptions={[50, 100]}
|
||||||
|
sx={{ border: 0, cursor: 'pointer' }}
|
||||||
|
|
||||||
|
onCellClick={(params) => {
|
||||||
|
handleClickField(params.field, params.value as string)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Export Dialog */}
|
||||||
|
<Dialog open={open} onClose={() => setOpen(false)}>
|
||||||
|
<DialogTitle>Export Transactions</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<FormControl fullWidth sx={{ mt: 2 }}>
|
||||||
|
<Select
|
||||||
|
value={fileType}
|
||||||
|
onChange={(e) =>
|
||||||
|
setFileType(e.target.value as "csv" | "xls" | "xlsx")
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MenuItem value="csv">CSV</MenuItem>
|
||||||
|
<MenuItem value="xls">XLS</MenuItem>
|
||||||
|
<MenuItem value="xlsx">XLSX</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={onlyCurrentTable}
|
||||||
|
onChange={(e) => setOnlyCurrentTable(e.target.checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Only export the results in the current table"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setOpen(false)}>Cancel</Button>
|
||||||
|
<Button variant="contained" onClick={() => exportData(transactions, depositTransactionsColumns, fileType, onlyCurrentTable, setOpen)}>
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</StyledPaper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledPaper = styled(Paper)(() => ({
|
||||||
|
height: "90vh",
|
||||||
|
width: "80vw"
|
||||||
|
}));
|
||||||
@ -119,3 +119,50 @@ export const columns: GridColDef[] = [
|
|||||||
// { field: 'originTransactionId', headerName: 'Origin Transaction ID', type: 'number', width: 90 },
|
// { field: 'originTransactionId', headerName: 'Origin Transaction ID', type: 'number', width: 90 },
|
||||||
// { field: 'transactionReferenceId', headerName: 'Transaction Reference ID', type: 'number', width: 90 },
|
// { field: 'transactionReferenceId', headerName: 'Transaction Reference ID', type: 'number', width: 90 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const depositTransactionsColumns = [
|
||||||
|
{ field: "userId", headerName: "User ID", width: 130 },
|
||||||
|
{ field: "merchandId", headerName: "Merchant ID", width: 130 },
|
||||||
|
{ field: "transactionId", headerName: "Transaction ID", width: 130 },
|
||||||
|
{ field: "depositMethod", headerName: "Deposit Method", width: 130 },
|
||||||
|
{ field: "status", headerName: "Status", width: 130 },
|
||||||
|
{ field: "amount", headerName: "Amount", width: 130 },
|
||||||
|
{ field: "currency", headerName: "Currency", width: 130 },
|
||||||
|
{ field: "dateTime", headerName: "Date / Time", width: 130 },
|
||||||
|
{ field: "errorInfo", headerName: "Error Info", width: 130 },
|
||||||
|
{ field: "fraudScore", headerName: "Fraud Score", width: 130 },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
export const currencies = ["USD", "EUR", "GBP"];
|
||||||
|
export const states = ["Pending", "Completed", "Failed"];
|
||||||
|
export const depositMethod = ["Card", "Bank Transfer"];
|
||||||
|
|
||||||
|
export const Labels = [
|
||||||
|
{ label: "User", field: "userId", type: "text" },
|
||||||
|
{ label: "Transaction ID", field: "transactionId", type: "text" },
|
||||||
|
{
|
||||||
|
label: "Transaction Reference ID",
|
||||||
|
field: "transactionReferenceId",
|
||||||
|
type: "text",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Currency",
|
||||||
|
field: "currency",
|
||||||
|
type: "select",
|
||||||
|
options: currencies,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "State",
|
||||||
|
field: "state",
|
||||||
|
type: "select",
|
||||||
|
options: states,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Payment Method",
|
||||||
|
field: "depositMethod",
|
||||||
|
type: "select",
|
||||||
|
options: depositMethod,
|
||||||
|
},
|
||||||
|
{ label: "Date / Time", field: "dateTime", type: "date" },
|
||||||
|
]
|
||||||
|
|||||||
@ -2691,11 +2691,12 @@ export const rows = [
|
|||||||
// transactionReferenceId: "", // no value provided
|
// transactionReferenceId: "", // no value provided
|
||||||
// },
|
// },
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
export const transactionDummyData = [
|
export const transactionDummyData = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
merchandId: 100987998,
|
merchandId: 100987998,
|
||||||
transactionID: 1049131973,
|
transactionID: 1049136973,
|
||||||
user: 1,
|
user: 1,
|
||||||
created: "2025-06-18 10:10:30",
|
created: "2025-06-18 10:10:30",
|
||||||
state: "FAILED",
|
state: "FAILED",
|
||||||
@ -2705,7 +2706,7 @@ export const transactionDummyData = [
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
merchandId: 100987998,
|
merchandId: 100987998,
|
||||||
transactionID: 1049131973,
|
transactionID: 1049131975,
|
||||||
user: 2,
|
user: 2,
|
||||||
created: "2025-06-18 10:10:30",
|
created: "2025-06-18 10:10:30",
|
||||||
state: "FAILED",
|
state: "FAILED",
|
||||||
@ -2715,7 +2716,7 @@ export const transactionDummyData = [
|
|||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
merchandId: 100987998,
|
merchandId: 100987998,
|
||||||
transactionID: 1049131973,
|
transactionID: 1049131975,
|
||||||
user: 3,
|
user: 3,
|
||||||
created: "2025-06-18 10:10:30",
|
created: "2025-06-18 10:10:30",
|
||||||
state: "Completed",
|
state: "Completed",
|
||||||
@ -2725,7 +2726,7 @@ export const transactionDummyData = [
|
|||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
merchandId: 100987998,
|
merchandId: 100987998,
|
||||||
transactionID: 1049131973,
|
transactionID: 1049131975,
|
||||||
user: 4,
|
user: 4,
|
||||||
created: "2025-06-18 10:10:30",
|
created: "2025-06-18 10:10:30",
|
||||||
state: "FAILED",
|
state: "FAILED",
|
||||||
@ -2735,7 +2736,7 @@ export const transactionDummyData = [
|
|||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
merchandId: 100987998,
|
merchandId: 100987998,
|
||||||
transactionID: 1049131973,
|
transactionID: 1049131975,
|
||||||
user: 5,
|
user: 5,
|
||||||
created: "2025-06-18 10:10:30",
|
created: "2025-06-18 10:10:30",
|
||||||
state: "FAILED",
|
state: "FAILED",
|
||||||
@ -2743,3 +2744,149 @@ export const transactionDummyData = [
|
|||||||
pspStatusCode: 100501,
|
pspStatusCode: 100501,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const depositTransactionDummyData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
userId: 17,
|
||||||
|
merchandId: 100987998,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Completed",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
userId: 17,
|
||||||
|
merchandId: 100987998,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Completed",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
userId: 17,
|
||||||
|
merchandId: 100987997,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Complete",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
userId: 19,
|
||||||
|
merchandId: 100987997,
|
||||||
|
transactionId: 1049136973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Completed",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
userId: 19,
|
||||||
|
merchandId: 100987998,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Completed",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
userId: 27,
|
||||||
|
merchandId: 100987997,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Pending",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
userId: 175,
|
||||||
|
merchandId: 100987938,
|
||||||
|
transactionId: 1049136973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Pending",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-18 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
userId: 172,
|
||||||
|
merchandId: 100987938,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Card",
|
||||||
|
status: "Pending",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-12 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
userId: 174,
|
||||||
|
merchandId: 100987938,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Bank Transfer",
|
||||||
|
status: "Inprogress",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-17 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
userId: 7,
|
||||||
|
merchandId: 100987998,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Bank Transfer",
|
||||||
|
status: "Inprogress",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-17 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 11,
|
||||||
|
userId: 1,
|
||||||
|
merchandId: 100987998,
|
||||||
|
transactionId: 1049131973,
|
||||||
|
depositMethod: "Bank Transfer",
|
||||||
|
status: "Error",
|
||||||
|
amount: 4000,
|
||||||
|
currency: "EUR",
|
||||||
|
dateTime: "2025-06-17 10:10:30",
|
||||||
|
errorInfo: "-",
|
||||||
|
fraudScore: "frad score 1234",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|||||||
3
payment-iq/app/features/Pages/transactions/types.ts
Normal file
3
payment-iq/app/features/Pages/transactions/types.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface ITransaction {
|
||||||
|
[key: string]: string | number; // Replace with actual fields if known, e.g. id: string, amount: number, etc.
|
||||||
|
}
|
||||||
@ -10,14 +10,36 @@ import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings";
|
|||||||
import InsightsIcon from "@mui/icons-material/Insights";
|
import InsightsIcon from "@mui/icons-material/Insights";
|
||||||
import ListAltIcon from "@mui/icons-material/ListAlt";
|
import ListAltIcon from "@mui/icons-material/ListAlt";
|
||||||
import SettingsIcon from "@mui/icons-material/Settings";
|
import SettingsIcon from "@mui/icons-material/Settings";
|
||||||
|
|
||||||
|
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
||||||
|
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
||||||
|
import HistoryIcon from '@mui/icons-material/History';
|
||||||
|
|
||||||
import { ISidebarLink } from "@/app/features/dashboard/sidebar/SidebarLink.interfaces";
|
import { ISidebarLink } from "@/app/features/dashboard/sidebar/SidebarLink.interfaces";
|
||||||
|
|
||||||
export const PAGE_LINKS: ISidebarLink[] = [
|
export const PAGE_LINKS: ISidebarLink[] = [
|
||||||
{ title: "Home", path: "/dashboard", icon: HomeIcon },
|
{ title: "Home", path: "/dashboard", icon: HomeIcon },
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "Transaction",
|
title: "Transaction",
|
||||||
path: "/dashboard/transactions",
|
path: "/dashboard/transactions",
|
||||||
icon: AccountBalanceWalletIcon,
|
icon: AccountBalanceWalletIcon, children: [
|
||||||
|
{
|
||||||
|
title: "Deposits",
|
||||||
|
path: "/dashboard/transactions/deposits",
|
||||||
|
icon: ArrowDownwardIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Withdrawals",
|
||||||
|
path: "/dashboard/transactions/withdrawals",
|
||||||
|
icon: ArrowUpwardIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Transaction History",
|
||||||
|
path: "/dashboard/transactions/history",
|
||||||
|
icon: HistoryIcon,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{ title: "Approve", path: "/dashboard/approve", icon: CheckCircleIcon },
|
{ title: "Approve", path: "/dashboard/approve", icon: CheckCircleIcon },
|
||||||
{ title: "Investigate", path: "/dashboard/investigate", icon: SearchIcon },
|
{ title: "Investigate", path: "/dashboard/investigate", icon: SearchIcon },
|
||||||
|
|||||||
37
payment-iq/app/utils/exportData.ts
Normal file
37
payment-iq/app/utils/exportData.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import * as XLSX from "xlsx";
|
||||||
|
import { GridColDef } from "@mui/x-data-grid";
|
||||||
|
export type FileType = "csv" | "xls" | "xlsx";
|
||||||
|
import { saveAs } from "file-saver";
|
||||||
|
|
||||||
|
import type { ITransaction } from "../features/Pages/transactions/types";
|
||||||
|
|
||||||
|
|
||||||
|
export const exportData = (
|
||||||
|
transactions: ITransaction[],
|
||||||
|
columns: GridColDef[],
|
||||||
|
fileType: FileType = "csv",
|
||||||
|
onlyCurrentTable = false,
|
||||||
|
setOpen: (open: boolean) => void
|
||||||
|
) => {
|
||||||
|
const exportRows = onlyCurrentTable ? transactions.slice(0, 5) : transactions;
|
||||||
|
const exportData = [
|
||||||
|
columns.map((col) => col.headerName),
|
||||||
|
...exportRows.map((row) => columns.map((col) => row[col.field] ?? "")),
|
||||||
|
];
|
||||||
|
|
||||||
|
const worksheet = XLSX.utils.aoa_to_sheet(exportData);
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, worksheet, "Transactions");
|
||||||
|
|
||||||
|
if (fileType === "csv") {
|
||||||
|
const csv = XLSX.utils.sheet_to_csv(worksheet);
|
||||||
|
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
|
||||||
|
saveAs(blob, "transactions.csv");
|
||||||
|
} else {
|
||||||
|
XLSX.writeFile(workbook, `transactions.${fileType}`, {
|
||||||
|
bookType: fileType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
13
payment-iq/app/utils/formatDate.ts
Normal file
13
payment-iq/app/utils/formatDate.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export const formatToDateTimeString = (dateString: string): string => {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // months are 0-indexed
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||||
|
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user