diff --git a/src/components/AddWithdraw/AddWithdrawCountriesList.tsx b/src/components/AddWithdraw/AddWithdrawCountriesList.tsx index 70c6ab5fb..32cc980a4 100644 --- a/src/components/AddWithdraw/AddWithdrawCountriesList.tsx +++ b/src/components/AddWithdraw/AddWithdrawCountriesList.tsx @@ -24,6 +24,8 @@ import PeanutLoading from '../Global/PeanutLoading' import { getCountryCodeForWithdraw } from '@/utils/withdraw.utils' import { DeviceType, useDeviceType } from '@/hooks/useGetDeviceType' import CryptoMethodDrawer from '../AddMoney/components/CryptoMethodDrawer' +import { useAppDispatch } from '@/redux/hooks' +import { bankFormActions } from '@/redux/slices/bank-form-slice' interface AddWithdrawCountriesListProps { flow: 'add' | 'withdraw' @@ -37,6 +39,7 @@ const AddWithdrawCountriesList = ({ flow }: AddWithdrawCountriesListProps) => { const { deviceType } = useDeviceType() const { user, fetchUser } = useAuth() const { setSelectedBankAccount, amountToWithdraw } = useWithdrawFlow() + const dispatch = useAppDispatch() // component level states const [view, setView] = useState<'list' | 'form'>('list') @@ -225,6 +228,8 @@ const AddWithdrawCountriesList = ({ flow }: AddWithdrawCountriesListProps) => { { + // clear DynamicBankAccountForm data + dispatch(bankFormActions.clearFormData()) // ensure kyc modal isn't open so late success events don't flip view setIsKycModalOpen(false) setView('list') diff --git a/src/components/AddWithdraw/DynamicBankAccountForm.tsx b/src/components/AddWithdraw/DynamicBankAccountForm.tsx index bececb135..b87e3d3b9 100644 --- a/src/components/AddWithdraw/DynamicBankAccountForm.tsx +++ b/src/components/AddWithdraw/DynamicBankAccountForm.tsx @@ -14,6 +14,8 @@ import PeanutActionDetailsCard, { PeanutActionDetailsCardProps } from '../Global import { PEANUT_WALLET_TOKEN_SYMBOL } from '@/constants' import { useWithdrawFlow } from '@/context/WithdrawFlowContext' import { getCountryFromIban, validateMXCLabeAccount, validateUSBankAccount } from '@/utils/withdraw.utils' +import { useAppDispatch, useAppSelector } from '@/redux/hooks' +import { bankFormActions } from '@/redux/slices/bank-form-slice' import { useDebounce } from '@/hooks/useDebounce' const isIBANCountry = (country: string) => { @@ -66,6 +68,7 @@ export const DynamicBankAccountForm = forwardRef<{ handleSubmit: () => void }, D const isUs = country.toUpperCase() === 'USA' const isIban = isUs || isMx ? false : isIBANCountry(country) const { user } = useAuth() + const dispatch = useAppDispatch() const [isSubmitting, setIsSubmitting] = useState(false) const [submissionError, setSubmissionError] = useState(null) const { country: countryNameParams } = useParams() @@ -76,6 +79,9 @@ export const DynamicBankAccountForm = forwardRef<{ handleSubmit: () => void }, D let selectedCountry = (countryNameFromProps ?? (countryNameParams as string)).toLowerCase() + // Get persisted form data from Redux + const persistedFormData = useAppSelector((state) => state.bankForm.formData) + const { control, handleSubmit, @@ -97,6 +103,7 @@ export const DynamicBankAccountForm = forwardRef<{ handleSubmit: () => void }, D state: '', postalCode: '', ...initialData, + ...persistedFormData, // Redux persisted data takes precedence }, mode: 'onBlur', reValidateMode: 'onSubmit', @@ -191,6 +198,17 @@ export const DynamicBankAccountForm = forwardRef<{ handleSubmit: () => void }, D }) if (result.error) { setSubmissionError(result.error) + setIsSubmitting(false) + } else { + // Save form data to Redux after successful submission + const formDataToSave = { + ...data, + country, + firstName: data.firstName.trim(), + lastName: data.lastName.trim(), + } + dispatch(bankFormActions.setFormData(formDataToSave)) + setIsSubmitting(false) } } catch (error: any) { setSubmissionError(error.message) diff --git a/src/components/Claim/Link/views/BankFlowManager.view.tsx b/src/components/Claim/Link/views/BankFlowManager.view.tsx index e2c09a7ee..9db74b7b2 100644 --- a/src/components/Claim/Link/views/BankFlowManager.view.tsx +++ b/src/components/Claim/Link/views/BankFlowManager.view.tsx @@ -28,6 +28,8 @@ import { InitiateKYCModal } from '@/components/Kyc' import { useWebSocket } from '@/hooks/useWebSocket' import { KYCStatus } from '@/utils/bridge-accounts.utils' import { getCountryCodeForWithdraw } from '@/utils/withdraw.utils' +import { useAppDispatch } from '@/redux/hooks' +import { bankFormActions } from '@/redux/slices/bank-form-slice' import { sendLinksApi } from '@/services/sendLinks' type BankAccountWithId = IBankAccountDetails & @@ -66,6 +68,7 @@ export const BankFlowManager = (props: IClaimScreenProps) => { const savedAccounts = useSavedAccounts() const { isLoading, setLoadingState } = useContext(loadingStateContext) const { claimLink } = useClaimLink() + const dispatch = useAppDispatch() // local states for this component const [localBankDetails, setLocalBankDetails] = useState(null) @@ -448,11 +451,12 @@ export const BankFlowManager = (props: IClaimScreenProps) => {
+ onPrev={() => { + dispatch(bankFormActions.clearFormData()) // clear DynamicBankAccountForm data savedAccounts.length > 0 ? setClaimBankFlowStep(ClaimBankFlowStep.SavedAccountsList) : setClaimBankFlowStep(ClaimBankFlowStep.BankCountryList) - } + }} />
>) { + state.formData = { ...(state.formData ?? {}), ...action.payload } + }, + updateFormField( + state, + action: PayloadAction<{ + field: keyof IBankAccountDetails + value: string + }> + ) { + const { field, value } = action.payload + if (!state.formData) { + state.formData = {} + } + state.formData[field] = value + }, + clearFormData(state) { + state.formData = null + }, + }, +}) + +export const bankFormActions = bankFormSlice.actions +export default bankFormSlice.reducer diff --git a/src/redux/store.ts b/src/redux/store.ts index a793aa76f..a3672945b 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -5,6 +5,7 @@ import setupReducer from './slices/setup-slice' import userReducer from './slices/user-slice' import walletReducer from './slices/wallet-slice' import zeroDevReducer from './slices/zerodev-slice' +import bankFormReducer from './slices/bank-form-slice' const store = configureStore({ reducer: { @@ -14,6 +15,7 @@ const store = configureStore({ payment: paymentReducer, user: userReducer, sendFlow: sendFlowReducer, + bankForm: bankFormReducer, }, // disable redux serialization checks middleware: (getDefaultMiddleware) => diff --git a/src/redux/types/bank-form.types.ts b/src/redux/types/bank-form.types.ts new file mode 100644 index 000000000..d6503e6c5 --- /dev/null +++ b/src/redux/types/bank-form.types.ts @@ -0,0 +1,7 @@ +import { IBankAccountDetails } from '@/components/AddWithdraw/DynamicBankAccountForm' + +export type BankFormFlow = 'claim' | 'withdraw' + +export interface IBankFormState { + formData: Partial | null +}