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(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(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(null); const [currentBalanceTransfer, setCurrentBalanceTransfer] = useState(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; }; const [formattedJson, setFormattedJson] = useState(''); const [highlightedJson, setHighlightedJson] = useState(''); useEffect(() => { const obj = { a: 1, 'b': 'foo', c: [false, 'false', null, 'null', { d: { e: 1.3e5, f: '1.3e5' } }] }; const str = JSON.stringify(obj, undefined, 4); setFormattedJson(str); setHighlightedJson(syntaxHighlight(str)); }, []); function syntaxHighlight(json: any) { json = json.replace(/&/g, '&').replace(//g, '>'); return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])"(\s:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match: any) { let cls = 'number'; if (/^"/.test(match)) { if (/:$/.test(match)) { cls = 'key'; } else { cls = 'string'; } } else if (/true|false/.test(match)) { cls = 'boolean'; } else if (/null/.test(match)) { cls = 'null'; } return '' + match + ''; }); } return ( Transaction Details {/* Tabs Navigation */}
{/* {transactionDetails?.kind == 'P' && ( */} {/* )} */} {transactionDetails?.kind !== 'P' && ( )} {transactionDetails?.kind !== 'P' && ( )} {transactionDetails?.kind !== 'P' && ( )}
{/* Tab Content */}
{activeTab === 'detail' && transactionDetails?.kind === 'P' && (

Transaction Information Info

Transaction Date

{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 }) : ''}

Full Name

{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}

Amount

{(transactionDetails?.purchase?.amount ?? transactionDetails?.transfer?.amount) != null ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format( transactionDetails.purchase?.amount ?? transactionDetails.transfer?.amount ) : "-"}

Fee

{(transactionDetails?.transfer?.fee_amount ?? transactionDetails?.purchase?.fee_amount ?? 0) .toLocaleString('en-US', { style: 'currency', currency: 'USD' })}

Status

{(() => { 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 if (transactionDetails?.status === 'P') { } else if (transactionDetails?.status === 'P') { status = 'PENDING'; badgeClass = 'bg-gray-100 text-gray-800'; } else if (transactionDetails?.status === 'R') { status = 'ROLLBACK'; badgeClass = 'bg-yellow-100 text-yellow-800'; } else if (transactionDetails?.status === 'S') { status = 'REVERSAL'; badgeClass = 'bg-purple-100 text-purple-800'; } else if (transactionDetails?.status === 'R') { status = 'ROLLBACK'; badgeClass = 'bg-yellow-100 text-yellow-800'; } else if (transactionDetails?.status === 'S') { status = 'REVERSAL'; badgeClass = 'bg-purple-100 text-purple-800'; } return ( {status} ); })()}

Transaction Type

{(() => { 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'; } else if (transactionDetails?.kind === 'L') { kind = 'PURCHASE LOJA'; } else if (transactionDetails?.kind === 'B') { kind = 'TOP UP P24'; } else if (transactionDetails?.kind === 'A') { kind = 'TRANSFER AGENT'; } else if (transactionDetails?.kind === 'M') { kind = 'WITHDRAWAL AGENT'; } return kind; })()}

Description

{transactionDetails?.description || '-'}

Name

{transactionDetails?.type?.name || '-'}

Purchase Purchase

Amount

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format( transactionDetails?.purchase?.amount ?? transactionDetails?.transfer?.amount ?? 0 )}

Cashback

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format( transactionDetails?.purchase?.cashback ?? transactionDetails?.transfer?.cashback ?? 0 )}

Cashback Point

{transactionDetails?.purchase?.cashback_point ?? transactionDetails?.transfer?.cashback_point ?? 0}

Fee Amount

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format( transactionDetails?.purchase?.fee_amount ?? transactionDetails?.transfer?.fee_amount ?? 0 )}

)} {activeTab === 'detail' && transactionDetails?.kind == 'P' && transactionDetails?.kind == 'P' && (

Product Information Product Info

Product Name

{transactionDetails?.purchase?.product?.name ?? "-"}

Price Cash

{transactionDetails?.purchase?.product?.price_cash != null ? new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(transactionDetails.purchase.product.price_cash) : "-"}

Price Point

{transactionDetails?.purchase?.product?.price_point ?? "-"}

Product Type

{transactionDetails?.purchase?.product?.type ?? "-"}

Provider Name

{transactionDetails?.purchase?.product?.provider?.description ?? "-"}

Provider Type

{transactionDetails?.purchase?.product?.provider?.type === "h2h" ? "HOST TO HOST" : transactionDetails?.purchase?.product?.provider?.type === "agent" ? "AGENT" : "-"}

)} {activeTab === 'detail' && transactionDetails?.kind != 'P' && transactionDetails?.transfer != null && (

Transaction Information Info

Transaction Date

{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 }) : ''}

Full Name

{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}

Amount

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.transfer.amount)}

