Merge branch 'master' of https://git.shiblysolution.id/TPAY/dashboard
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Dialog, DialogContent } from '@/components/ui/dialog';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@ -59,16 +59,12 @@ const EditDialog = () => {
|
||||
if (response?.status) {
|
||||
toast.success('Feedback reviewed successfully');
|
||||
|
||||
// Close the edit dialog
|
||||
handleEditDialog(false, null);
|
||||
|
||||
// First close the detail dialog to reset its state
|
||||
handleDetailDialog(false, null);
|
||||
|
||||
// Refresh the main data grid first
|
||||
refreshData();
|
||||
|
||||
// Wait a tiny bit then reopen the detail with refreshed data
|
||||
setTimeout(() => {
|
||||
handleDetailDialog(true, selectedFeedback);
|
||||
}, 300);
|
||||
@ -97,7 +93,6 @@ const EditDialog = () => {
|
||||
}
|
||||
|
||||
const data = response.data;
|
||||
// console.log('Fetched data:', data);
|
||||
|
||||
setReviewNotes(data.review_notes || '');
|
||||
|
||||
@ -112,7 +107,11 @@ const EditDialog = () => {
|
||||
|
||||
return (
|
||||
<Dialog open={showEditDialog} onOpenChange={(open) => handleEditDialog(open, null)}>
|
||||
<DialogContent className="p-0 w-full sm:max-w-2xl bg-white rounded-lg overflow-hidden">
|
||||
<DialogContent className="p-0 w-full sm:max-w-2xl bg-white rounded-lg overflow-hidden [&>button]:hidden">
|
||||
<DialogHeader>
|
||||
<DialogTitle></DialogTitle>
|
||||
<DialogDescription></DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="relative">
|
||||
<div className="p-6 flex items-center justify-between border-b">
|
||||
<div>
|
||||
|
||||
@ -10,8 +10,10 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle
|
||||
} from '@/components/ui/dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
const API_URL = apiConfig.transaction;
|
||||
const API_URL_CURRENT_BALANCE = apiConfig.service_wallet;
|
||||
|
||||
const DetailApprovalTransaction = () => {
|
||||
const { GetData } = useCallApi();
|
||||
@ -51,6 +53,60 @@ const DetailApprovalTransaction = () => {
|
||||
}
|
||||
}, [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}>
|
||||
@ -471,7 +527,27 @@ const DetailApprovalTransaction = () => {
|
||||
<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>
|
||||
)}
|
||||
|
||||
@ -482,16 +558,42 @@ const DetailApprovalTransaction = () => {
|
||||
{!transactionDetails?.transfer ? (
|
||||
<div className="text-center 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 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>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">Description</p>
|
||||
<p className="font-medium">{transactionDetails.transfer.destination_wallet.description}</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>
|
||||
)}
|
||||
@ -540,8 +642,8 @@ const DetailApprovalTransaction = () => {
|
||||
})
|
||||
: ''}</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>
|
||||
<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>
|
||||
))
|
||||
) : (
|
||||
|
||||
@ -13,11 +13,15 @@ import {
|
||||
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,
|
||||
@ -45,7 +49,7 @@ const DetailTransaction = () => {
|
||||
id: selectedTransactionId
|
||||
});
|
||||
setTransactionDetails(response?.data);
|
||||
// console.log(response?.data);
|
||||
// console.log(response?.data.origin_customer.id);
|
||||
// console.log(selectedTransactionId);
|
||||
} catch (error) {
|
||||
console.error('Error fetching transaction', error);
|
||||
@ -67,6 +71,61 @@ const DetailTransaction = () => {
|
||||
}
|
||||
}, [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}>
|
||||
@ -231,16 +290,6 @@ const DetailTransaction = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="font-semibold flex items-center">
|
||||
Origin Wallet
|
||||
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
|
||||
Wallet
|
||||
</span>
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
|
||||
</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">
|
||||
@ -482,7 +531,27 @@ const DetailTransaction = () => {
|
||||
<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>
|
||||
)}
|
||||
|
||||
@ -493,16 +562,43 @@ const DetailTransaction = () => {
|
||||
{!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 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>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">Description</p>
|
||||
<p className="font-medium">{transactionDetails.transfer.destination_wallet.description}</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>
|
||||
)}
|
||||
|
||||
@ -23,6 +23,29 @@ interface TransferType {
|
||||
|
||||
const API_URL = apiConfig.service_transaction;
|
||||
|
||||
const typeLabelMap: Record<string, string> = {
|
||||
D: 'Disbursement',
|
||||
O: 'Other',
|
||||
CA: 'Change Group Emoney Customer to Agent',
|
||||
AC: 'Change Group Emoney Agent to Customer',
|
||||
PC: 'Change Group Point Agent to Customer',
|
||||
PA: 'Change Group Point Customer to Agent',
|
||||
CE: 'Return Customer Emoney',
|
||||
AD: 'Return Agent Deposit',
|
||||
AM: 'Return Agent Merchant',
|
||||
AE: 'Return Agent Emoney',
|
||||
R: 'Reward Point',
|
||||
TE: 'Top Up Escrow',
|
||||
TM: 'Top Up Master Agent',
|
||||
TA: 'Top Up Agent',
|
||||
PL: 'Purchase Loja',
|
||||
DE: 'Disbursment Escrow',
|
||||
DM: 'Disbursment Master Agent',
|
||||
DA: 'Disbursment Agent',
|
||||
WI: 'Withdraw Merchant',
|
||||
IC: 'Income Merchant'
|
||||
};
|
||||
|
||||
const ListToolbar = () => {
|
||||
const { table, reload } = useDataGrid();
|
||||
const { handleAddDialog } = useManageTransferTypeContext();
|
||||
@ -31,40 +54,10 @@ const ListToolbar = () => {
|
||||
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [statusTypes, setStatusTypes] = useState('');
|
||||
const [walletOrigins, setWalletOrigin] = useState('');
|
||||
const [walletDestinations, setWalletDestination] = useState('');
|
||||
const [approval, setApproval] = useState('');
|
||||
|
||||
const unique = (arr: string[]) => Array.from(new Set(arr));
|
||||
const types = unique(transferTypes.map((t) => t.type));
|
||||
const origins = unique(transferTypes.map((t) => t.wallet_origin.name));
|
||||
const destinations = unique(transferTypes.map((t) => t.wallet_destination.name));
|
||||
const typeLabelMap: Record<string, string> = {
|
||||
D: 'Disbursement',
|
||||
O: 'Other',
|
||||
CA: 'Change Group Emoney Customer to Agent',
|
||||
AC: 'Change Group Emoney Agent to Customer',
|
||||
PC: 'Change Group Point Agent to Customer',
|
||||
PA: 'Change Group Point Customer to Agent',
|
||||
CE: 'Return Customer Emoney',
|
||||
AD: 'Return Agent Deposit',
|
||||
AM: 'Return Agent Merchant',
|
||||
AE: 'Return Agent Emoney',
|
||||
R: 'Reward Point',
|
||||
TE: 'Top Up Escrow',
|
||||
TM: 'Top Up Master Agent',
|
||||
TA: 'Top Up Agent',
|
||||
PL: 'Purchase Loja',
|
||||
DE: 'Disbursment Escrow',
|
||||
DM: 'Disbursment Master Agent',
|
||||
DA: 'Disbursment Agent',
|
||||
WI: 'Withdraw Merchant',
|
||||
IC: 'Income Merchant'
|
||||
};
|
||||
const approvalLabelMap: Record<string, string> = {
|
||||
Y: 'Yes',
|
||||
N: 'No'
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
@ -78,18 +71,6 @@ const ListToolbar = () => {
|
||||
table.getColumn('type')?.setFilterValue(statusTypes);
|
||||
}, [statusTypes]);
|
||||
|
||||
useEffect(() => {
|
||||
table
|
||||
.getColumn('wallet_origin')
|
||||
?.setFilterValue(walletOrigins === '__all__' ? '' : walletOrigins);
|
||||
}, [walletOrigins]);
|
||||
|
||||
useEffect(() => {
|
||||
table
|
||||
.getColumn('wallet_destination')
|
||||
?.setFilterValue(walletDestinations === '__all__' ? '' : walletDestinations);
|
||||
}, [walletDestinations]);
|
||||
|
||||
useEffect(() => {
|
||||
table.getColumn('status_approval')?.setFilterValue(approval);
|
||||
}, [approval]);
|
||||
@ -115,62 +96,86 @@ const ListToolbar = () => {
|
||||
|
||||
const handleClearFilter = () => {
|
||||
setSearchValue('');
|
||||
setStatusTypes('__all__');
|
||||
setWalletOrigin('__all__');
|
||||
setWalletDestination('__all__');
|
||||
setApproval('__all__');
|
||||
setStatusTypes('');
|
||||
setApproval('');
|
||||
|
||||
table.getColumn('name')?.setFilterValue('');
|
||||
table.getColumn('type')?.setFilterValue('');
|
||||
table.getColumn('wallet_origin')?.setFilterValue('');
|
||||
table.getColumn('wallet_destination')?.setFilterValue('');
|
||||
table.getColumn('status_approval')?.setFilterValue('');
|
||||
table.setPageIndex(0);
|
||||
|
||||
setTimeout(() => {
|
||||
table.setPageIndex(0);
|
||||
reload();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const renderSelect = (
|
||||
placeholder: string,
|
||||
value: string,
|
||||
onChange: (val: string) => void,
|
||||
options: string[],
|
||||
labelMap?: Record<string, string>
|
||||
) => (
|
||||
<div className="min-w-[220px]">
|
||||
<Select value={value === '' ? undefined : value} onValueChange={onChange}>
|
||||
<SelectTrigger className="h-8 text-sm">
|
||||
<SelectValue placeholder={placeholder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{options.map((opt) => (
|
||||
<SelectItem key={opt} value={opt}>
|
||||
{labelMap?.[opt] ?? opt}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<div className="card-header flex-wrap gap-2 border-b-0 px-5">
|
||||
<div className="flex flex-wrap gap-2 lg:gap-5 w-full">
|
||||
<div className="card-header flex-wrap border-b-0 px-5">
|
||||
<div className="flex flex-wrap gap-1 w-full">
|
||||
<div className="flex justify-between w-full items-center mb-3">
|
||||
<div className="flex w-[34%] gap-2 items-center">
|
||||
<label className="input input-sm w-full text-sm">
|
||||
<KeenIcon icon="magnifier" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search Transaction Type Name"
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<div className="flex flex-nowrap items-end gap-3 w-full overflow-x-auto">
|
||||
<div className="w-48 shrink-0">
|
||||
<label className="input input-sm w-full text-sm">
|
||||
<KeenIcon icon="magnifier" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search Name"
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="min-w-[220px] shrink-0">
|
||||
<Select
|
||||
key={`type-filter-${statusTypes}`}
|
||||
value={statusTypes}
|
||||
onValueChange={setStatusTypes}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-sm">
|
||||
<SelectValue placeholder="Select Status Transaction Type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-64 overflow-y-auto">
|
||||
{types.map((opt) => (
|
||||
<SelectItem key={opt} value={opt} className="truncate">
|
||||
{typeLabelMap[opt] ?? opt}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="min-w-[220px] shrink-0">
|
||||
<Select
|
||||
key={`approval-filter-${approval}`}
|
||||
value={approval}
|
||||
onValueChange={setApproval}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-sm">
|
||||
<SelectValue placeholder="Select Status Approval" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-64 overflow-y-auto">
|
||||
<SelectItem value="Y" className="truncate">
|
||||
Yes
|
||||
</SelectItem>
|
||||
<SelectItem value="N" className="truncate">
|
||||
No
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<DefaultTooltip title={'Reset Filter'} placement={'top'}>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-7.5 disabled:bg-gray-400"
|
||||
onClick={handleClearFilter}
|
||||
>
|
||||
<KeenIcon icon="arrow-circle-left" />
|
||||
</Button>
|
||||
</DefaultTooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 items-center">
|
||||
<Button variant="outline" className="h-8 px-3 text-xs" onClick={handleClearFilter}>
|
||||
Clear
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-8 px-3 text-xs"
|
||||
@ -186,33 +191,6 @@ const ListToolbar = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Filter bar */}
|
||||
<div className="flex flex-wrap gap-2 w-full">
|
||||
{renderSelect(
|
||||
'Select Status Transaction Type',
|
||||
statusTypes,
|
||||
setStatusTypes,
|
||||
types,
|
||||
typeLabelMap
|
||||
)}
|
||||
{renderSelect(
|
||||
'Select Status Approval',
|
||||
approval,
|
||||
setApproval,
|
||||
['Y', 'N'],
|
||||
approvalLabelMap
|
||||
)}
|
||||
{/* {renderSelect('Select Origin Wallet', walletOrigins, setWalletOrigin, origins)}
|
||||
{renderSelect(
|
||||
'Select Destination Wallet',
|
||||
walletDestinations,
|
||||
setWalletDestination,
|
||||
destinations
|
||||
)} */}
|
||||
|
||||
{/* {renderSelect('Origin', walletOrigins, setWalletOrigin, origins)}
|
||||
{renderSelect('Destination', walletDestinations, setWalletDestination, destinations)} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -19,6 +19,13 @@ interface WalletProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
const getOneMonthsAgo = () => {
|
||||
const today = new Date();
|
||||
return new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
||||
};
|
||||
|
||||
const formatDate = (date: Date): string => date.toISOString().split('T')[0];
|
||||
|
||||
const ListToolbar = () => {
|
||||
const { table, reload } = useDataGrid();
|
||||
const { GetData } = useCallApi();
|
||||
@ -32,12 +39,10 @@ const ListToolbar = () => {
|
||||
);
|
||||
const [wallets, setWallets] = useState<WalletProps[]>([]);
|
||||
|
||||
const formatDate = (date: Date): string => date.toISOString().split('T')[0];
|
||||
|
||||
useEffect(() => {
|
||||
const today = new Date();
|
||||
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
|
||||
setDateRange({ from: formatDate(firstDayOfMonth), to: formatDate(today) });
|
||||
const threeMonthsAgo = getOneMonthsAgo();
|
||||
setDateRange({ from: formatDate(threeMonthsAgo), to: formatDate(today) });
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@ -45,7 +50,6 @@ const ListToolbar = () => {
|
||||
table.getColumn('msisdn')?.setFilterValue(searchValue);
|
||||
table.setPageIndex(0);
|
||||
}, 200);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [searchValue, table]);
|
||||
|
||||
@ -89,35 +93,50 @@ const ListToolbar = () => {
|
||||
}, []);
|
||||
|
||||
const handleClearAllFilters = () => {
|
||||
const today = new Date();
|
||||
const oneMonthAgo = getOneMonthsAgo();
|
||||
const resetDateRange = {
|
||||
from: formatDate(oneMonthAgo),
|
||||
to: formatDate(today)
|
||||
};
|
||||
|
||||
setSearchValue('');
|
||||
setWalletId('');
|
||||
setDateRange(resetDateRange);
|
||||
|
||||
table.getColumn('msisdn')?.setFilterValue('');
|
||||
table.getColumn('id_wallet')?.setFilterValue('');
|
||||
table.getColumn('CreatedAt')?.setFilterValue(resetDateRange);
|
||||
|
||||
setTimeout(() => {
|
||||
table.setPageIndex(0);
|
||||
reload();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
|
||||
const handleRefresh = () => {
|
||||
const today = new Date();
|
||||
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
|
||||
setDateRange({
|
||||
from: formatDate(firstDayOfMonth),
|
||||
const threeMonthsAgo = getOneMonthsAgo();
|
||||
const resetDateRange = {
|
||||
from: formatDate(threeMonthsAgo),
|
||||
to: formatDate(today)
|
||||
});
|
||||
};
|
||||
|
||||
table.getAllColumns().forEach((column) => {
|
||||
if (column.id !== 'CreatedAt') {
|
||||
column.setFilterValue(undefined);
|
||||
}
|
||||
});
|
||||
setSearchValue('');
|
||||
setWalletId('');
|
||||
setDateRange(resetDateRange);
|
||||
|
||||
table.setColumnFilters([{ id: 'CreatedAt', value: resetDateRange }]);
|
||||
table.setPageIndex(0);
|
||||
|
||||
table.getColumn('CreatedAt')?.setFilterValue({
|
||||
from: formatDate(firstDayOfMonth),
|
||||
to: formatDate(today)
|
||||
});
|
||||
reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="card-header flex-wrap gap-2 border-b-0 px-5">
|
||||
<div className="flex flex-wrap gap-2 lg:gap-5 w-full">
|
||||
<div className="flex justify-between w-full items-center">
|
||||
<div className="flex gap-3 items-center flex-wrap">
|
||||
<div className="flex flex-wrap items-end gap-3 w-full">
|
||||
<label className="input input-sm w-[160px]">
|
||||
From
|
||||
<input
|
||||
@ -136,7 +155,7 @@ const ListToolbar = () => {
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label className="input input-sm w-1/3">
|
||||
<label className="input input-sm w-[160px]">
|
||||
<KeenIcon icon="magnifier" />
|
||||
<input
|
||||
type="text"
|
||||
@ -146,14 +165,9 @@ const ListToolbar = () => {
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div className="w-[220px]">
|
||||
<Select
|
||||
value={walletId}
|
||||
onValueChange={(value) => {
|
||||
setWalletId(value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<div className="w-[160px]">
|
||||
<Select value={walletId} onValueChange={(value) => setWalletId(value)}>
|
||||
<SelectTrigger className="h-[32px]">
|
||||
<SelectValue placeholder="Select Wallet" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@ -165,25 +179,20 @@ const ListToolbar = () => {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<Button variant="outline" size="sm" onClick={handleClearAllFilters}>
|
||||
Clear Filter
|
||||
</Button>
|
||||
<DefaultTooltip title={'Reset Filter'} placement={'top'}>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-7.5 disabled:bg-gray-400"
|
||||
onClick={handleClearAllFilters}
|
||||
>
|
||||
<KeenIcon icon="arrow-circle-left" />
|
||||
</Button>
|
||||
</DefaultTooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3 items-center">
|
||||
<DefaultTooltip title={'Refresh'} placement={'top'}>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-7.5"
|
||||
onClick={() => {
|
||||
setSearchValue('');
|
||||
setWalletId('');
|
||||
table.setColumnFilters((prev) => prev.filter((f) => f.id === 'CreatedAt'));
|
||||
table.setPageIndex(0);
|
||||
reload();
|
||||
}}
|
||||
>
|
||||
<Button variant="outline" className="h-7.5" onClick={handleRefresh}>
|
||||
<KeenIcon icon="arrows-circle" />
|
||||
</Button>
|
||||
</DefaultTooltip>
|
||||
|
||||
Reference in New Issue
Block a user