update
This commit is contained in:
@ -155,35 +155,6 @@ const DetailTransaction = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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, '<').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 '<span className="' + cls + '">' + match + '</span>';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={showDetailDialog} onOpenChange={setShowDetailDialog}>
|
<Dialog open={showDetailDialog} onOpenChange={setShowDetailDialog}>
|
||||||
<DialogContent className="container-fixed max-w-[1024px] flex flex-col p-5 overflow-hidden">
|
<DialogContent className="container-fixed max-w-[1024px] flex flex-col p-5 overflow-hidden">
|
||||||
@ -392,7 +363,7 @@ const DetailTransaction = () => {
|
|||||||
kind = 'TOP UP';
|
kind = 'TOP UP';
|
||||||
} else if (transactionDetails?.kind === 'R') {
|
} else if (transactionDetails?.kind === 'R') {
|
||||||
kind = 'RETURN';
|
kind = 'RETURN';
|
||||||
}else if (transactionDetails?.kind === 'E') {
|
} else if (transactionDetails?.kind === 'E') {
|
||||||
kind = 'REWARD';
|
kind = 'REWARD';
|
||||||
} else if (transactionDetails?.kind === 'L') {
|
} else if (transactionDetails?.kind === 'L') {
|
||||||
kind = 'PURCHASE LOJA';
|
kind = 'PURCHASE LOJA';
|
||||||
@ -460,58 +431,58 @@ const DetailTransaction = () => {
|
|||||||
|
|
||||||
|
|
||||||
{activeTab === 'detail' && transactionDetails?.kind == 'P' && transactionDetails?.kind == 'P' && (
|
{activeTab === 'detail' && transactionDetails?.kind == 'P' && transactionDetails?.kind == 'P' && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold flex items-center">
|
<h3 className="font-semibold flex items-center">
|
||||||
Product Information
|
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">
|
<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
|
Product Info
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Product Name</p>
|
<p className="text-sm text-gray-500">Product Name</p>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
{transactionDetails?.purchase?.product?.name ?? "-"}
|
{transactionDetails?.purchase?.product?.name ?? "-"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Price Cash</p>
|
<p className="text-sm text-gray-500">Price Cash</p>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
{transactionDetails?.purchase?.product?.price_cash != null
|
{transactionDetails?.purchase?.product?.price_cash != null
|
||||||
? new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(transactionDetails.purchase.product.price_cash)
|
? 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>
|
</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>
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'detail' && transactionDetails?.kind != 'P' && transactionDetails?.transfer != null && (
|
{activeTab === 'detail' && transactionDetails?.kind != 'P' && transactionDetails?.transfer != null && (
|
||||||
@ -555,47 +526,37 @@ const DetailTransaction = () => {
|
|||||||
<p className="text-sm text-gray-500">Status</p>
|
<p className="text-sm text-gray-500">Status</p>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
{(() => {
|
{(() => {
|
||||||
let status;
|
let status = 'UNKNOWN';
|
||||||
let badgeClass;
|
let badgeClass = 'bg-gray-100 text-gray-800';
|
||||||
|
|
||||||
let badgeClass;
|
switch (transactionDetails?.status) {
|
||||||
|
case 'C':
|
||||||
if (transactionDetails?.status === 'C') {
|
status = 'COMPLETE';
|
||||||
status = 'COMPLETE';
|
badgeClass = 'bg-green-100 text-green-800';
|
||||||
badgeClass = 'bg-green-100 text-green-800';
|
break;
|
||||||
badgeClass = 'bg-green-100 text-green-800';
|
case 'F':
|
||||||
} else if (transactionDetails?.status === 'F') {
|
status = 'FAILED';
|
||||||
status = 'FAILED';
|
badgeClass = 'bg-red-100 text-red-800';
|
||||||
badgeClass = 'bg-red-100 text-red-800';
|
break;
|
||||||
badgeClass = 'bg-red-100 text-red-800';
|
case 'O':
|
||||||
} else if (transactionDetails?.status === 'O') {
|
status = 'ON PROCESS';
|
||||||
status = 'ON PROCESS';
|
badgeClass = 'bg-blue-100 text-blue-800';
|
||||||
badgeClass = 'bg-blue-100 text-blue-800';
|
break;
|
||||||
} else if (transactionDetails?.status === 'P') {
|
case 'P':
|
||||||
badgeClass = 'bg-blue-100 text-blue-800';
|
status = 'PENDING';
|
||||||
} else if (transactionDetails?.status === 'P') {
|
badgeClass = 'bg-gray-100 text-gray-800';
|
||||||
status = 'PENDING';
|
break;
|
||||||
badgeClass = 'bg-gray-100 text-gray-800';
|
case 'R':
|
||||||
} else if (transactionDetails?.status === 'R') {
|
status = 'ROLLBACK';
|
||||||
status = 'ROLLBACK';
|
badgeClass = 'bg-yellow-100 text-yellow-800';
|
||||||
badgeClass = 'bg-yellow-100 text-yellow-800';
|
break;
|
||||||
} else if (transactionDetails?.status === 'S') {
|
case 'S':
|
||||||
status = 'REVERSAL';
|
status = 'REVERSAL';
|
||||||
badgeClass = 'bg-purple-100 text-purple-800';
|
badgeClass = 'bg-purple-100 text-purple-800';
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
return (
|
// optional: keep 'UNKNOWN' or set to null
|
||||||
<span className={`px-3 py-1 rounded-full text-xs font-semibold ${badgeClass}`}>
|
break;
|
||||||
{status}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
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';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -604,6 +565,7 @@ const DetailTransaction = () => {
|
|||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
})()}
|
})()}
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -751,7 +713,6 @@ const DetailTransaction = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'destinationwallet' && transactionDetails?.kind?.trim()?.toUpperCase() !== 'P' && (
|
|
||||||
{activeTab === 'destinationwallet' && transactionDetails?.kind?.trim()?.toUpperCase() !== 'P' && (
|
{activeTab === 'destinationwallet' && transactionDetails?.kind?.trim()?.toUpperCase() !== 'P' && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h3 className="font-semibold">Destination Wallet</h3>
|
<h3 className="font-semibold">Destination Wallet</h3>
|
||||||
@ -798,6 +759,7 @@ const DetailTransaction = () => {
|
|||||||
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
@ -883,68 +845,67 @@ const DetailTransaction = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'approve' && transactionDetails?.kind == "P" && (
|
{activeTab === 'approve' && transactionDetails?.kind == "P" && (
|
||||||
{activeTab === 'approve' && transactionDetails?.kind == "P" && (
|
<div className="space-y-4">
|
||||||
<div className="space-y-4">
|
<h3 className="font-semibold">Approval Logs</h3>
|
||||||
<h3 className="font-semibold">Approval Logs</h3>
|
{transactionDetails?.log_approve.length === 0 ? (
|
||||||
{transactionDetails?.log_approve.length === 0 ? (
|
<p className="text-sm text-gray-500">No data available</p>
|
||||||
<p className="text-sm text-gray-500">No data available</p>
|
) : (
|
||||||
) : (
|
<div className="border rounded-lg overflow-x-auto">
|
||||||
<div className="border rounded-lg overflow-x-auto">
|
<table className="min-w-full table-auto">
|
||||||
<table className="min-w-full table-auto">
|
<thead>
|
||||||
<thead>
|
<tr className="bg-gray-100">
|
||||||
<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">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">Date</th>
|
{/* <th className="px-4 py-2 text-left text-sm text-gray-500">Updated At</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>
|
</tr>
|
||||||
)}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{transactionDetails?.log_approve && transactionDetails?.log_approve.length > 0 ? (
|
||||||
</div>
|
transactionDetails.log_approve.map((log: { created_at: string; status: string; updated_at: string }, index: number) => (
|
||||||
)}
|
<tr key={index} className="border-t">
|
||||||
</div>
|
<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' && (
|
{activeTab === 'p24' && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user