2025-12-29 19:54:42 +01:00

191 lines
5.9 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import {
Box,
Button,
IconButton,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from "@mui/material";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import CancelIcon from "@mui/icons-material/Cancel";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import { dashboardService } from "@/app/services/dashboardService";
import { formatToDateTimeString } from "@/app/utils/formatDate";
import "./TransactionsWaitingApproval.scss";
import {
type IReviewTransactionsData,
type IReviewTransaction,
} from "@/app/services/types";
import StatusChangeDialog from "../DataTable/StatusChangeDialog";
interface ITransactionsWaitingApprovalProps {
initialReviewTransactions?: IReviewTransactionsData | null;
}
export const TransactionsWaitingApproval = ({
initialReviewTransactions = null,
}: ITransactionsWaitingApprovalProps) => {
const [reviewTransactions, setReviewTransactions] =
useState<IReviewTransactionsData | null>(
initialReviewTransactions ||
dashboardService.getCurrentDashboardData()?.reviewTransactions ||
null
);
const [statusDialogData, setStatusDialogData] = useState<{
rowId: number;
newStatus: string;
} | null>(null);
/**
* Subscribe to dashboard data changes
*/
useEffect(() => {
const subscription = dashboardService
.getDashboardData$()
.subscribe(data => {
if (data?.reviewTransactions) {
setReviewTransactions(data.reviewTransactions);
}
});
// Cleanup subscription on unmount
return () => subscription.unsubscribe();
}, []);
/**
* Format transaction for display
*/
const formatTransaction = (tx: IReviewTransaction) => {
const createdDate = tx.created || tx.modified || "";
const formattedDate = createdDate
? formatToDateTimeString(createdDate)
: "";
return {
id: tx.id ?? tx.external_id ?? "",
user: tx.customer || "",
created: formattedDate,
type: tx.type || "",
amount: tx.amount
? `${tx.amount < 0 ? "-" : ""}${Math.abs(tx.amount).toFixed(2)} ${tx.currency || ""}`
: "",
psp: tx.psp_id || "",
};
};
const transactions = reviewTransactions?.transactions || [];
const displayTransactions = transactions.map(formatTransaction);
const handleStatusChange = (rowId: number, newStatus: string) => {
setStatusDialogData({ rowId, newStatus });
};
return (
<Paper elevation={3} className="transactions-waiting-approval">
<Box sx={{ p: 3 }}>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}>
<Typography variant="h5" fontWeight="bold">
Transactions Waiting for Approval
</Typography>
<Box>
<Button variant="outlined">All Pending Withdrawals</Button>
<IconButton size="small">
<MoreVertIcon fontSize="small" />
</IconButton>
</Box>
</Box>
{reviewTransactions && (
<TableContainer
component={Paper}
sx={{
maxHeight: 400,
overflow: "auto",
}}
>
<Table>
<TableHead>
<TableRow>
<TableCell>
<strong>ID</strong>
</TableCell>
<TableCell>
<strong>User</strong>
</TableCell>
<TableCell>
<strong>Created</strong>
</TableCell>
<TableCell>
<strong>Type</strong>
</TableCell>
<TableCell>
<strong>Amount</strong>
</TableCell>
<TableCell>
<strong>PSP</strong>
</TableCell>
<TableCell>
<strong>Action</strong>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{displayTransactions.length > 0 ? (
displayTransactions.map((tx, i) => (
<TableRow key={`${tx.id}-${i}`}>
<TableCell>{tx.id}</TableCell>
<TableCell>{tx.user}</TableCell>
<TableCell>{tx.created}</TableCell>
<TableCell>{tx.type}</TableCell>
<TableCell>{tx.amount}</TableCell>
<TableCell>{tx.psp}</TableCell>
<TableCell>
<IconButton
color="success"
onClick={() => handleStatusChange(tx.id, "approved")}
>
<CheckCircleIcon />
</IconButton>
<IconButton
color="error"
onClick={() => handleStatusChange(tx.id, "declined")}
>
<CancelIcon />
</IconButton>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={7} align="center">
<Typography variant="body2" color="text.secondary">
No transactions waiting for approval
</Typography>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
)}
</Box>
<StatusChangeDialog
open={Boolean(statusDialogData)}
transactionId={statusDialogData?.rowId ?? undefined}
newStatus={statusDialogData?.newStatus ?? ""}
onClose={() => setStatusDialogData(null)}
/>
</Paper>
);
};