Files
revenue-fe/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx
wayanrivan 0b1ef14abe update
2025-05-16 10:01:50 +07:00

849 lines
53 KiB
TypeScript

import { useTransactionContext } from '../hooks/useTransactionContext';
import { useCallApi } from '@/hooks';
import { apiConfig } from '@/config/api.config';
import { useCallback, useEffect, useState } from 'react';
import ResendTransaction from './ResendTransaction';
import {
Dialog,
DialogBody,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle
} from '@/components/ui/dialog';
import { useDataGrid } from '@/components';
import { Button } from '@/components/ui/button';
const API_URL = apiConfig.transaction;
const API_URL_CURRENT_BALANCE = apiConfig.service_wallet;
const DetailTransaction = () => {
const { GetData } = useCallApi();
// const { reload } = useDataGrid();
const {
showDetailDialog,
setShowDetailDialog,
selectedTransactionId
} = useTransactionContext();
const [transactionDetails, setTransactionDetails] = useState<any>(null);
const [showResend, setResend] = useState(false);
const handleResendOpen = () => {
setResend(true);
};
const handleResendClose = () => {
setResend(false);
};
useEffect(() => {
const fetchTransactionDetails = async () => {
if (selectedTransactionId) {
try {
const response = await GetData(`${API_URL}/transaction/history/detail/${selectedTransactionId}`, {
id: selectedTransactionId
});
setTransactionDetails(response?.data);
// console.log(response?.data);
// console.log(selectedTransactionId);
} catch (error) {
console.error('Error fetching transaction', error);
}
}
};
if (showDetailDialog && selectedTransactionId) {
fetchTransactionDetails();
}
}, [showDetailDialog, selectedTransactionId, GetData]);
const [activeTab, setActiveTab] = useState('detail');
// Reset ke tab awal saat dialog dibuka
useEffect(() => {
if (showDetailDialog) {
setActiveTab('detail');
}
}, [showDetailDialog]);
const [currentBalance, setCurrentBalance] = useState<number | null>(null);
const [currentBalanceTransfer, setCurrentBalanceTransfer] = useState<number | null>(null);
useEffect(() => {
setCurrentBalance(null);
}, [transactionDetails]);
useEffect(() => {
setCurrentBalanceTransfer(null);
}, [transactionDetails]);
const getCurrentBallanceWallet = async (customerId: string) => {
try {
const responsecurrentbalance = await GetData(
`${API_URL_CURRENT_BALANCE}/dashboard/balance/account/${customerId}`,
{}
);
const match = responsecurrentbalance?.data?.find(
(item: any) => item.id_wallet === transactionDetails?.origin_wallet?.id
);
if (match) {
// console.log('Matched Wallet:', match); // Optional debug
return match.amount;
}
} catch (error) {
console.error('Error fetching current balance', error);
}
return null;
};
const getCurrentBallanceWalletTransfer = async (customerIdtransfer: string) => {
try {
const response = await GetData(
`${API_URL_CURRENT_BALANCE}/dashboard/balance/account/${customerIdtransfer}`,
{}
);
const match = response?.data?.find(
(item: any) => item.id_wallet === transactionDetails?.transfer?.destination_wallet?.id
);
if (match) {
// console.log('Matched Wallet:', match);
return match.amount;
}
} catch (error) {
console.error('Error fetching current balance', error);
}
return null;
};
return (
<Dialog open={showDetailDialog} onOpenChange={setShowDetailDialog}>
<DialogContent className="container-fixed max-w-[1024px] flex flex-col p-5 overflow-hidden">
<DialogHeader>
<DialogTitle>Transaction Details</DialogTitle>
</DialogHeader>
<DialogDescription></DialogDescription>
<DialogBody>
{/* Tabs Navigation */}
<div className="flex border-b border-gray-200">
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'detail' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('detail')}
>
Detail Transaction
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'origincustomer' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('origincustomer')}
>
Origin Customer
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'destinationcustomer' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('destinationcustomer')}
>
Destination Customer
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'originwallet' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('originwallet')}
>
Origin Wallet
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'destinationwallet' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('destinationwallet')}
>
Destination Wallet
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'log' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('log')}
>
Transaction Log
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'approve' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('approve')}
>
Approval Log
</button>
<button
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'p24' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
onClick={() => setActiveTab('p24')}
>
Log P24
</button>
</div>
{/* Tab Content */}
<div className="py-4 overflow-y-auto max-h-[400px]">
{activeTab === 'detail' && transactionDetails?.kind === 'P' && (
<div className="space-y-4">
<h3 className="font-semibold flex items-center">
Transaction Information
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Info
</span>
</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Transaction Date</p>
<p className="font-medium">
{transactionDetails?.transaction_date
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Full Name</p>
<p className="font-medium">{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Amount</p>
<p className="font-medium">
{(transactionDetails?.purchase?.amount ?? transactionDetails?.transfer?.amount) != null
? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(
transactionDetails.purchase?.amount ?? transactionDetails.transfer?.amount
)
: "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Fee</p>
<p className="font-medium">
{(transactionDetails?.transfer?.fee_amount ?? transactionDetails?.purchase?.fee_amount ?? 0)
.toLocaleString('en-US', { style: 'currency', currency: 'USD' })}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Status</p>
<div>
{(() => {
let status;
let badgeClass;
if (transactionDetails?.status === 'C') {
status = 'COMPLETE';
badgeClass = 'bg-green-100 text-green-800';
} else if (transactionDetails?.status === 'F') {
status = 'FAILED';
badgeClass = 'bg-red-100 text-red-800';
} else if (transactionDetails?.status === 'O') {
status = 'ON PROCESS';
badgeClass = 'bg-blue-100 text-blue-800';
} else {
status = 'PENDING';
badgeClass = 'bg-gray-100 text-gray-800';
}
return (
<span className={`px-3 py-1 rounded-full text-xs font-semibold ${badgeClass}`}>
{status}
</span>
);
})()}
</div>
</div>
<div>
<p className="text-sm text-gray-500">Transaction Type</p>
<p className="font-medium">
{(() => {
let kind;
if (transactionDetails?.kind === 'T') {
kind = 'TRANSFER';
} else if (transactionDetails?.kind === 'P') {
kind = 'PURCHASE';
} else if (transactionDetails?.kind === 'W') {
kind = 'WITHDRAW';
} else if (transactionDetails?.kind === 'U') {
kind = 'TOP UP';
} else if (transactionDetails?.kind === 'R') {
kind = 'RETURN';
}else if (transactionDetails?.kind === 'E') {
kind = 'REWARD';
}
return kind;
})()}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Description</p>
<p className="font-medium">{transactionDetails?.description || '-'}</p>
</div>
<div>
<p className="text-sm text-gray-500">Name</p>
<p className="font-medium">{transactionDetails?.type?.name || '-'}</p>
</div>
</div>
<h3 className="font-semibold flex items-center">
Purchase
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Purchase
</span>
</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Amount</p>
<p className="font-medium">
{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(
transactionDetails?.purchase?.amount ?? transactionDetails?.transfer?.amount ?? 0
)}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Cashback</p>
<p className="font-medium">
{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(
transactionDetails?.purchase?.cashback ?? transactionDetails?.transfer?.cashback ?? 0
)}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Cashback Point</p>
<p className="font-medium">
{transactionDetails?.purchase?.cashback_point ?? transactionDetails?.transfer?.cashback_point ?? 0}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Fee Amount</p>
<p className="font-medium">
{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(
transactionDetails?.purchase?.fee_amount ?? transactionDetails?.transfer?.fee_amount ?? 0
)}
</p>
</div>
</div>
</div>
)}
{activeTab === 'detail' && (
<div className="space-y-4">
<h3 className="font-semibold flex items-center">
Product Information
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Product Info
</span>
</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Product Name</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.name ?? "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Price Cash</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.price_cash != null
? new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(transactionDetails.purchase.product.price_cash)
: "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Price Point</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.price_point ?? "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Product Type</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.type ?? "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Provider Name</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.provider?.description ?? "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Provider Type</p>
<p className="font-medium">
{transactionDetails?.purchase?.product?.provider?.type === "h2h"
? "HOST TO HOST"
: transactionDetails?.purchase?.product?.provider?.type === "agent"
? "AGENT"
: "-"}
</p>
</div>
</div>
</div>
)}
{activeTab === 'detail' && transactionDetails?.kind != 'P' && transactionDetails?.transfer != null && (
<div className="space-y-4">
<h3 className="font-semibold flex items-center">
Transaction Information
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Info
</span>
</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Transaction Date</p>
<p className="font-medium">{transactionDetails?.transaction_date
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}</p>
</div>
<div>
<p className="text-sm text-gray-500">Full Name</p>
<p className="font-medium">{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Amount</p>
<p className="font-medium">{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.transfer.amount)}</p>
</div>
<div>
<p className="text-sm text-gray-500">Fee</p>
<p className="font-medium">
{(transactionDetails?.transfer?.fee_amount ?? transactionDetails?.purchase?.fee_amount ?? 0).toLocaleString('en-US', { style: 'currency', currency: 'USD' })}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Status</p>
<p className="font-medium">
{(() => {
let status;
if (transactionDetails?.status === 'C') {
status = 'COMPLETE';
} else if (transactionDetails?.status === 'F') {
status = 'FAILED';
} else if (transactionDetails?.status === 'O') {
status = 'ON PROCESS';
} else {
status = 'PENDING';
}
return status;
})()}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Transaction Type</p>
<p className="font-medium">
{(() => {
let kind;
if (transactionDetails?.kind === 'T') {
kind = 'TRANSFER';
} else if (transactionDetails?.kind === 'P') {
kind = 'PURCHASE';
} else if (transactionDetails?.kind === 'W') {
kind = 'WITHDRAW';
} else if (transactionDetails?.kind === 'U') {
kind = 'TOP UP';
} else if (transactionDetails?.kind === 'R') {
kind = 'RETURN';
}else if (transactionDetails?.kind === 'E') {
kind = 'REWARD';
}
return kind;
})()}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Description</p>
<p className="font-medium">{transactionDetails?.description}</p>
</div>
<div>
<p className="text-sm text-gray-500">Name</p>
<p className="font-medium">{transactionDetails?.type?.name || '-'}</p>
</div>
<div>
<p className="text-sm text-gray-500">Reference</p>
<p className="font-medium">{transactionDetails?.transfer.reference}</p>
</div>
<div>
<p className="text-sm text-gray-500">Destination Iban</p>
<p className="font-medium">{transactionDetails?.transfer.destination_iban}</p>
</div>
</div>
</div>
)}
{activeTab === 'origincustomer' && (
<div className="space-y-4">
<h3 className="font-semibold">Origin Customer</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Full Name</p>
<p className="font-medium">{transactionDetails?.origin_customer?.origin_name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Phone Number</p>
<p className="font-medium">{transactionDetails?.origin_msisdn}</p>
<p className="font-medium">{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Phone Number</p>
<p className="font-medium">{transactionDetails?.origin_customer?.msisdn ?? transactionDetails?.origin_msisdn}</p>
</div>
<div>
<p className="text-sm text-gray-500">Email</p>
<p className="font-medium">{transactionDetails?.origin_customer?.email ?? "-"}</p>
</div>
<div>
<p className="text-sm text-gray-500">Username</p>
<p className="font-medium">{transactionDetails?.origin_customer?.username ?? "-"}</p>
</div>
</div>
</div>
)}
{activeTab === 'destinationcustomer' && (
<div className="space-y-4">
<h3 className="font-semibold">Destination Customer</h3>
{transactionDetails?.transfer?.destination_customer ? (
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Name</p>
<p className="font-medium">
{transactionDetails.transfer.destination_customer.fullname ?? transactionDetails.transfer.destination_name}
</p>
</div>
<div>
<p className="text-sm text-gray-500">MSISDN</p>
<p className="font-medium">
{transactionDetails.transfer.destination_customer.msisdn ?? transactionDetails.transfer.destination_msisdn}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Email</p>
<p className="font-medium">
{transactionDetails.transfer.destination_customer.email ?? "-"}
</p>
</div>
<div>
<p className="text-sm text-gray-500">Username</p>
<p className="font-medium">
{transactionDetails.transfer.destination_customer.username ?? "-"}
</p>
</div>
</div>
) : (
<p className="text-gray-500">No data available</p>
)}
</div>
)}
{activeTab === 'originwallet' && (
<div className="space-y-4">
<h3 className="font-semibold">Origin Wallet</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Name</p>
<p className="font-medium">{transactionDetails?.origin_wallet.name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Description</p>
<p className="font-medium">{transactionDetails?.origin_wallet.description}</p>
</div>
<div>
<p className="text-sm text-gray-500">Current Balance</p>
<p className="font-medium">
{currentBalance !== null && currentBalance !== undefined
? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(currentBalance)
: '-'}
</p>
</div>
</div>
<Button
className="btn btn-primary"
type="button"
onClick={async () => {
const balance = await getCurrentBallanceWallet(transactionDetails?.origin_customer.id);
if (balance !== null) {
setCurrentBalance(balance);
}
}}
>
Generate Current Balance
</Button>
</div>
)}
{activeTab === 'destinationwallet' && (
<div className="space-y-4">
<h3 className="font-semibold">Destination Wallet</h3>
{!transactionDetails?.transfer ? (
<div className="text-sm text-gray-500">No Data available</div>
) : (
<>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-500">Name</p>
<p className="font-medium">{transactionDetails.transfer.destination_wallet.name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Description</p>
<p className="font-medium">{transactionDetails.transfer.destination_wallet.description}</p>
</div>
<div>
<p className="text-sm text-gray-500">Current Balance</p>
<p className="font-medium">
{currentBalanceTransfer !== null
? new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(currentBalanceTransfer)
: '-'}
</p>
</div>
</div>
<Button
className="btn btn-primary"
type="button"
onClick={async () => {
const customerId = transactionDetails?.transfer?.destination_customer?.id;
const balance = await getCurrentBallanceWalletTransfer(customerId);
if (balance !== null) {
setCurrentBalanceTransfer(balance); // ✅ INI YANG BENAR
}
}}
>
Generate Current Balance
</Button>
</>
)}
</div>
)}
{activeTab === 'log' && (
<div className="space-y-4">
<h3 className="font-semibold">Transaction Logs</h3>
<div className="border rounded-lg overflow-x-auto">
<table className="min-w-full table-auto">
<thead>
<tr className="bg-gray-100">
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Date</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
</tr>
</thead>
<tbody>
{transactionDetails?.log && transactionDetails?.log.length > 0 ? (
transactionDetails.log.map((log: { type: string, request_endpoint: string, status: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
<tr key={index} className="border-t">
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date
? new Date(log.request_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date
? new Date(log.response_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint}</td>
</tr>
))
) : (
<tr>
<td colSpan={3} className="px-4 py-2 text-center text-sm text-gray-500">
No logs available
</td>
</tr>
)}
</tbody>
</table>
</div>
</div>
)}
{activeTab === 'approve' && (
<div className="space-y-4">
<h3 className="font-semibold">Approval Logs</h3>
{transactionDetails?.log_approve.length === 0 ? (
<p className="text-sm text-gray-500">No data available</p>
) : (
<div className="border rounded-lg overflow-x-auto">
<table className="min-w-full table-auto">
<thead>
<tr className="bg-gray-100">
<th className="px-4 py-2 text-left text-sm text-gray-500">Status</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Date</th>
{/* <th className="px-4 py-2 text-left text-sm text-gray-500">Updated At</th> */}
</tr>
</thead>
<tbody>
{transactionDetails?.log_approve && transactionDetails?.log_approve.length > 0 ? (
transactionDetails.log_approve.map((log: { created_at: string; status: string; updated_at: string }, index: number) => (
<tr key={index} className="border-t">
<td className="px-4 py-2 font-medium">
{(() => {
let status;
if (log.status === 'W') {
status = 'WAITING';
} else if (log.status === 'Y') {
status = 'APPROVE';
} else if (log.status === 'N') {
status = 'REJECT';
} else if (log.status === 'T') {
status = 'NO NEED';
}
return status;
})()}
</td>
<td className="px-4 py-2 text-sm text-gray-500">
{new Date(log.created_at).toLocaleString('sv-SE', {
timeZone: 'Asia/Jakarta', // kalau kamu mau waktu lokal (optional)
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
}).replace(' ', ' ')}
</td>
{/* <td className="px-4 py-2 text-sm text-gray-500">{log.updated_at}</td> */}
</tr>
))
) : (
<tr>
<td colSpan={3} className="px-4 py-2 text-center text-sm text-gray-500">
No logs available
</td>
</tr>
)}
</tbody>
</table>
</div>
)}
</div>
)}
{activeTab === 'p24' && (
<div className="space-y-4">
<h3 className="font-semibold">P24 Logs</h3>
{transactionDetails?.p24.length === 0 ? (
<p className="text-sm text-gray-500">No data available</p>
) : (
<div className="border rounded-lg overflow-x-auto">
<table className="min-w-full table-auto">
<thead>
<tr className="bg-gray-100">
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Date</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
</tr>
</thead>
<tbody>
{transactionDetails?.p24 && transactionDetails?.p24.length > 0 ? (
transactionDetails.p24.map((log: { request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
<tr key={index} className="border-t">
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date
? new Date(log.request_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date
? new Date(log.response_date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
: ''}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? '-'}</td>
</tr>
))
) : (
<tr>
<td colSpan={3} className="px-4 py-2 text-center text-sm text-gray-500">
No logs available
</td>
</tr>
)}
</tbody>
</table>
</div>
)}
</div>
)}
</div>
{/* {showResendDialog} */}
{(transactionDetails?.status === 'F' || transactionDetails?.status === 'P') && transactionDetails?.status_approve !== 'W' && (
<div className="flex justify-end mt-4">
<button className="btn btn-primary" onClick={handleResendOpen}>Retry Transaction</button>
<ResendTransaction isOpen={showResend} onClose={handleResendClose} selectedTransactionForResend={transactionDetails} />
</div>
)}
</DialogBody>
</DialogContent>
</Dialog>
);
};
export default DetailTransaction;