From f959a477f191b77d32c366345a33ca437292cb58 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Fri, 11 Apr 2025 14:22:20 +0700 Subject: [PATCH] Update approval transaction --- .../blocks/ApprovalDialog.tsx | 83 +++++-- .../blocks/DetailApprovalTransaction.tsx | 233 ++++++++++++------ .../blocks/ListToolbar.tsx | 8 +- .../hooks/ApprovalTransactionContext.tsx | 43 ++-- .../blocks/DetailTransaction.tsx | 188 ++++++++------ .../blocks/ListToolbar.tsx | 8 +- .../hooks/TransactionContext.tsx | 56 +++-- 7 files changed, 395 insertions(+), 224 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx index 6108b50..779e189 100644 --- a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx @@ -1,14 +1,13 @@ import { useTransactionContext } from '../hooks/useApprovalTransactionContext'; import { useCallApi } from '@/hooks'; import { apiConfig } from '@/config/api.config'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { Dialog, DialogBody, DialogContent, - DialogDescription, DialogHeader, - DialogTitle + DialogTitle, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { @@ -16,9 +15,9 @@ import { SelectContent, SelectItem, SelectTrigger, - SelectValue + SelectValue, } from '@/components/ui/select'; -import { Alert, KeenIcon, useDataGrid } from '@/components'; +import { Alert, useDataGrid } from '@/components'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { toast } from 'sonner'; import { Input } from '@/components/ui/input'; @@ -27,11 +26,11 @@ const API_URL = apiConfig.transaction; const ApprovalDialog = () => { const { GetData, PostData } = useCallApi(); - // const { reload } = useDataGrid(); + const { showApprovalDialog, setShowApprovalDialog, - selectedTransactionIdForApproval + selectedTransactionIdForApproval, } = useTransactionContext(); const [transactionDetails, setTransactionDetails] = useState(null); @@ -39,12 +38,12 @@ const ApprovalDialog = () => { const [formField, setFormField] = useState({ transaction_code: '', status: '', - notes: '' + notes: '', }); const [alert, setAlert] = useState({ show: false, - message: '' + message: '', }); const doApproval = useCallback( @@ -60,39 +59,51 @@ const ApprovalDialog = () => { toast.error('Please select a status.'); return; } - const response = await PostData(`${API_URL}/transaction/set-approval`, { - transaction_code: transactionDetails.id, + id_transaction: transactionDetails.id, status: formField.status, - notes: formField.notes + notes: formField.notes, }); if (response?.status) { - setAlert((prev) => ({ ...prev, show: false, message: '' })); + setAlert({ show: false, message: '' }); toast.success('Success Update Position'); const createActivity = { module: 'Approval Transaction', description: `Change status approve for transaction => ${transactionDetails.code}`, - action: 'U' + action: 'U', }; doSaveLogActivity(createActivity); - setShowApprovalDialog(false); // optionally close dialog + setShowApprovalDialog(false); } else { - setAlert((prev) => ({ ...prev, show: true, message: response?.message })); + setAlert({ show: true, message: response?.message }); } }, [formField, transactionDetails] ); + useEffect(() => { + if (showApprovalDialog) { + // Reset form fields when dialog opens + setFormField({ + transaction_code: '', + status: '', + notes: '', + }); + setTransactionDetails(null); // Optional reset + } + }, [showApprovalDialog]); + useEffect(() => { const fetchTransactionDetails = async () => { if (selectedTransactionIdForApproval) { try { - const response = await GetData(`${API_URL}/transaction/history/detail/${selectedTransactionIdForApproval}`, { - id: selectedTransactionIdForApproval - }); - // console.log(response?.data.code); - // console.log(selectedTransactionIdForApproval); + const response = await GetData( + `${API_URL}/transaction/history/detail/${selectedTransactionIdForApproval}`, + { + id: selectedTransactionIdForApproval, + } + ); setTransactionDetails(response?.data); } catch (error) { console.error('Error fetching transaction', error); @@ -105,6 +116,15 @@ const ApprovalDialog = () => { } }, [showApprovalDialog, selectedTransactionIdForApproval, GetData]); + // Set formField.transaction_code once details are fetched + useEffect(() => { + if (transactionDetails) { + setFormField((prev) => ({ + ...prev, + transaction_code: transactionDetails.id ?? '', + })); + } + }, [transactionDetails]); return ( @@ -113,7 +133,7 @@ const ApprovalDialog = () => { Approval Transaction -
+
@@ -122,7 +142,9 @@ const ApprovalDialog = () => {
+ onChange={(e) => + setFormField((prev) => ({ + ...prev, + notes: e.target.value, + })) + } + />
)} @@ -164,4 +193,4 @@ const ApprovalDialog = () => { ); }; -export default ApprovalDialog; +export default ApprovalDialog; \ No newline at end of file diff --git a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx index e0d0ecc..e032a94 100644 --- a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx +++ b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx @@ -66,6 +66,24 @@ const DetailApprovalTransaction = () => { > Origin Customer + + +

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 { status = 'PENDING'; + badgeClass = 'bg-gray-100 text-gray-800'; } - return status; + + return ( + + {status} + + ); })()} -