Fee

{(transactionDetails?.transfer?.fee_amount ?? transactionDetails?.purchase?.fee_amount ?? 0).toLocaleString('en-US', { style: 'currency', currency: 'USD' })}

Status

{(() => { let status = 'UNKNOWN'; let badgeClass = 'bg-gray-100 text-gray-800'; switch (transactionDetails?.status) { case 'C': status = 'COMPLETE'; badgeClass = 'bg-green-100 text-green-800'; break; case 'F': status = 'FAILED'; badgeClass = 'bg-red-100 text-red-800'; break; case 'O': status = 'ON PROCESS'; badgeClass = 'bg-blue-100 text-blue-800'; break; case 'P': status = 'PENDING'; badgeClass = 'bg-gray-100 text-gray-800'; break; case 'R': status = 'ROLLBACK'; badgeClass = 'bg-yellow-100 text-yellow-800'; break; case 'S': status = 'REVERSAL'; badgeClass = 'bg-purple-100 text-purple-800'; break; default: // optional: keep 'UNKNOWN' or set to null break; } return ( {status} ); })()}

Transaction Type

{(() => { 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') { } else if (transactionDetails?.kind === 'E') { kind = 'REWARD'; } return kind; })()}

Description

{transactionDetails?.description}

Name

{transactionDetails?.type?.name || '-'}

Reference

{transactionDetails?.transfer.reference}

Destination Iban

{transactionDetails?.transfer.destination_iban}

)} {activeTab === 'origincustomer' && (

Origin Customer

Full Name

{transactionDetails?.origin_customer?.origin_name}

Phone Number

{transactionDetails?.origin_msisdn}

{transactionDetails?.origin_customer?.fullname ?? transactionDetails?.origin_customer?.origin_name}

Phone Number

{transactionDetails?.origin_customer?.msisdn ?? transactionDetails?.origin_msisdn}

Email

{transactionDetails?.origin_customer?.email ?? "-"}

Username

{transactionDetails?.origin_customer?.username ?? "-"}

)} {activeTab === 'destinationcustomer' && (

Destination Customer

{transactionDetails?.transfer?.destination_customer ? (

Name

{transactionDetails.transfer.destination_customer.fullname ?? transactionDetails.transfer.destination_name}

MSISDN

{transactionDetails.transfer.destination_customer.msisdn ?? transactionDetails.transfer.destination_msisdn}

Email

{transactionDetails.transfer.destination_customer.email ?? "-"}

Username

{transactionDetails.transfer.destination_customer.username ?? "-"}

) : (

No data available

)}
)} {activeTab === 'originwallet' && (

Origin Wallet

Name

{transactionDetails?.origin_wallet.name}

Description

{transactionDetails?.origin_wallet.description}

Current Balance

{currentBalance !== null && currentBalance !== undefined ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(currentBalance) : '-'}

)} {activeTab === 'destinationwallet' && transactionDetails?.kind?.trim()?.toUpperCase() !== 'P' && (

Destination Wallet

{!transactionDetails?.transfer ? (
No Data available
) : ( <>

Name

{transactionDetails.transfer.destination_wallet.name}

Description

{transactionDetails.transfer.destination_wallet.description}

Current Balance

{currentBalanceTransfer !== null ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }).format(currentBalanceTransfer) : '-'}

)}
)} {activeTab === 'log' && (

Transaction Logs

{/* */} {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) => ( )) ) : ( )}
Type Request Date Response DateResponse BodyResponse Code Request Endpoint
{log.type || ''} {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 }) : ''} {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 }) : ''}
                                                        
                                                        
{log.request_endpoint || ''}
No logs available
)} {activeTab === 'approve' && transactionDetails?.kind == "P" && (

Approval Logs

{transactionDetails?.log_approve.length === 0 ? (

No data available

) : (
{/* */} {transactionDetails?.log_approve && transactionDetails?.log_approve.length > 0 ? ( transactionDetails.log_approve.map((log: { created_at: string; status: string; updated_at: string }, index: number) => ( {/* */} )) ) : ( )}
Status DateUpdated At
{(() => { 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; })()} {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(' ', ' ')} {log.updated_at}
No logs available
)}
)} {activeTab === 'p24' && (

P24 Logs

{transactionDetails?.p24.length === 0 ? (

No data available

) : (
{/* */} {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) => ( )) ) : ( )}
Type Request Date Response DateResponse BodyResponse Code Request Endpoint
{log.type ?? ''} {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 }) : ''} {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 }) : ''}
                                                            
                                                            
{log.request_endpoint ?? ''}
No logs available
)}
)}
{/* {showResendDialog} */} {(transactionDetails?.status === 'F' || transactionDetails?.status === 'P') && transactionDetails?.status_approve !== 'W' && (
)}
); }; export default DetailTransaction;