From faf9adbb42dddf3e4f39c1cc55f0fcdbd1077068 Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Thu, 8 May 2025 16:50:47 +0700 Subject: [PATCH 1/4] update manage wallet --- src/pages/master/wallet/blocks/AddDialog.tsx | 150 +++++++++---------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/src/pages/master/wallet/blocks/AddDialog.tsx b/src/pages/master/wallet/blocks/AddDialog.tsx index 90ad6ba..a88bb23 100644 --- a/src/pages/master/wallet/blocks/AddDialog.tsx +++ b/src/pages/master/wallet/blocks/AddDialog.tsx @@ -24,21 +24,7 @@ import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; - -interface CurrencyProps { - ID: string; - code: string; - name: string; - prefix: string; - status: string; -} - -interface GroupProps { - id: string; - name: string; - description: string; - status: string; -} +import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from './Types'; const API_URL_WALLET = apiConfig.service_wallet; const API_URL_MASTER_DATA = apiConfig.service_master_data; @@ -47,31 +33,15 @@ const AddDialog = () => { const { showAddDialog, handleAddDialog, selectedWallet } = useManageWalletContext(); const { GetData, PostData } = useCallApi(); const { reload } = useDataGrid(); - const [alert, setAlert] = useState({ - show: false, - message: '' - }); - const initialState: { - name: string; - description: string; - status: string; - group: string[]; - id_currency: string; - } = { - name: '', - description: '', - status: '', - group: [], - id_currency: '' - }; - const [formField, setFormField] = useState(initialState); + const [errors, setErrors] = useState>({}); + const [formField, setFormField] = useState(initialStateWallet); const [isSubmitting, setIsSubmitting] = useState(false); const [currencies, setCurrencies] = useState([]); const [groups, setGroups] = useState([]); const resetForm = () => { - setFormField(initialState); - setAlert({ show: false, message: '' }); + setFormField(initialStateWallet); + setErrors({}); }; const handleGroupChange = (groupId: string) => { @@ -115,8 +85,7 @@ const AddDialog = () => { doSaveLogActivity(createActivity); } else { - toast.error('Failed Create Wallet'); - setAlert({ show: true, message: response?.message }); + toast.error(response?.message); } } catch (error) { toast.error('Something went wrong, please try again.'); @@ -130,20 +99,11 @@ const AddDialog = () => { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - if ( - formField.name.trim() === '' || - formField.description.trim() === '' || - formField.status.trim() === '' || - formField.group.length === 0 || - formField.id_currency.trim() === '' - ) { - setAlert({ show: true, message: 'Please fill in all required fields.' }); + if (!validateFormsWallet(formField, setErrors)) { return; } - - // console.log(formField); - doCreateWallet(e); - setAlert({ show: false, message: '' }); + console.log(formField); + // doCreateWallet(e); }; const getCurrencyLists = async (sorting: any) => { @@ -155,7 +115,6 @@ const AddDialog = () => { order_field: sorting[0].id, order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - // console.log('Currency: ', response?.data); setCurrencies(response?.data.list); } catch (error) { console.error('Error fetching currency', error); @@ -171,13 +130,17 @@ const AddDialog = () => { order_field: sorting[0].id, order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - // console.log('Group: ', response?.data); setGroups(response?.data.list); } catch (error) { console.error('Error fetching group', error); } }; + const selectedGroups = groups + .filter((g) => formField.group.includes(g.id)) + .map((g) => g.name) + .join(', '); + useEffect(() => { getCurrencyLists([{ id: 'name', desc: false }]); getGroupLists([{ id: 'name', desc: false }]); @@ -198,12 +161,6 @@ const AddDialog = () => {
- {alert.show && ( - -

{alert.message}

-
- )} -
@@ -212,12 +169,17 @@ const AddDialog = () => { Wallet Name* setFormField({ ...formField, name: e.target.value })} + onChange={(e) => { + setFormField({ ...formField, name: e.target.value }); + setErrors({ ...errors, name: '' }); + }} placeholder="Wallet Name" />
+ {errors.name &&
{errors.name}
}
@@ -226,12 +188,19 @@ const AddDialog = () => { Description* setFormField({ ...formField, description: e.target.value })} + onChange={(e) => { + setFormField({ ...formField, description: e.target.value }); + setErrors({ ...errors, description: '' }); + }} placeholder="Description" />
+ {errors.description && ( +
{errors.description}
+ )}
@@ -241,9 +210,12 @@ const AddDialog = () => {
+ {errors.status && ( +
{errors.status}
+ )}
@@ -261,9 +236,12 @@ const AddDialog = () => {
+ {errors.id_currency && ( +
{errors.id_currency}
+ )}
@@ -282,18 +263,37 @@ const AddDialog = () => { -
- {groups.map((group) => ( - - ))} +
+ + {errors.group && ( +
{errors.group}
+ )} + +
+
+ {groups.map((group) => ( +
+ handleGroupChange(group.id)} + /> + +
+ ))} +
+
From ebd5e8b4f9b6476f62a457467b7bc7a09818df65 Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Thu, 8 May 2025 17:10:10 +0700 Subject: [PATCH 2/4] fix alert empty validation on manage wallet module - make 2 mode of validation (create and update) - change input field group --- src/pages/master/wallet/blocks/AddDialog.tsx | 211 ++++++++++-------- src/pages/master/wallet/blocks/EditDialog.tsx | 151 ++++++------- src/pages/master/wallet/blocks/Types.ts | 68 ++++++ .../TransactionDisbursement.tsx | 1 - 4 files changed, 247 insertions(+), 184 deletions(-) create mode 100644 src/pages/master/wallet/blocks/Types.ts diff --git a/src/pages/master/wallet/blocks/AddDialog.tsx b/src/pages/master/wallet/blocks/AddDialog.tsx index a88bb23..99341d0 100644 --- a/src/pages/master/wallet/blocks/AddDialog.tsx +++ b/src/pages/master/wallet/blocks/AddDialog.tsx @@ -46,19 +46,21 @@ const AddDialog = () => { const handleGroupChange = (groupId: string) => { setFormField((prevState) => { - const isSelected = prevState.group.includes(groupId); + const currentGroup = prevState.group ?? []; + + const isSelected = currentGroup.includes(groupId); if (isSelected) { // Remove the group if already selected return { ...prevState, - group: prevState.group.filter((id) => id !== groupId) + group: currentGroup.filter((id) => id !== groupId) }; } else { // Add the group if not selected return { ...prevState, - group: [...prevState.group, groupId] + group: [...currentGroup, groupId] }; } }); @@ -99,11 +101,11 @@ const AddDialog = () => { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - if (!validateFormsWallet(formField, setErrors)) { + if (!validateFormsWallet(formField, setErrors, 'create')) { return; } console.log(formField); - // doCreateWallet(e); + doCreateWallet(e); }; const getCurrencyLists = async (sorting: any) => { @@ -137,7 +139,7 @@ const AddDialog = () => { }; const selectedGroups = groups - .filter((g) => formField.group.includes(g.id)) + .filter((g) => formField.group?.includes(g.id)) .map((g) => g.name) .join(', '); @@ -154,7 +156,7 @@ const AddDialog = () => { return ( handleAddDialog(open)}> - + Wallet - Create @@ -168,18 +170,22 @@ const AddDialog = () => { - { - setFormField({ ...formField, name: e.target.value }); - setErrors({ ...errors, name: '' }); - }} - placeholder="Wallet Name" - /> +
+ { + setFormField({ ...formField, name: e.target.value }); + setErrors({ ...errors, name: '' }); + }} + placeholder="Wallet Name" + /> + {errors.name && ( +
{errors.name}
+ )} +
- {errors.name &&
{errors.name}
}
@@ -187,20 +193,22 @@ const AddDialog = () => { - { - setFormField({ ...formField, description: e.target.value }); - setErrors({ ...errors, description: '' }); - }} - placeholder="Description" - /> +
+ { + setFormField({ ...formField, description: e.target.value }); + setErrors({ ...errors, description: '' }); + }} + placeholder="Description" + /> + {errors.description && ( +
{errors.description}
+ )} +
- {errors.description && ( -
{errors.description}
- )}
@@ -208,25 +216,27 @@ const AddDialog = () => { - +
+ + {errors.status && ( +
{errors.status}
+ )} +
- {errors.status && ( -
{errors.status}
- )}
@@ -234,28 +244,30 @@ const AddDialog = () => { - +
+ + {errors.id_currency && ( +
{errors.id_currency}
+ )} +
- {errors.id_currency && ( -
{errors.id_currency}
- )}
@@ -263,36 +275,37 @@ const AddDialog = () => { -
- - {errors.group && ( -
{errors.group}
- )} - -
-
- {groups.map((group) => ( -
- handleGroupChange(group.id)} - /> - -
- ))} +
+
+ +
+
+ {groups.map((group) => ( +
+ handleGroupChange(group.id)} + /> + +
+ ))} +
+ {errors.group && ( +
{errors.group}
+ )}
diff --git a/src/pages/master/wallet/blocks/EditDialog.tsx b/src/pages/master/wallet/blocks/EditDialog.tsx index f7590ac..f7190b6 100644 --- a/src/pages/master/wallet/blocks/EditDialog.tsx +++ b/src/pages/master/wallet/blocks/EditDialog.tsx @@ -23,21 +23,7 @@ import { import { Button } from '@/components/ui/button'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; - -interface CurrencyProps { - ID: string; - code: string; - name: string; - prefix: string; - status: string; -} - -interface GroupProps { - id: string; - name: string; - description: string; - status: string; -} +import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from './Types'; const API_URL_WALLET = apiConfig.service_wallet; const API_URL_MASTER_DATA = apiConfig.service_master_data; @@ -47,31 +33,15 @@ const EditDialog = () => { const { reload } = useDataGrid(); const { GetData, PutData } = useCallApi(); const [isLoading, setIsLoading] = useState(false); - const [alert, setAlert] = useState({ - show: false, - message: '' - }); - const initialState: { - name: string; - description: string; - status: string; - currency_id: string; - group: string[]; - } = { - name: '', - description: '', - status: '', - currency_id: '', - group: [] - }; - const [formField, setFormField] = useState(initialState); + const [errors, setErrors] = useState>({}); + const [formField, setFormField] = useState(initialStateWallet); const [currencies, setCurrencies] = useState([]); const [groups, setGroups] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const resetForm = () => { - setFormField(initialState); - setAlert({ show: false, message: '' }); + setFormField(initialStateWallet); + setErrors({}); }; const doUpdateWallet = useCallback( @@ -98,8 +68,7 @@ const EditDialog = () => { doSaveLogActivity(createActivity); } else { - toast.error('Failed Update Wallet'); - setAlert({ show: true, message: response?.message }); + toast.error(response?.message); } } catch (error) { toast.error('Something went wrong, please try again.'); @@ -119,9 +88,11 @@ const EditDialog = () => { description: formField.description, status: formField.status }; - // console.log(payload); + + if (!validateFormsWallet(payload, setErrors, 'update')) { + return; + } doUpdateWallet(payload); - setAlert({ show: false, message: '' }); }; const doFetchData = useCallback(async (id: string) => { @@ -179,10 +150,10 @@ const EditDialog = () => { } }; - const selectedCurrency = currencies.find((currency) => currency.ID === formField.currency_id); + const selectedCurrency = currencies.find((currency) => currency.ID === formField.id_currency); const selectedGroupNames = groups - .filter((g) => formField.group.includes(g.id)) + .filter((g) => formField.group?.includes(g.id)) .map((g) => g.name) .join(', '); @@ -193,14 +164,6 @@ const EditDialog = () => { useEffect(() => { if (selectedWallet) { - // setFormField((prev) => ({ - // ...prev, - // name: selectedWallet?.Wallet_name, - // description: selectedWallet?.Wallet_description, - // status: selectedWallet?.Wallet_status, - // currency_id: selectedWallet?.Wallet_currency_id, - // group: selectedWallet?.Wallet_group - // })); doFetchData(selectedWallet?.id); } }, [selectedWallet]); @@ -220,12 +183,6 @@ const EditDialog = () => {
- {alert.show && ( - -

{alert.message}

-
- )} - {isLoading ? (
@@ -245,48 +202,74 @@ const EditDialog = () => {
- setFormField({ ...formField, name: e.target.value })} - placeholder="Wallet Name" - /> +
+ { + setFormField({ ...formField, name: e.target.value }); + setErrors({ ...errors, name: '' }); + }} + placeholder="Wallet Name" + /> + {errors.name && ( +
{errors.name}
+ )} +
- - setFormField({ ...formField, description: e.target.value }) - } - placeholder="Description" - /> +
+ { + setFormField({ ...formField, description: e.target.value }); + setErrors({ ...errors, description: '' }); + }} + placeholder="Description" + /> + {errors.description && ( +
{errors.description}
+ )} +
- - + +
+ + {errors.status && ( +
{errors.status}
+ )} +
diff --git a/src/pages/master/wallet/blocks/Types.ts b/src/pages/master/wallet/blocks/Types.ts new file mode 100644 index 0000000..58db1ed --- /dev/null +++ b/src/pages/master/wallet/blocks/Types.ts @@ -0,0 +1,68 @@ +import React from 'react'; +import { toast } from 'sonner'; + +export interface CurrencyProps { + ID: string; + code: string; + name: string; + prefix: string; + status: string; +} + +export interface GroupProps { + id: string; + name: string; + description: string; + status: string; +} + +export const initialStateWallet: { + name: string; + description: string; + status: string; + group?: string[]; + id_currency?: string; +} = { + name: '', + description: '', + status: '', + group: [], + id_currency: '' +}; + +export const validateFormsWallet = ( + formField: typeof initialStateWallet, + setErrors: React.Dispatch>>, + mode: 'create' | 'update' = 'create' // default: create +) => { + const requiredFields = + mode === 'create' + ? [ + { key: 'name', label: 'Name' }, + { key: 'description', label: 'Description' }, + { key: 'status', label: 'Status' }, + { key: 'group', label: 'Group' }, + { key: 'id_currency', label: 'Currency' } + ] + : [ + { key: 'name', label: 'Name' }, + { key: 'description', label: 'Description' }, + { key: 'status', label: 'Status' } + ]; + + const newErrors: Record = {}; + let isValid = true; + + requiredFields.forEach(({ key, label }) => { + const value = formField[key as keyof typeof formField]; + + if (value === '' || value === null || value === undefined) { + newErrors[key] = `${label} is required`; + toast.error(`${label} is required`); + isValid = false; + } + }); + + setErrors(newErrors); + return isValid; +}; diff --git a/src/pages/transaction/disbursement-saldo/TransactionDisbursement.tsx b/src/pages/transaction/disbursement-saldo/TransactionDisbursement.tsx index 34d28da..b023836 100644 --- a/src/pages/transaction/disbursement-saldo/TransactionDisbursement.tsx +++ b/src/pages/transaction/disbursement-saldo/TransactionDisbursement.tsx @@ -137,7 +137,6 @@ const TransactionDisbursement = () => { }); return; } - console.log(form); setAlert({ show: false, message: '' }); setShowConfirmation(true); }; From 48c37b38791ee97c227a12639e694ca547776e60 Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Thu, 8 May 2025 18:13:59 +0700 Subject: [PATCH 3/4] fix import and type of wallet --- src/pages/master/wallet/{blocks => }/Types.ts | 16 ++++++++++++++++ src/pages/master/wallet/blocks/AddDialog.tsx | 2 +- src/pages/master/wallet/blocks/EditDialog.tsx | 2 +- .../master/wallet/hooks/ManageWalletContext.tsx | 15 +++++---------- 4 files changed, 23 insertions(+), 12 deletions(-) rename src/pages/master/wallet/{blocks => }/Types.ts (85%) diff --git a/src/pages/master/wallet/blocks/Types.ts b/src/pages/master/wallet/Types.ts similarity index 85% rename from src/pages/master/wallet/blocks/Types.ts rename to src/pages/master/wallet/Types.ts index 58db1ed..ac4b94f 100644 --- a/src/pages/master/wallet/blocks/Types.ts +++ b/src/pages/master/wallet/Types.ts @@ -1,6 +1,22 @@ import React from 'react'; import { toast } from 'sonner'; +export interface WalletProps { + id: string; + name: string; + description: string; + id_currency: string; + status: string; + group: WalletGroupProps[]; +} + +export interface WalletGroupProps { + id: string; + name: string; + description: string; + status: string; +} + export interface CurrencyProps { ID: string; code: string; diff --git a/src/pages/master/wallet/blocks/AddDialog.tsx b/src/pages/master/wallet/blocks/AddDialog.tsx index 99341d0..a753b93 100644 --- a/src/pages/master/wallet/blocks/AddDialog.tsx +++ b/src/pages/master/wallet/blocks/AddDialog.tsx @@ -24,7 +24,7 @@ import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; -import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from './Types'; +import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from '../Types'; const API_URL_WALLET = apiConfig.service_wallet; const API_URL_MASTER_DATA = apiConfig.service_master_data; diff --git a/src/pages/master/wallet/blocks/EditDialog.tsx b/src/pages/master/wallet/blocks/EditDialog.tsx index f7190b6..6ba3033 100644 --- a/src/pages/master/wallet/blocks/EditDialog.tsx +++ b/src/pages/master/wallet/blocks/EditDialog.tsx @@ -23,7 +23,7 @@ import { import { Button } from '@/components/ui/button'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; -import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from './Types'; +import { CurrencyProps, GroupProps, initialStateWallet, validateFormsWallet } from '../Types'; const API_URL_WALLET = apiConfig.service_wallet; const API_URL_MASTER_DATA = apiConfig.service_master_data; diff --git a/src/pages/master/wallet/hooks/ManageWalletContext.tsx b/src/pages/master/wallet/hooks/ManageWalletContext.tsx index 15e8469..3bee0ba 100644 --- a/src/pages/master/wallet/hooks/ManageWalletContext.tsx +++ b/src/pages/master/wallet/hooks/ManageWalletContext.tsx @@ -5,15 +5,7 @@ import { ColumnDef } from '@tanstack/react-table'; import React, { createContext, useCallback, useMemo, useState } from 'react'; import { Toaster } from 'sonner'; import ListToolbar from '../blocks/ListToolbar'; - -interface WalletProps { - id: string; - name: string; - status: string; - description: string; - group: string[]; - currency_id: string; -} +import { WalletProps } from '../Types'; interface ContextProps { wallet: WalletProps[]; @@ -146,7 +138,10 @@ const ManageWalletContextProvider = ({ children }: { children: React.ReactNode } const getWalletLists = async (page: number, limit: number, sorting: any, filter: any) => { try { sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; - filter = filter.length == 0 ? {} : { 'wallets.name': { like: `%${filter[0].value?.toLowerCase()}%` } }; + filter = + filter.length == 0 + ? {} + : { 'wallets.name': { like: `%${filter[0].value?.toLowerCase()}%` } }; const response = await GetData(`${API_URL_MASTER_DATA}/wallet/list`, { limit, From c91f59b8c2640af322a42e16d17173897da554ee Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Thu, 8 May 2025 18:14:14 +0700 Subject: [PATCH 4/4] fix alert empty validation on manage wallet rule --- src/pages/master/walletRule/Types.ts | 81 ++++ .../master/walletRule/blocks/AddDialog.tsx | 376 +++++++++--------- .../master/walletRule/blocks/EditDialog.tsx | 63 +-- .../hooks/ManageWalletRuleContext.tsx | 13 +- 4 files changed, 274 insertions(+), 259 deletions(-) create mode 100644 src/pages/master/walletRule/Types.ts diff --git a/src/pages/master/walletRule/Types.ts b/src/pages/master/walletRule/Types.ts new file mode 100644 index 0000000..bfb60ec --- /dev/null +++ b/src/pages/master/walletRule/Types.ts @@ -0,0 +1,81 @@ +import { toast } from 'sonner'; + +export interface WalletRuleProps { + ID: string; + id_wallet: string; + id_group: string; + max_transaction_per_day: number | null; + balance_minimum: number | null; + balance_maximum: number | null; + credit_limit: number | null; + monthly_limit: number | null; + status: string; +} + +export const initialStateWalletRule: { + id_wallet: string; + id_group: string; + max_transaction_per_day: string | number | null; + balance_minimum: string | number | null; + balance_maximum: string | number | null; + credit_limit: string | number | null; + monthly_limit: string | number | null; + status: string; +} = { + id_wallet: '', + id_group: '', + max_transaction_per_day: null, + balance_minimum: null, + balance_maximum: null, + credit_limit: null, + monthly_limit: null, + status: '' +}; + +export interface GroupProps { + ID: string; + is_bank: string; + name: string; + status: string; +} + +export interface WalletProps { + ID: string; + name: string; + id_currency: string; + status: string; +} + +export const validateFormsWalletRule = ( + formField: typeof initialStateWalletRule, + setErrors: React.Dispatch>> +) => { + const requiredFields = [ + { key: 'id_wallet', label: 'Wallet' }, + { key: 'id_group', label: 'Group' }, + { key: 'max_transaction_per_day', label: 'Max Transaction Per Day' }, + { key: 'balance_minimum', label: 'Balance Minimum' }, + { key: 'balance_maximum', label: 'Balance Maximum' }, + { key: 'credit_limit', label: 'Credit Limit' }, + { key: 'monthly_limit', label: 'Monthly Limit' }, + { key: 'status', label: 'Status' } + ]; + + const newErrors: Record = {}; + let isValid = true; + + requiredFields.forEach(({ key, label }) => { + if ( + formField[key as keyof typeof formField] === '' || + formField[key as keyof typeof formField] === null || + formField[key as keyof typeof formField] === undefined + ) { + newErrors[key] = `${label} is required`; + toast.error(`${label} is required`); + isValid = false; + } + }); + + setErrors(newErrors); + return isValid; +}; diff --git a/src/pages/master/walletRule/blocks/AddDialog.tsx b/src/pages/master/walletRule/blocks/AddDialog.tsx index 48cfc40..c9e4d72 100644 --- a/src/pages/master/walletRule/blocks/AddDialog.tsx +++ b/src/pages/master/walletRule/blocks/AddDialog.tsx @@ -33,28 +33,8 @@ import { import { NumericFormat } from 'react-number-format'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; - -interface GroupProps { - ID: string; - is_bank: string; - name: string; - status: string; -} - -interface WalletGroupProps { - id: string; - name: string; - description: string; - status: string; -} - -interface WalletProps { - id: string; - name: string; - id_currency: string; - status: string; - group: WalletGroupProps[]; -} +import { initialStateWalletRule, validateFormsWalletRule } from '../Types'; +import { WalletProps } from '../../wallet/Types'; const API_URL_WALLET = apiConfig.service_wallet; const API_URL_MASTERDATA = apiConfig.service_master_data; @@ -63,37 +43,14 @@ const AddDialog = () => { const { showAddDialog, handleAddDialog, selectedWalletRule } = useManageWalletRuleContext(); const { reload } = useDataGrid(); const { PostData, GetData } = useCallApi(); - const [open, setOpen] = useState(false); - const [alert, setAlert] = useState({ - show: false, - message: '' - }); - const initialState: { - id_wallet: string; - id_group: string; - max_transaction_per_day: string | number | null; - balance_minimum: string | number | null; - balance_maximum: string | number | null; - credit_limit: string | number | null; - monthly_limit: string | number | null; - status: string; - } = { - id_wallet: '', - id_group: '', - max_transaction_per_day: null, - balance_minimum: null, - balance_maximum: null, - credit_limit: null, - monthly_limit: null, - status: '' - }; - const [formField, setFormField] = useState(initialState); + const [errors, setErrors] = useState>({}); + const [formField, setFormField] = useState(initialStateWalletRule); const [wallets, setWallets] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const resetForm = () => { - setFormField(initialState); - setAlert({ show: false, message: '' }); + setFormField(initialStateWalletRule); + setErrors({}); }; const doCreateWalletRule = useCallback( @@ -117,8 +74,7 @@ const AddDialog = () => { doSaveLogActivity(createActivity); } else { - toast.error('Failed Create Wallet Rule'); - setAlert({ show: true, message: response?.message }); + toast.error(response?.message); } } catch (error) { toast.error('Something went wrong, please try again.'); @@ -132,23 +88,11 @@ const AddDialog = () => { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - if ( - formField.id_group.trim() === '' || - formField.status.trim() === '' || - formField.id_wallet.trim() === '' || - formField.max_transaction_per_day === null || - formField.balance_minimum === null || - formField.balance_maximum === null || - formField.credit_limit === null || - formField.monthly_limit === null - ) { - setAlert({ show: true, message: 'Please fill in all required fields.' }); + if (!validateFormsWalletRule(formField, setErrors)) { return; } - console.log(formField); doCreateWalletRule(e); - setAlert({ show: false, message: '' }); }; const getWalletLists = async (sorting: any) => { @@ -160,8 +104,6 @@ const AddDialog = () => { order_field: sorting[0].id, order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - - // console.log('WALLET: ', response?.data); setWallets(response?.data.list); } catch (error) { console.error('Error fetching wallet', error); @@ -190,12 +132,6 @@ const AddDialog = () => {
- {alert.show && ( - -

{alert.message}

-
- )} -
@@ -203,23 +139,29 @@ const AddDialog = () => { - +
+ + {errors.id_wallet && ( +
{errors.id_wallet}
+ )} +
@@ -228,26 +170,34 @@ const AddDialog = () => { - +
+ + {errors.id_group && ( +
{errors.id_group}
+ )} +
@@ -256,21 +206,29 @@ const AddDialog = () => { - { - setFormField((prev) => ({ - ...prev, - max_transaction_per_day: - values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Max Transaction Per Day" - /> +
+ { + setFormField((prev) => ({ + ...prev, + max_transaction_per_day: + values.floatValue !== undefined ? values.floatValue : '' + })); + setErrors({ ...errors, max_transaction_per_day: '' }); + }} + placeholder="Enter Max Transaction Per Day" + /> + {errors.max_transaction_per_day && ( +
+ {errors.max_transaction_per_day} +
+ )} +
@@ -279,20 +237,27 @@ const AddDialog = () => { - { - setFormField((prev) => ({ - ...prev, - balance_minimum: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Balance Minimum" - /> +
+ { + setFormField((prev) => ({ + ...prev, + balance_minimum: + values.floatValue !== undefined ? values.floatValue : '' + })); + setErrors({ ...errors, balance_minimum: '' }); + }} + placeholder="Enter Balance Minimum" + /> + {errors.balance_minimum && ( +
{errors.balance_minimum}
+ )} +
@@ -301,20 +266,27 @@ const AddDialog = () => { - { - setFormField((prev) => ({ - ...prev, - balance_maximum: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Balance Maximum" - /> +
+ { + setFormField((prev) => ({ + ...prev, + balance_maximum: + values.floatValue !== undefined ? values.floatValue : '' + })); + setErrors({ ...errors, balance_maximum: '' }); + }} + placeholder="Enter Balance Maximum" + /> + {errors.balance_maximum && ( +
{errors.balance_maximum}
+ )} +
@@ -323,20 +295,26 @@ const AddDialog = () => { - { - setFormField((prev) => ({ - ...prev, - credit_limit: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Credit Limit" - /> +
+ { + setFormField((prev) => ({ + ...prev, + credit_limit: values.floatValue !== undefined ? values.floatValue : '' + })); + setErrors({ ...errors, credit_limit: '' }); + }} + placeholder="Enter Credit Limit" + /> + {errors.credit_limit && ( +
{errors.credit_limit}
+ )} +
@@ -345,20 +323,26 @@ const AddDialog = () => { - { - setFormField((prev) => ({ - ...prev, - monthly_limit: values.floatValue !== undefined ? values.floatValue : '' - })); - }} - placeholder="Enter Monthly Limit" - /> +
+ { + setFormField((prev) => ({ + ...prev, + monthly_limit: values.floatValue !== undefined ? values.floatValue : '' + })); + setErrors({ ...errors, monthly_limit: '' }); + }} + placeholder="Enter Monthly Limit" + /> + {errors.monthly_limit && ( +
{errors.monthly_limit}
+ )} +
@@ -367,18 +351,26 @@ const AddDialog = () => { - +
+ + {errors.status && ( +
{errors.status}
+ )} +
diff --git a/src/pages/master/walletRule/blocks/EditDialog.tsx b/src/pages/master/walletRule/blocks/EditDialog.tsx index 166225b..02a33f3 100644 --- a/src/pages/master/walletRule/blocks/EditDialog.tsx +++ b/src/pages/master/walletRule/blocks/EditDialog.tsx @@ -33,20 +33,7 @@ import { Button } from '@/components/ui/button'; import { NumericFormat } from 'react-number-format'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { RefreshCw } from 'lucide-react'; - -interface GroupProps { - ID: string; - is_bank: string; - name: string; - status: string; -} - -interface WalletProps { - ID: string; - name: string; - id_currency: string; - status: string; -} +import { GroupProps, initialStateWalletRule, validateFormsWalletRule, WalletProps } from '../Types'; const API_URL_WALLET = apiConfig.service_wallet; @@ -54,37 +41,15 @@ const EditDialog = () => { const { showEditDialog, handleEditDialog, selectedWalletRule } = useManageWalletRuleContext(); const { GetData, PutData } = useCallApi(); const { reload } = useDataGrid(); - const [alert, setAlert] = useState({ - show: false, - message: '' - }); - const initialState: { - id_wallet: string; - id_group: string; - max_transaction_per_day: string | number | null; - balance_minimum: string | number | null; - balance_maximum: string | number | null; - credit_limit: string | number | null; - monthly_limit: string | number | null; - status: string; - } = { - id_wallet: '', - id_group: '', - max_transaction_per_day: null, - balance_minimum: null, - balance_maximum: null, - credit_limit: null, - monthly_limit: null, - status: '' - }; - const [formField, setFormField] = useState(initialState); + const [errors, setErrors] = useState>({}); + const [formField, setFormField] = useState(initialStateWalletRule); const [groups, setGroups] = useState([]); const [wallets, setWallets] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const resetForm = () => { - setFormField(initialState); - setAlert({ show: false, message: '' }); + setFormField(initialStateWalletRule); + setErrors({}); }; const doUpdateWalletRule = useCallback( @@ -111,8 +76,7 @@ const EditDialog = () => { doSaveLogActivity(createActivity); } else { - toast.error('Failed Update Wallet Rule'); - setAlert({ show: true, message: response?.message }); + toast.error(response?.message); } } catch (error) { toast.error('Something went wrong, please try again'); @@ -126,14 +90,11 @@ const EditDialog = () => { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - if (formField.id_group.trim() === '' || formField.status.trim() === '') { - setAlert({ show: true, message: 'Please fill in all required fields.' }); + if (!validateFormsWalletRule(formField, setErrors)) { return; } - // console.log(formField); doUpdateWalletRule(e); - setAlert({ show: false, message: '' }); }; const getGroupLists = async (sorting: any) => { @@ -146,7 +107,6 @@ const EditDialog = () => { order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - // console.log('GROUPS: ', response?.data); setGroups(response?.data.list); } catch (error) { console.error('Error fetching groups', error); @@ -163,7 +123,6 @@ const EditDialog = () => { order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' }); - // console.log('WALLET: ', response?.data); setWallets(response?.data.list); } catch (error) { console.error('Error fetching wallet', error); @@ -215,7 +174,7 @@ const EditDialog = () => { })); } }, [selectedWalletRule]); - // console.log(selectedWalletRule); + return ( handleEditDialog(open, null)}> @@ -225,12 +184,6 @@ const EditDialog = () => {
- {alert.show && ( - -

{alert.message}

-
- )} -
diff --git a/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx b/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx index 7f3d6b4..4ac8e3f 100644 --- a/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx +++ b/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx @@ -5,18 +5,7 @@ import { useCallApi } from '@/hooks'; import { ColumnDef } from '@tanstack/react-table'; import React, { createContext, useCallback, useMemo, useState } from 'react'; import ListToolbar from '../blocks/ListToolbar'; - -interface WalletRuleProps { - ID: string; - id_wallet: string; - id_group: string; - max_transaction_per_day: number | null; - balance_minimum: number | null; - balance_maximum: number | null; - credit_limit: number | null; - monthly_limit: number | null; - status: string; -} +import { WalletRuleProps } from '../Types'; interface ContextProps { walletRules: WalletRuleProps[];