Merge branch 'master' of https://git.shiblysolution.id/TPAY/dashboard
This commit is contained in:
@ -683,11 +683,11 @@ const DetailApprovalTransaction = () => {
|
||||
<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">Transaction Status</th>
|
||||
<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">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">Request Body</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>
|
||||
@ -861,14 +861,14 @@ const DetailApprovalTransaction = () => {
|
||||
<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">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">Request Body</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: { status: string,request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
||||
transactionDetails.p24.map((log: { status: string, 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">
|
||||
{(() => {
|
||||
@ -912,6 +912,22 @@ const DetailApprovalTransaction = () => {
|
||||
hour12: false
|
||||
})
|
||||
: ''}</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-500">
|
||||
<pre style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap' }}>
|
||||
{(() => {
|
||||
try {
|
||||
if (log.request_body === null) {
|
||||
return '';
|
||||
}
|
||||
const parsed = JSON.parse(log.request_body);
|
||||
return JSON.stringify(parsed, null, 2) ?? '';
|
||||
} catch (e) {
|
||||
return log.request_body ?? ''; // fallback: tampilkan as-is jika gagal parse
|
||||
}
|
||||
})()}
|
||||
</pre>
|
||||
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-500">
|
||||
<pre style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap' }}>
|
||||
{(() => {
|
||||
@ -927,22 +943,7 @@ const DetailApprovalTransaction = () => {
|
||||
})()}
|
||||
</pre>
|
||||
</td>
|
||||
<td className="px-4 py-2 text-sm text-gray-500">
|
||||
<pre style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap' }}>
|
||||
{(() => {
|
||||
try {
|
||||
if (log.request_body === null) {
|
||||
return '';
|
||||
}
|
||||
const parsed = JSON.parse(log.request_body);
|
||||
return JSON.stringify(parsed, null, 2) ?? '';
|
||||
} catch (e) {
|
||||
return log.response_body ?? ''; // fallback: tampilkan as-is jika gagal parse
|
||||
}
|
||||
})()}
|
||||
</pre>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? ''}</td>
|
||||
|
||||
@ -175,6 +175,24 @@ const DetailTransaction = () => {
|
||||
</button>
|
||||
{/* )} */}
|
||||
|
||||
{transactionDetails?.kind == 'P' && (
|
||||
<button
|
||||
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'purchase' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
|
||||
onClick={() => setActiveTab('purchase')}
|
||||
>
|
||||
Purchase Detail
|
||||
</button>
|
||||
)}
|
||||
|
||||
{transactionDetails?.kind == 'P' && (
|
||||
<button
|
||||
className={`py-2 px-4 font-medium text-sm focus:outline-none ${activeTab === 'productdetail' ? 'text-blue-600 border-b-2 border-blue-600' : 'text-gray-500 hover:text-gray-700'}`}
|
||||
onClick={() => setActiveTab('productdetail')}
|
||||
>
|
||||
Product Detail
|
||||
</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')}
|
||||
@ -229,15 +247,105 @@ const DetailTransaction = () => {
|
||||
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
{activeTab === 'purchase' && (
|
||||
<>
|
||||
<h3 className="font-semibold flex items-center mt-4">
|
||||
Purchase
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-4 mt-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>
|
||||
</>
|
||||
)}
|
||||
|
||||
{activeTab === 'productdetail' && (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
<h3 className="font-semibold flex items-center mt-4">
|
||||
Product Information
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-4 mt-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>
|
||||
</>
|
||||
)}
|
||||
|
||||
<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>
|
||||
@ -259,7 +367,7 @@ const DetailTransaction = () => {
|
||||
</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>
|
||||
<p className="font-medium">{transactionDetails?.origin_customer?.origin_name ?? ""}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">Amount</p>
|
||||
@ -348,7 +456,24 @@ const DetailTransaction = () => {
|
||||
kind = 'TRANSFER AGENT';
|
||||
} else if (transactionDetails?.kind === 'M') {
|
||||
kind = 'WITHDRAWAL AGENT';
|
||||
}else if( transactionDetails?.kind === 'O') {
|
||||
kind = 'TOPUP AGENT';
|
||||
}else if (transactionDetails?.kind === 'S') {
|
||||
kind = 'TOPUP P24';
|
||||
}else if (transactionDetails?.kind === 'I') {
|
||||
kind = 'WITHDRAW MERCHANT';
|
||||
}else if (transactionDetails?.kind === 'D') {
|
||||
kind = 'DONATION';
|
||||
}else if (transactionDetails?.kind === 'F') {
|
||||
kind = 'FEE';
|
||||
}else if (transactionDetails?.kind === 'V') {
|
||||
kind = 'REVERSAL';
|
||||
}else if( transactionDetails?.kind === 'C') {
|
||||
kind = 'CASHBACK CASH';
|
||||
}else if( transactionDetails?.kind === 'H') {
|
||||
kind = 'CASHBACK POINT';
|
||||
}
|
||||
|
||||
return kind;
|
||||
})()}
|
||||
</p>
|
||||
@ -363,100 +488,6 @@ const DetailTransaction = () => {
|
||||
</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' && transactionDetails?.kind == 'P' && transactionDetails?.kind == 'P' && (
|
||||
<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>
|
||||
)}
|
||||
|
||||
@ -485,7 +516,7 @@ const DetailTransaction = () => {
|
||||
</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>
|
||||
<p className="font-medium">{transactionDetails?.origin_customer?.origin_name ?? ""}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">Amount</p>
|
||||
@ -597,7 +628,7 @@ const DetailTransaction = () => {
|
||||
<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>
|
||||
<p className="font-medium">{transactionDetails?.origin_customer?.origin_name ?? ""}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">Phone Number</p>
|
||||
@ -748,8 +779,8 @@ const DetailTransaction = () => {
|
||||
<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">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">Request Body</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>
|
||||
@ -922,14 +953,14 @@ const DetailTransaction = () => {
|
||||
<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">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">Request Body</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: { status: string,request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
||||
transactionDetails.p24.map((log: { status: string, 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">
|
||||
{(() => {
|
||||
@ -992,10 +1023,10 @@ const DetailTransaction = () => {
|
||||
<pre style={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap' }}>
|
||||
{(() => {
|
||||
try {
|
||||
if (log.request_body === null) {
|
||||
if (log.response_body === null) {
|
||||
return '';
|
||||
}
|
||||
const parsed = JSON.parse(log.request_body);
|
||||
const parsed = JSON.parse(log.response_body);
|
||||
return JSON.stringify(parsed, null, 2) ?? '';
|
||||
} catch (e) {
|
||||
return log.response_body ?? ''; // fallback: tampilkan as-is jika gagal parse
|
||||
|
||||
@ -170,6 +170,7 @@ const ListToolbar = () => {
|
||||
<SelectValue placeholder="Select Transaction Type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
||||
<SelectItem value="T">TRANSFER</SelectItem>
|
||||
<SelectItem value="P">PURCHASE</SelectItem>
|
||||
<SelectItem value="W">WITHDRAW</SelectItem>
|
||||
@ -181,6 +182,14 @@ const ListToolbar = () => {
|
||||
<SelectItem value="B">TOP UP P24</SelectItem>
|
||||
<SelectItem value="A">TRANSFER AGENT</SelectItem>
|
||||
<SelectItem value="M">WITHDRAWAL AGENT</SelectItem>
|
||||
<SelectItem value="O">TOP UP AGENT</SelectItem>
|
||||
<SelectItem value="S">TRANSFER P24</SelectItem>
|
||||
<SelectItem value="I">WITHDRAW MERCHANT</SelectItem>
|
||||
<SelectItem value="D">DONATION</SelectItem>
|
||||
<SelectItem value="F">FEE</SelectItem>
|
||||
<SelectItem value="V">REVERSAL</SelectItem>
|
||||
<SelectItem value="C">CASHBACK CASH</SelectItem>
|
||||
<SelectItem value="H">CASHBACK POINT</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
@ -82,6 +82,14 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
case 'B': return 'TOP UP P24';
|
||||
case 'A': return 'TRANSFER AGENT';
|
||||
case 'M': return 'WITHDRAWAL AGENT';
|
||||
case 'O': return 'TOP UP AGENT';
|
||||
case 'S': return 'TRANSFER P24';
|
||||
case 'I': return 'WIJTDRAW MERCHANT';
|
||||
case 'D': return 'DONATION';
|
||||
case 'F': return 'FEE';
|
||||
case 'V': return 'REVERSAL';
|
||||
case 'C': return 'CASHBACK CASH';
|
||||
case 'H': return 'CASHBACK POINT';
|
||||
default: return '_';
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user