import { useCallback, useEffect, useRef, useState } from 'react'; import { NumericFormat } from 'react-number-format'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Dialog, DialogBody, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { useManageTransferFeeContext } from '../hooks/useManageTransferFeeContext'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { apiConfig } from '@/config/api.config'; import { Alert, Container, DataGridInner, KeenIcon, useDataGrid } from '@/components'; import { toast } from 'sonner'; import { useCallApi } from '@/hooks'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { getAuth } from '@/auth'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'; const API_URL = apiConfig.service_transaction; const API_URL_MASTER_DATA = apiConfig.service_master_data; const API_URL_CUSTOMER = apiConfig.service_customer; interface WalletProps { id: string; name: string; } interface CustomerProps { id: string; username: string; msisdn: string; } interface TransactionTypeProps { id: string; name: string; } const EditFeeDialog = () => { const parentRef = useRef(null); const { showEditFeeDialog, handleEditFeeDialog, selectedTransferFee } = useManageTransferFeeContext(); const { reload } = useDataGrid(); const { GetData, PutData } = useCallApi(); const parsedUser = getAuth()?.user; const [wallets, setWallets] = useState([]); const [customers, setCustomers] = useState([]); const [transactionTypes, setTransactionTypes] = useState([]); const [transactionTypeName, setTransactionTypeName] = useState(''); const customersWithNames = customers.map((customer) => ({ id: customer.id, name: customer.username })); const [customerSearchTerm, setCustomerSearchTerm] = useState(''); const [showCustomerSearch, setShowCustomerSearch] = useState(false); const [open, setOpen] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' }); const [isLoadingTransferFee, setIsLoadingTransferFee] = useState(false); const [isLoadingTransactionType, setIsLoadingTransactionType] = useState(false); const [isLoadingWallets, setIsLoadingWallets] = useState(false); const [isLoadingCustomers, setIsLoadingCustomers] = useState(false); const initialState = { name: '', description: '', transaction_type: '', minimum_amount: 0, maximum_amount: 0, period_start: '', period_end: '', deduct_amount: 0, deduct_percentage: 0, status: '', status_include: '', updated_by: '', updated_at: '', deduct_from: '', deduct_origin: '00000000-0000-0000-0000-000000000000', deduct_from_account: '', credit_to: '', credit_destination: '00000000-0000-0000-0000-000000000000', credit_destination_account: '' }; const [formField, setFormField] = useState(initialState); useEffect(() => { const updated_time = new Date(); const formattedTime = updated_time.toISOString().slice(0, 19).replace('T', ' '); if (showEditFeeDialog) { setFormField((prevState) => ({ ...prevState, updated_by: parsedUser?.username, updated_at: formattedTime })); } }, [showEditFeeDialog, parsedUser?.username]); const resetForm = () => { if (selectedTransferFee) { fetchTransactionFee(selectedTransferFee); } else { setFormField(initialState); } }; const doUpdateTransferFee = useCallback( async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); const requiredFields = [ 'name', 'description', 'period_start', 'period_end', 'transaction_type', 'status', 'status_include', 'deduct_from', 'deduct_from_account', 'credit_to', 'credit_destination_account' ]; for (const field of requiredFields) { if (formField[field as keyof typeof formField] === '') { setAlert({ show: true, message: `All required fields must be filled out. Missing: ${field.replace(/_/g, ' ')}` }); setIsSubmitting(false); return; } } if (formField.credit_to === 'I' && !formField.credit_destination) { setAlert({ show: true, message: 'Credit destination is required when Input Customer is selected' }); setIsSubmitting(false); return; } if (formField.deduct_from === 'I' && !formField.deduct_origin) { setAlert({ show: true, message: 'Deduct Origin is required when Input is selected' }); setIsSubmitting(false); return; } setAlert({ show: false, message: '' }); const payload = { ...formField }; if (formField.credit_to !== 'I') { payload.credit_destination = '00000000-0000-0000-0000-000000000000'; } if (formField.deduct_from !== 'I') { payload.deduct_origin = '00000000-0000-0000-0000-000000000000'; } // console.log(payload); try { const response = await PutData( `${API_URL}/transactionfees/update/${selectedTransferFee}`, payload ); if (response?.status) { reload(); handleEditFeeDialog(false, null); toast.success('Successfully updated transfer fee'); const createActivity = { module: 'Manage Transfer Fee', description: `Edit Transfer Fee => ${formField.name}`, action: 'U' }; doSaveLogActivity(createActivity); } else { setAlert({ show: true, message: response?.message || 'Failed to update transfer fee' }); } } catch (error) { console.error('Error updating transfer fee', error); setAlert({ show: true, message: 'An error occurred while updating the transfer fee' }); } finally { setIsSubmitting(false); } }, [formField, selectedTransferFee, handleEditFeeDialog] ); const fetchWallets = useCallback(async () => { setIsLoadingWallets(true); const params = { limit: 100, page: 1, with_deleted: false, order_field: 'Wallets.name', order_direction: 'ASC' }; try { const response = await GetData(`${API_URL_MASTER_DATA}/wallet/list`, params); if (response?.status && response?.data) { setWallets(response.data.list); } else { setWallets([]); } } catch (error) { console.error('Error fetching wallets', error); setWallets([]); } finally { setIsLoadingWallets(false); } }, [GetData]); useEffect(() => { if (!showEditFeeDialog) return; fetchWallets(); }, [showEditFeeDialog, fetchWallets]); useEffect(() => { if (!showEditFeeDialog) return; const getCustomerList = async (sorting: any) => { setIsLoadingCustomers(true); try { sorting = sorting.length === 0 ? [{ id: 'name', desc: false }] : sorting; const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, { limit: 100, page: 1, with_deleted: false, order_field: sorting[0].id, order_direction: sorting[0].desc ? 'DESC' : 'ASC' }); setCustomers(response?.data.list || []); } catch (error) { console.error('Error fetching customers', error); } finally { setIsLoadingCustomers(false); } }; getCustomerList([{ id: 'id', desc: false }]); }, [showEditFeeDialog, GetData]); useEffect(() => { if (!showEditFeeDialog) return; const getTransactionTypeList = async (sorting: any) => { setIsLoadingTransactionType(true); try { sorting = sorting.length === 0 ? [{ id: 'name', desc: false }] : sorting; const response = await GetData(`${API_URL}/transactiontype/list`, { limit: 100, page: 1, with_deleted: false, order_field: sorting[0].id, order_direction: sorting[0].desc ? 'DESC' : 'ASC' }); setTransactionTypes(response?.data.list || []); } catch (error) { console.error('Error fetching transaction types', error); } finally { setIsLoadingTransactionType(false); } }; getTransactionTypeList([{ id: 'id', desc: false }]); }, [showEditFeeDialog, GetData]); const formatDate = (dateString: string) => { if (!dateString || dateString.includes('0001-01-01')) return ''; return dateString.split('T')[0]; }; const fetchTransactionFee = useCallback( async (id: string) => { setIsLoadingTransferFee(true); try { const response = await GetData(`${API_URL}/transactionfees/getdata/${id}`, {}); // console.log(response); if (response?.status) { setFormField({ ...initialState, name: response.data.name || '', description: response.data.description || '', transaction_type: response.data.transaction_type?.id || '', minimum_amount: response.data.minimum_amount || 0, maximum_amount: response.data.maximum_amount || 0, period_start: formatDate(response.data.period_start), period_end: formatDate(response.data.period_end), deduct_amount: response.data.deduct_amount || 0, deduct_percentage: response.data.deduct_percentage || 0, status: response.data.status || '', status_include: response.data.status_include || '', deduct_from: response.data.deduct_from || '', deduct_from_account: response.data.deduct_from_account?.id || '', deduct_origin: response.data.deduct_origin?.id || '00000000-0000-0000-0000-000000000000', credit_to: response.data.credit_to || '', credit_destination: response.data.credit_destination?.id || '00000000-0000-0000-0000-000000000000', credit_destination_account: response.data.credit_destination_account?.id || '', updated_by: parsedUser?.username, updated_at: new Date().toISOString().slice(0, 19).replace('T', ' ') }); if (response.data.transaction_type?.name) { setTransactionTypeName(response.data.transaction_type.name); } } } catch (error) { console.error('Error fetching transaction fee details', error); setAlert({ show: true, message: 'Failed to fetch transaction fee details' }); } finally { setIsLoadingTransferFee(false); } }, [GetData, parsedUser?.username] ); const hasFetchedRef = useRef(false); useEffect(() => { if (selectedTransferFee && showEditFeeDialog && !hasFetchedRef.current) { fetchTransactionFee(selectedTransferFee); hasFetchedRef.current = true; } if (!showEditFeeDialog) { hasFetchedRef.current = false; } }, [selectedTransferFee, showEditFeeDialog, fetchTransactionFee]); const handleCloseDialog = () => { setFormField(initialState); setAlert({ show: false, message: '' }); setCustomerSearchTerm(''); setOpen(false); handleEditFeeDialog(false, null); }; useEffect(() => { if (!showEditFeeDialog) { setCustomerSearchTerm(''); setOpen(false); } }, [showEditFeeDialog]); const renderSelectWithLoading = ( value: string, onChangeHandler: (value: string) => void, options: { id: string; name: string }[] | null, placeholder: string, isLoading: boolean ) => { return ( ); }; return ( { if (!open) { handleCloseDialog(); } }} >