+
+

Transaction Type

@@ -172,14 +201,7 @@ const DetailApprovalTransaction = () => {
-
-

Name

-

{transactionDetails?.origin_wallet.name}

-
-
-

Description

-

{transactionDetails?.origin_wallet.description}

-
+

@@ -208,8 +230,54 @@ const DetailApprovalTransaction = () => {

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

+ Product Information + + Product Info + +

+
+
+

Product Name

+

{transactionDetails?.purchase.product.name}

+
+
+

Price Cash

+ {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

+

+ {(() => { + let providertype; + if (transactionDetails?.purchase.product.provider.type === 'h2h') { + providertype = 'HOST TO HOST'; + } else if (transactionDetails?.purchase.product.provider.type === 'agent') { + providertype = 'AGENT'; + } + return providertype; + })()} +

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

Transaction Information @@ -291,69 +359,9 @@ const DetailApprovalTransaction = () => {

{transactionDetails?.transfer.destination_iban}

- -

- Destination Wallet - - Wallet - -

-
-
-

Name

-

{transactionDetails?.transfer.destination_wallet.name}

-
-
-

Description

-

{transactionDetails?.transfer.destination_wallet.description}

-
-
- -

- Destination Customer - - Destination Customer - -

-
-
-

Name

-

{transactionDetails?.transfer.destination_customer.fullname}

-
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.msisdn}

-
-
-

Email

-

{transactionDetails?.transfer.destination_customer.email}

-
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.username}

-
-
- -

- Origin Wallet - - Wallet - -

-
-
-

Name

-

{transactionDetails?.origin_wallet.name}

-
-
-

Description

-

{transactionDetails?.origin_wallet.description}

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

Origin Customer

@@ -378,6 +386,68 @@ const DetailApprovalTransaction = () => {
)} + {activeTab === 'destinationcustomer' && ( +
+

Destination Customer

+
+
+

Name

+

{transactionDetails?.transfer.destination_customer.fullname}

+
+
+

MSISDN

+

{transactionDetails?.transfer.destination_customer.msisdn}

+
+
+

Email

+

{transactionDetails?.transfer.destination_customer.email}

+
+
+

Username

+

{transactionDetails?.transfer.destination_customer.username}

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

Origin Wallet

+
+
+

Name

+

{transactionDetails?.origin_wallet.name}

+
+
+

Description

+

{transactionDetails?.origin_wallet.description}

+
+
+
+ )} + + {activeTab === 'destinationwallet' && ( +
+

Destination Wallet

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

Name

+

{transactionDetails.transfer.destination_wallet.name}

+
+
+

Description

+

{transactionDetails.transfer.destination_wallet.description}

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

Transaction Logs

@@ -443,8 +513,8 @@ const DetailApprovalTransaction = () => { Status - Created At - Updated At + Date + {/* Updated At */} @@ -466,8 +536,19 @@ const DetailApprovalTransaction = () => { return status; })()} - {log.created_at} - {log.updated_at} + + {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} */} )) ) : ( diff --git a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx index 3247955..3a82db3 100644 --- a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx @@ -18,12 +18,10 @@ const ListToolbar = () => { // useEffect to set the default date values useEffect(() => { const today = new Date(); - const nextWeek = new Date(today); - nextWeek.setDate(today.getDate() + 7); - + const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); settrxDate({ - from: formatDate(today), // Set 'from' to today - to: formatDate(nextWeek), // Set 'to' to 7 days later + from: formatDate(firstDayOfMonth), + to: formatDate(today), }); }, []); diff --git a/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx b/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx index fb4536c..c8b5854 100644 --- a/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx +++ b/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx @@ -155,7 +155,7 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } }, { accessorKey: 'type.name', - header: ({ column }) => , + header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { @@ -163,22 +163,35 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } }, }, { - accessorFn: (row) => { - switch (row.status_approve) { - case 'W': return 'WAITING APPROVAL'; - case 'Y': return 'APPROVED'; - case 'N': return 'REJECTED'; - default: return 'PENDING'; + accessorKey: 'status_approve', + header: 'Status', + cell: ({ row }) => { + const statusCode = row.original.status_approve; + let label = ''; + let badgeClass = ''; + + switch (statusCode) { + case 'Y': + label = 'APPROVED'; + badgeClass = 'bg-green-100 text-green-800'; + break; + case 'N': + label = 'REJECTED'; + badgeClass = 'bg-red-100 text-red-800'; + break; + case 'W': + label = 'WAITING APPROVAL'; + badgeClass = 'bg-gray-100 text-gray-800'; + break; } + + return ( + + {label} + + ); }, - id: 'status_approve', - header: ({ column }) => , - enableSorting: false, - enableHiding: false, - meta: { - headerClassName: 'w-[250px]', - }, - }, + }, { id: 'actions', header: ({ column }) => , diff --git a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx index 6b44bdc..55db0a0 100644 --- a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx +++ b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx @@ -30,7 +30,6 @@ const DetailTransaction = () => { const response = await GetData(`${API_URL}/transaction/history/detail/${selectedTransactionId}`, { id: selectedTransactionId }); - // console.log(response?.data); setTransactionDetails(response?.data); } catch (error) { console.error('Error fetching transaction', error); @@ -66,6 +65,24 @@ const DetailTransaction = () => { > Origin Customer + + +

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 { status = 'PENDING'; + badgeClass = 'bg-gray-100 text-gray-800'; } - return status; + + return ( + + {status} + + ); })()} -

+
+

Transaction Type

@@ -172,14 +200,7 @@ const DetailTransaction = () => {
-
-

Name

-

{transactionDetails?.origin_wallet.name}

-
-
-

Description

-

{transactionDetails?.origin_wallet.description}

-
+

@@ -246,7 +267,7 @@ const DetailTransaction = () => { providertype = 'HOST TO HOST'; } else if (transactionDetails?.purchase.product.provider.type === 'agent') { providertype = 'AGENT'; - } + } return providertype; })()}

@@ -337,69 +358,9 @@ const DetailTransaction = () => {

{transactionDetails?.transfer.destination_iban}

- -

- Destination Wallet - - Wallet - -

-
-
-

Name

-

{transactionDetails?.transfer.destination_wallet.name}

-
-
-

Description

-

{transactionDetails?.transfer.destination_wallet.description}

-
-
- -

- Destination Customer - - Destination Customer - -

-
-
-

Name

-

{transactionDetails?.transfer.destination_customer.fullname}

-
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.msisdn}

-
-
-

Email

-

{transactionDetails?.transfer.destination_customer.email}

-
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.username}

-
-
- -

- Origin Wallet - - Wallet - -

-
-
-

Name

-

{transactionDetails?.origin_wallet.name}

-
-
-

Description

-