Edit Transfer Fee

{alert.show && (

{alert.message}

)} {isLoadingTransferFee ? (

Loading transfer fee details...

) : (
{isLoadingTransactionType && (
Loading transaction type...
)}
setFormField((prev) => ({ ...prev, name: target.value })) } />
setFormField((prev) => ({ ...prev, description: target.value })) } />
{ setFormField((prev) => ({ ...prev, minimum_amount: values.floatValue || 0 })); }} placeholder="Enter Minimum Amount" />
{ setFormField((prev) => ({ ...prev, maximum_amount: values.floatValue || 0 })); }} placeholder="Enter Maximum Amount" />
setFormField((prev) => ({ ...prev, period_start: target.value })) } />
setFormField((prev) => ({ ...prev, period_end: target.value })) } />
{ setFormField((prev) => ({ ...prev, deduct_amount: values.floatValue || 0 })); }} placeholder="Enter Deduct Amount" />
{ setFormField((prev) => ({ ...prev, deduct_percentage: values.floatValue || 0 })); }} placeholder="Enter Deduct Percentage" />
{formField.deduct_from === 'I' && (
setOpen(!open)} > {customers.find((customer) => customer.id === formField.deduct_origin) ?.username || 'Search customer...'}
{open && (
setCustomerSearchTerm(e.target.value)} autoComplete="off" onClick={(e) => e.stopPropagation()} autoFocus />
{customers .filter( (customer) => customer.username .toLowerCase() .includes(customerSearchTerm.toLowerCase()) || customer.msisdn.includes(customerSearchTerm) ) .map((customer) => (
{ setFormField({ ...formField, deduct_origin: customer.id }); setOpen(false); }} > {customer.username}
))} {customers.filter( (customer) => customer.username .toLowerCase() .includes(customerSearchTerm.toLowerCase()) || customer.msisdn.includes(customerSearchTerm) ).length === 0 && (
No customer found
)}
)}
)}
{renderSelectWithLoading( formField.deduct_from_account, (value) => setFormField({ ...formField, deduct_from_account: value }), wallets, 'Select Wallet', isLoadingWallets )}
{formField.credit_to === 'I' && (
setOpen(!open)} > {customers.find( (customer) => customer.id === formField.credit_destination )?.username || 'Search customer...'}
{open && (
setCustomerSearchTerm(e.target.value)} autoComplete="off" onClick={(e) => e.stopPropagation()} autoFocus />
{customers .filter( (customer) => customer.username .toLowerCase() .includes(customerSearchTerm.toLowerCase()) || customer.msisdn.includes(customerSearchTerm) ) .map((customer) => (
{ setFormField({ ...formField, credit_destination: customer.id }); setOpen(false); }} > {customer.username}
))} {customers.filter( (customer) => customer.username .toLowerCase() .includes(customerSearchTerm.toLowerCase()) || customer.msisdn.includes(customerSearchTerm) ).length === 0 && (
No customer found
)}
)}
)}
{renderSelectWithLoading( formField.credit_destination_account, (value) => setFormField({ ...formField, credit_destination_account: value }), wallets, 'Select Wallet', isLoadingWallets )}
)}
); }; export { EditFeeDialog };