{transactionDetails?.origin_wallet.description}

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

Origin Customer

@@ -424,6 +385,68 @@ const DetailTransaction = () => {
)} + {activeTab === 'destinationcustomer' && ( +
+

Destination Customer

+
+
+

Name

+

{transactionDetails?.transfer.destination_customer.fullname}

+
+
+

MSISDN

+

{transactionDetails?.transfer.destination_customer.msisdn}

+
+
+

Email

+

{transactionDetails?.transfer.destination_customer.email}

+
+
+

Username

+

{transactionDetails?.transfer.destination_customer.username}

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

Origin Wallet

+
+
+

Name

+

{transactionDetails?.origin_wallet.name}

+
+
+

Description

+

{transactionDetails?.origin_wallet.description}

+
+
+
+ )} + + {activeTab === 'destinationwallet' && ( +
+

Destination Wallet

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

Name

+

{transactionDetails.transfer.destination_wallet.name}

+
+
+

Description

+

{transactionDetails.transfer.destination_wallet.description}

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

Transaction Logs

@@ -489,8 +512,8 @@ const DetailTransaction = () => { Status - Created At - Updated At + Date + {/* Updated At */} @@ -512,8 +535,19 @@ const DetailTransaction = () => { return status; })()} - {log.created_at} - {log.updated_at} + + {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} */} )) ) : ( diff --git a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx index afc8ac5..e0a15c3 100644 --- a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx @@ -18,12 +18,10 @@ const ListToolbar = () => { // useEffect to set the default date values useEffect(() => { const today = new Date(); - const nextWeek = new Date(today); - nextWeek.setDate(today.getDate() + 7); - + const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); settrxDate({ - from: formatDate(today), // Set 'from' to today - to: formatDate(nextWeek), // Set 'to' to 7 days later + from: formatDate(firstDayOfMonth), + to: formatDate(today), }); }, []); diff --git a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx index 273dd4f..6a39771 100644 --- a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx +++ b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx @@ -84,7 +84,7 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { }); return formattedDateTime; // Format DD-MM-YYYY HH:MM:SS (menggunakan waktu yang sudah ada) } - }, + }, { accessorKey: 'origin_customer.fullname', header: ({ column }) => , @@ -125,19 +125,6 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { }, }, { - accessorFn: (row) => { - let status; - if (row.status === 'C') { - status = 'COMPLETE'; - } else if (row.status === 'F') { - status = 'FAILED'; - } else if (row.status === 'O') { - status = 'ON PROCESS'; - } else { - status = 'PENDING'; - } - return status; - }, accessorKey: 'status', header: ({ column }) => , enableSorting: false, @@ -145,7 +132,37 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { meta: { headerClassName: 'w-[250px]', }, - }, + cell: ({ row }) => { + const statusCode = row.original.status; + let label = ''; + let badgeClass = ''; + + switch (statusCode) { + case 'C': + label = 'COMPLETE'; + badgeClass = 'bg-green-100 text-green-800'; + break; + case 'F': + label = 'FAILED'; + badgeClass = 'bg-red-100 text-red-800'; + break; + case 'O': + label = 'ON PROCESS'; + badgeClass = 'bg-blue-100 text-blue-800'; + break; + default: + label = 'PENDING'; + badgeClass = 'bg-gray-100 text-gray-800'; + break; + } + + return ( + + {label} + + ); + }, + }, { accessorKey: 'description', header: ({ column }) => , @@ -201,11 +218,12 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { if (filter == undefined || filter.length == 0) { const today = new Date(); - const nextWeek = new Date(); - nextWeek.setDate(today.getDate() + 7); - startdate = today.toISOString().split('T')[0]; - enddate = nextWeek.toISOString().split('T')[0]; + // Tanggal 1 di bulan sekarang + const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + + startdate = firstDayOfMonth.toISOString().split('T')[0]; + enddate = today.toISOString().split('T')[0]; } else if (filter != undefined || filter.length != 0) { startdate = filter[0].value.from; enddate = filter[0].value.to;