From 42cb40cd0f87f1268346a15aeb93d62a57469236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Wed, 24 Sep 2025 19:16:19 -0300 Subject: [PATCH 1/2] feat: remember manteca methods --- src/app/(mobile-ui)/withdraw/manteca/page.tsx | 7 +- src/components/AddMoney/consts/index.ts | 3 + .../AddWithdraw/AddWithdrawRouterView.tsx | 73 ++++++++++--------- src/interfaces/interfaces.ts | 1 + 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/app/(mobile-ui)/withdraw/manteca/page.tsx b/src/app/(mobile-ui)/withdraw/manteca/page.tsx index 0d8265b74..81eb8452f 100644 --- a/src/app/(mobile-ui)/withdraw/manteca/page.tsx +++ b/src/app/(mobile-ui)/withdraw/manteca/page.tsx @@ -42,7 +42,9 @@ export default function MantecaWithdrawFlow() { const [usdAmount, setUsdAmount] = useState(undefined) const [step, setStep] = useState('amountInput') const [balanceErrorMessage, setBalanceErrorMessage] = useState(null) - const [destinationAddress, setDestinationAddress] = useState('') + const searchParams = useSearchParams() + const paramAddress = searchParams.get('destination') + const [destinationAddress, setDestinationAddress] = useState(paramAddress ?? '') const [selectedBank, setSelectedBank] = useState(null) const [accountType, setAccountType] = useState(null) const [errorMessage, setErrorMessage] = useState(null) @@ -50,7 +52,6 @@ export default function MantecaWithdrawFlow() { const [isDestinationAddressValid, setIsDestinationAddressValid] = useState(false) const [isDestinationAddressChanging, setIsDestinationAddressChanging] = useState(false) const router = useRouter() - const searchParams = useSearchParams() const { sendMoney, balance } = useWallet() const { isLoading, loadingState, setLoadingState } = useContext(loadingStateContext) const { user, fetchUser } = useAuth() @@ -223,7 +224,7 @@ export default function MantecaWithdrawFlow() { setAmount(undefined) setCurrencyAmount(undefined) setUsdAmount(undefined) - setDestinationAddress('') + setDestinationAddress(paramAddress ?? '') setSelectedBank(null) setAccountType(null) setErrorMessage(null) diff --git a/src/components/AddMoney/consts/index.ts b/src/components/AddMoney/consts/index.ts index 9c21e2293..548c10894 100644 --- a/src/components/AddMoney/consts/index.ts +++ b/src/components/AddMoney/consts/index.ts @@ -2487,9 +2487,12 @@ const LATAM_COUNTRY_CODES = [ export const countryCodeMap: { [key: string]: string } = { ALA: 'AX', AND: 'AD', + ARG: 'AR', AUT: 'AT', BEL: 'BE', BGR: 'BG', + BOL: 'BO', + BRA: 'BR', HRV: 'HR', CYP: 'CY', CZE: 'CZ', diff --git a/src/components/AddWithdraw/AddWithdrawRouterView.tsx b/src/components/AddWithdraw/AddWithdrawRouterView.tsx index 878848649..b0c58f7ef 100644 --- a/src/components/AddWithdraw/AddWithdrawRouterView.tsx +++ b/src/components/AddWithdraw/AddWithdrawRouterView.tsx @@ -26,6 +26,27 @@ interface AddWithdrawRouterViewProps { const MAX_RECENT_METHODS = 5 +function saveRecentMethod(method: DepositMethod) { + const newRecentMethod: RecentMethod = { + id: method.id, + type: method.type as 'crypto' | 'country', + title: method.title, + description: method.description, + iconUrl: method.iconUrl, + currency: method.currency, + path: method.path, + } + + const prefs = getUserPreferences() || {} + const currentRecentList = prefs.recentAddMethods || [] + + const filteredList = currentRecentList.filter((m) => m.id !== newRecentMethod.id) + + const updatedRecentList = [newRecentMethod, ...filteredList].slice(0, MAX_RECENT_METHODS) + + updateUserPreferences({ ...prefs, recentAddMethods: updatedRecentList }) +} + export const AddWithdrawRouterView: FC = ({ flow, pageTitle, @@ -57,7 +78,10 @@ export const AddWithdrawRouterView: FC = ({ const bankAccounts = user?.accounts.filter( (acc) => - acc.type === AccountType.IBAN || acc.type === AccountType.US || acc.type === AccountType.CLABE + acc.type === AccountType.IBAN || + acc.type === AccountType.US || + acc.type === AccountType.CLABE || + acc.type === AccountType.MANTECA ) ?? [] if (bankAccounts.length > 0) { @@ -81,6 +105,10 @@ export const AddWithdrawRouterView: FC = ({ }, [flow, user, setShouldShowAllMethods]) const handleMethodSelected = (method: DepositMethod) => { + if (flow === 'add') { + saveRecentMethod(method) + } + // Handle "From Bank" specially for add flow if (flow === 'add' && method.id === 'bank-transfer-add') { setFromBankSelected(true) @@ -108,37 +136,6 @@ export const AddWithdrawRouterView: FC = ({ return } - // Original add flow logic - const newRecentMethod: RecentMethod = { - id: method.id, - type: method.type as 'crypto' | 'country', - title: method.title, - description: method.description, - iconUrl: method.iconUrl, - currency: method.currency, - path: method.path, - } - - const prefs = getUserPreferences() || {} - let currentRecentList: RecentMethod[] = [] - if (flow === 'add') { - currentRecentList = prefs.recentAddMethods || [] - } else { - currentRecentList = prefs.recentWithdrawMethods || [] - } - - const filteredList = currentRecentList.filter( - (m) => !(m.id === newRecentMethod.id && m.type === newRecentMethod.type) - ) - - const updatedRecentList = [newRecentMethod, ...filteredList].slice(0, MAX_RECENT_METHODS) - - if (flow === 'add') { - updateUserPreferences({ ...prefs, recentAddMethods: updatedRecentList }) - } else { - // for withdraw, we don't save to recents from the 'all methods' list, we show saved accounts - } - if (method.path) { router.push(method.path) } @@ -190,7 +187,13 @@ export const AddWithdrawRouterView: FC = ({ // FIXED: For withdraw flow, route to saved account path if (flow === 'withdraw') { - router.push(path) + if (account.type === AccountType.MANTECA) { + router.push( + `/withdraw/manteca?country=${account.details.countryName}&destination=${account.identifier}` + ) + } else { + router.push(path) + } return } @@ -261,13 +264,13 @@ export const AddWithdrawRouterView: FC = ({ viewMode="add-withdraw" onCountryClick={(country) => { if (flow === 'withdraw') { - // FIXED: Route directly to country page for method selection const countryPath = `${baseRoute}/${country.path}` router.push(countryPath) return } - // Original add flow + //Add + saveRecentMethod(country) const countryPath = `${baseRoute}/${country.path}` router.push(countryPath) }} diff --git a/src/interfaces/interfaces.ts b/src/interfaces/interfaces.ts index 030da12e4..769531eb6 100644 --- a/src/interfaces/interfaces.ts +++ b/src/interfaces/interfaces.ts @@ -269,6 +269,7 @@ export enum AccountType { EVM_ADDRESS = 'evm-address', PEANUT_WALLET = 'peanut-wallet', BRIDGE = 'bridgeBankAccount', + MANTECA = 'manteca', } export interface Account { From 2e3a0b59f3f377b6a7dc86c061fcde4672ba1038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Fri, 26 Sep 2025 13:11:12 -0300 Subject: [PATCH 2/2] refactor: rename and separate country code map --- .../withdraw/[country]/bank/page.tsx | 5 +- .../components/AddMoneyBankDetails.tsx | 4 +- .../AddMoney/components/DepositMethodList.tsx | 5 +- src/components/AddMoney/consts/index.ts | 22 +- .../AddWithdraw/DynamicBankAccountForm.tsx | 6 +- .../Link/views/Confirm.bank-claim.view.tsx | 4 +- src/components/Common/CountryList.tsx | 20 +- src/components/Common/SavedAccountsView.tsx | 5 +- src/components/Kyc/KycStatusDrawer.tsx | 4 +- .../views/IdentityVerification.view.tsx | 253 +++++++++--------- src/utils/withdraw.utils.ts | 8 +- 11 files changed, 173 insertions(+), 163 deletions(-) diff --git a/src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx b/src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx index c6565d5cd..99ccb3a0b 100644 --- a/src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx +++ b/src/app/(mobile-ui)/withdraw/[country]/bank/page.tsx @@ -1,7 +1,7 @@ 'use client' import { Button } from '@/components/0_Bruddle' -import { countryCodeMap } from '@/components/AddMoney/consts' +import { ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '@/components/AddMoney/consts' import Card from '@/components/Global/Card' import ErrorAlert from '@/components/Global/ErrorAlert' import NavHeader from '@/components/Global/NavHeader' @@ -183,7 +183,8 @@ export default function WithdrawBankPage() { const countryCodeForFlag = () => { if (!bankAccount?.details?.countryCode) return '' - const code = countryCodeMap[bankAccount.details.countryCode ?? ''] ?? bankAccount.details.countryCode + const code = + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[bankAccount.details.countryCode ?? ''] ?? bankAccount.details.countryCode return code.toLowerCase() } diff --git a/src/components/AddMoney/components/AddMoneyBankDetails.tsx b/src/components/AddMoney/components/AddMoneyBankDetails.tsx index 1472e6d40..3677f3236 100644 --- a/src/components/AddMoney/components/AddMoneyBankDetails.tsx +++ b/src/components/AddMoney/components/AddMoneyBankDetails.tsx @@ -9,7 +9,7 @@ import { PEANUT_WALLET_TOKEN_SYMBOL } from '@/constants' import { useOnrampFlow } from '@/context/OnrampFlowContext' import { useRouter, useParams } from 'next/navigation' import { useCallback, useEffect, useMemo } from 'react' -import { countryCodeMap, CountryData, countryData } from '@/components/AddMoney/consts' +import { ALL_COUNTRIES_ALPHA3_TO_ALPHA2, CountryData, countryData } from '@/components/AddMoney/consts' import { formatCurrencyAmount } from '@/utils/currency' import { formatBankAccountDisplay } from '@/utils/format.utils' import Icon from '@/components/Global/Icon' @@ -93,7 +93,7 @@ export default function AddMoneyBankDetails({ flow = 'add-money' }: IAddMoneyBan const countryCodeForFlag = useMemo(() => { const countryId = currentCountryDetails?.id || 'USA' - const countryCode = countryCodeMap[countryId] || countryId // if countryId is not in countryCodeMap, use countryId because for some countries countryId is of 2 digit and countryCodeMap is a mapping of 3 digit to 2 digit country codes + const countryCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[countryId] || countryId // if countryId is not in countryCodeMap, use countryId because for some countries countryId is of 2 digit and countryCodeMap is a mapping of 3 digit to 2 digit country codes return countryCode?.toLowerCase() || 'us' }, [currentCountryDetails]) diff --git a/src/components/AddMoney/components/DepositMethodList.tsx b/src/components/AddMoney/components/DepositMethodList.tsx index 838085590..9cd6679f4 100644 --- a/src/components/AddMoney/components/DepositMethodList.tsx +++ b/src/components/AddMoney/components/DepositMethodList.tsx @@ -4,7 +4,7 @@ import AvatarWithBadge from '@/components/Profile/AvatarWithBadge' import { SearchResultCard } from '@/components/SearchUsers/SearchResultCard' import Image from 'next/image' import { twMerge } from 'tailwind-merge' -import { countryCodeMap } from '../consts' +import { ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '../consts' export interface DepositMethod { type: 'crypto' | 'country' @@ -54,7 +54,8 @@ export const DepositMethodList = ({ methods, onItemClick, isAllMethodsView = fal } const threeLetterCountryCode = (method.id ?? '').toUpperCase() - const twoLetterCountryCode = countryCodeMap[threeLetterCountryCode] ?? threeLetterCountryCode + const twoLetterCountryCode = + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode const countryCodeForFlag = twoLetterCountryCode.toLowerCase() ?? '' diff --git a/src/components/AddMoney/consts/index.ts b/src/components/AddMoney/consts/index.ts index 548c10894..afb8ebb3c 100644 --- a/src/components/AddMoney/consts/index.ts +++ b/src/components/AddMoney/consts/index.ts @@ -2484,15 +2484,12 @@ const LATAM_COUNTRY_CODES = [ // bridge EAA country codes, source: https://apidocs.bridge.xyz/docs/sepa-euro-transactions // note: this is a map of 3-letter country codes to 2-letter country codes, for flags to work, bridge expects 3 letter codes -export const countryCodeMap: { [key: string]: string } = { +export const BRIDGE_ALPHA3_TO_ALPHA2: { [key: string]: string } = { ALA: 'AX', AND: 'AD', - ARG: 'AR', AUT: 'AT', BEL: 'BE', BGR: 'BG', - BOL: 'BO', - BRA: 'BR', HRV: 'HR', CYP: 'CY', CZE: 'CZ', @@ -2531,9 +2528,20 @@ export const countryCodeMap: { [key: string]: string } = { USA: 'US', } -const enabledBankWithdrawCountries = new Set([...Object.values(countryCodeMap), 'US', 'MX', 'AR', 'BO']) +export const MANTECA_ALPHA3_TO_ALPHA2: { [key: string]: string } = { + ARG: 'AR', + BOL: 'BO', + BRA: 'BR', +} + +export const ALL_COUNTRIES_ALPHA3_TO_ALPHA2: { [key: string]: string } = { + ...BRIDGE_ALPHA3_TO_ALPHA2, + ...MANTECA_ALPHA3_TO_ALPHA2, +} + +const enabledBankWithdrawCountries = new Set([...Object.values(BRIDGE_ALPHA3_TO_ALPHA2), 'US', 'MX', 'AR', 'BO']) -const enabledBankDepositCountries = new Set([...Object.values(countryCodeMap), 'US', 'AR']) +const enabledBankDepositCountries = new Set([...Object.values(BRIDGE_ALPHA3_TO_ALPHA2), 'US', 'AR']) // Helper function to check if a country code is enabled for bank transfers // Handles both 2-letter and 3-letter country codes @@ -2545,7 +2553,7 @@ const isCountryEnabledForBankTransfer = (countryCode: string, direction: 'withdr } // Check if it's a 3-letter code that maps to an enabled 2-letter code - const mappedCode = countryCodeMap[countryCode] + const mappedCode = ALL_COUNTRIES_ALPHA3_TO_ALPHA2[countryCode] return mappedCode ? enabledCountries.has(mappedCode) : false } diff --git a/src/components/AddWithdraw/DynamicBankAccountForm.tsx b/src/components/AddWithdraw/DynamicBankAccountForm.tsx index 0617df83d..3f2170777 100644 --- a/src/components/AddWithdraw/DynamicBankAccountForm.tsx +++ b/src/components/AddWithdraw/DynamicBankAccountForm.tsx @@ -5,7 +5,7 @@ import { useAuth } from '@/context/authContext' import { Button } from '@/components/0_Bruddle/Button' import { AddBankAccountPayload, BridgeAccountOwnerType, BridgeAccountType } from '@/app/actions/types/users.types' import BaseInput from '@/components/0_Bruddle/BaseInput' -import { countryCodeMap } from '@/components/AddMoney/consts' +import { BRIDGE_ALPHA3_TO_ALPHA2, ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '@/components/AddMoney/consts' import { useParams, useRouter } from 'next/navigation' import { validateIban, validateBic, isValidRoutingNumber } from '@/utils/bridge-accounts.utils' import ErrorAlert from '@/components/Global/ErrorAlert' @@ -20,7 +20,7 @@ import { bankFormActions } from '@/redux/slices/bank-form-slice' import { useDebounce } from '@/hooks/useDebounce' const isIBANCountry = (country: string) => { - return countryCodeMap[country.toUpperCase()] !== undefined + return BRIDGE_ALPHA3_TO_ALPHA2[country.toUpperCase()] !== undefined } export type IBankAccountDetails = { @@ -273,7 +273,7 @@ export const DynamicBankAccountForm = forwardRef<{ handleSubmit: () => void }, D ) const countryCodeForFlag = useMemo(() => { - return countryCodeMap[country.toUpperCase()] ?? country.toUpperCase() + return ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.toUpperCase()] ?? country.toUpperCase() }, [country]) return ( diff --git a/src/components/Claim/Link/views/Confirm.bank-claim.view.tsx b/src/components/Claim/Link/views/Confirm.bank-claim.view.tsx index e0df2d795..12ea4596c 100644 --- a/src/components/Claim/Link/views/Confirm.bank-claim.view.tsx +++ b/src/components/Claim/Link/views/Confirm.bank-claim.view.tsx @@ -1,7 +1,7 @@ 'use client' import { Button } from '@/components/0_Bruddle' -import { countryCodeMap } from '@/components/AddMoney/consts' +import { ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '@/components/AddMoney/consts' import Card from '@/components/Global/Card' import ErrorAlert from '@/components/Global/ErrorAlert' import NavHeader from '@/components/Global/NavHeader' @@ -50,7 +50,7 @@ export function ConfirmBankClaimView({ }, [bankDetails]) const countryCodeForFlag = useMemo(() => { - return countryCodeMap[bankDetails?.country?.toUpperCase()] ?? bankDetails.country.toUpperCase() + return ALL_COUNTRIES_ALPHA3_TO_ALPHA2[bankDetails?.country?.toUpperCase()] ?? bankDetails.country.toUpperCase() }, [bankDetails.country]) // amount in USD from claim link data diff --git a/src/components/Common/CountryList.tsx b/src/components/Common/CountryList.tsx index 495687e2f..b0eb12b81 100644 --- a/src/components/Common/CountryList.tsx +++ b/src/components/Common/CountryList.tsx @@ -1,5 +1,11 @@ 'use client' -import { countryCodeMap, CountryData, countryData, MantecaSupportedExchanges } from '@/components/AddMoney/consts' +import { + BRIDGE_ALPHA3_TO_ALPHA2, + CountryData, + countryData, + MantecaSupportedExchanges, + ALL_COUNTRIES_ALPHA3_TO_ALPHA2, +} from '@/components/AddMoney/consts' import EmptyState from '@/components/Global/EmptyStates/EmptyState' import { SearchInput } from '@/components/SearchUsers/SearchInput' import { SearchResultCard } from '@/components/SearchUsers/SearchResultCard' @@ -53,9 +59,11 @@ export const CountryList = ({ return [...supportedCountries].sort((a, b) => { if (userGeoLocationCountryCode) { const aIsUserCountry = - countryCodeMap[a.id] === userGeoLocationCountryCode || a.id === userGeoLocationCountryCode + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[a.id] === userGeoLocationCountryCode || + a.id === userGeoLocationCountryCode const bIsUserCountry = - countryCodeMap[b.id] === userGeoLocationCountryCode || b.id === userGeoLocationCountryCode + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[b.id] === userGeoLocationCountryCode || + b.id === userGeoLocationCountryCode if (aIsUserCountry && !bIsUserCountry) return -1 if (!aIsUserCountry && bIsUserCountry) return 1 @@ -111,14 +119,14 @@ export const CountryList = ({ {filteredCountries.length > 0 ? ( filteredCountries.map((country, index) => { const twoLetterCountryCode = - countryCodeMap[country.id.toUpperCase()] ?? country.id.toLowerCase() + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country.id.toUpperCase()] ?? country.id.toLowerCase() const position = getCardPosition(index, filteredCountries.length) const isBridgeSupportedCountry = [ 'US', 'MX', - ...Object.keys(countryCodeMap), - ...Object.values(countryCodeMap), + ...Object.keys(BRIDGE_ALPHA3_TO_ALPHA2), + ...Object.values(BRIDGE_ALPHA3_TO_ALPHA2), ].includes(country.id) const isMantecaSupportedCountry = Object.keys(MantecaSupportedExchanges).includes( country.id diff --git a/src/components/Common/SavedAccountsView.tsx b/src/components/Common/SavedAccountsView.tsx index 876172ada..e23194ba4 100644 --- a/src/components/Common/SavedAccountsView.tsx +++ b/src/components/Common/SavedAccountsView.tsx @@ -1,5 +1,5 @@ 'use client' -import { countryData as ALL_METHODS_DATA, countryCodeMap } from '@/components/AddMoney/consts' +import { countryData as ALL_METHODS_DATA, ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '@/components/AddMoney/consts' import { shortenAddressLong, formatIban } from '@/utils/general.utils' import { AccountType, Account } from '@/interfaces' import Image from 'next/image' @@ -74,7 +74,8 @@ export function SavedAccountsMapping({ } const threeLetterCountryCode = (details.countryCode ?? '').toUpperCase() - const twoLetterCountryCode = countryCodeMap[threeLetterCountryCode] ?? threeLetterCountryCode + const twoLetterCountryCode = + ALL_COUNTRIES_ALPHA3_TO_ALPHA2[threeLetterCountryCode] ?? threeLetterCountryCode const countryCodeForFlag = twoLetterCountryCode.toLowerCase() ?? '' diff --git a/src/components/Kyc/KycStatusDrawer.tsx b/src/components/Kyc/KycStatusDrawer.tsx index bf8834563..fbd23234b 100644 --- a/src/components/Kyc/KycStatusDrawer.tsx +++ b/src/components/Kyc/KycStatusDrawer.tsx @@ -120,7 +120,7 @@ export const KycStatusDrawer = ({ isOpen, onClose, verification, bridgeKycStatus case 'processing': return ( @@ -137,7 +137,7 @@ export const KycStatusDrawer = ({ isOpen, onClose, verification, bridgeKycStatus return ( { - const { user, fetchUser } = useAuth() const router = useRouter() const formRef = useRef<{ handleSubmit: () => void }>(null) const [isUserDetailsFormValid, setIsUserDetailsFormValid] = useState(false) @@ -34,8 +33,10 @@ const IdentityVerificationView = () => { const [isMantecaModalOpen, setIsMantecaModalOpen] = useState(false) const [selectedCountry, setSelectedCountry] = useState<{ id: string; title: string } | null>(null) const [userClickedCountry, setUserClickedCountry] = useState<{ id: string; title: string } | null>(null) + const { isUserBridgeKycApproved } = useKycStatus() + const { user, fetchUser } = useAuth() - const handleRedirect = useCallback(() => { + const handleRedirect = () => { const redirectUrl = getRedirectUrl() if (redirectUrl) { clearRedirectUrl() @@ -43,87 +44,80 @@ const IdentityVerificationView = () => { } else { router.replace('/profile') } - }, [router]) - - const handleKycSuccess = useCallback(async () => { - await fetchUser() - handleRedirect() - }, [router, fetchUser]) - - const handleMantecaKycSuccess = useCallback(() => { - handleRedirect() - }, [router]) + } const { iframeOptions, handleInitiateKyc, - handleIframeClose, isVerificationProgressModalOpen, closeVerificationProgressModal, error: kycError, isLoading: isKycLoading, - } = useBridgeKycFlow({ onKycSuccess: handleKycSuccess }) - - const { isUserBridgeKycApproved } = useKycStatus() - - const [firstName, ...lastNameParts] = (user?.user.fullName ?? '').split(' ') - const lastName = lastNameParts.join(' ') + } = useBridgeKycFlow({ + onKycSuccess: async () => { + await fetchUser() + handleRedirect() + }, + }) const initialUserDetails: Partial = useMemo( () => ({ fullName: user?.user.fullName ?? '', email: user?.user.email ?? '', }), - [user?.user.fullName, user?.user.email, firstName, lastName] + [user] ) - const handleUserDetailsSubmit = async (data: UserDetailsFormData) => { - setIsUpdatingUser(true) - setUserUpdateError(null) - try { - if (!user?.user.userId) throw new Error('User not found') - const result = await updateUserById({ - userId: user.user.userId, - fullName: data.fullName, - email: data.email, - }) - if (result.error) { - throw new Error(result.error) + const handleUserDetailsSubmit = useCallback( + async (data: UserDetailsFormData) => { + setIsUpdatingUser(true) + setUserUpdateError(null) + try { + if (!user?.user.userId) throw new Error('User not found') + const result = await updateUserById({ + userId: user.user.userId, + fullName: data.fullName, + email: data.email, + }) + if (result.error) { + throw new Error(result.error) + } + await fetchUser() + await handleInitiateKyc() + } catch (error: any) { + setUserUpdateError(error.message) + return { error: error.message } + } finally { + setIsUpdatingUser(false) } - await fetchUser() - await handleInitiateKyc() - } catch (error: any) { - setUserUpdateError(error.message) - return { error: error.message } - } finally { - setIsUpdatingUser(false) - } - return {} - } + return {} + }, + [user] + ) const handleBack = useCallback(() => { if (showUserDetailsForm) { setShowUserDetailsForm(false) } else { - router.replace('/profile') + handleRedirect() } - }, [router, showUserDetailsForm]) + }, [showUserDetailsForm]) // country validation helpers - const isBridgeSupportedCountry = useCallback((code: string) => { + const isBridgeSupportedCountry = (code: string) => { const upper = code.toUpperCase() return ( upper === 'US' || upper === 'MX' || - Object.keys(countryCodeMap).includes(upper) || - Object.values(countryCodeMap).includes(upper) + Object.keys(BRIDGE_ALPHA3_TO_ALPHA2).includes(upper) || + Object.values(BRIDGE_ALPHA3_TO_ALPHA2).includes(upper) ) - }, []) + } - const isMantecaSupportedCountry = useCallback((code: string) => { + const isMantecaSupportedCountry = (code: string) => { const upper = code.toUpperCase() return Object.prototype.hasOwnProperty.call(MantecaSupportedExchanges, upper) - }, []) + } const isVerifiedForCountry = useCallback( (code: string) => { @@ -139,91 +133,83 @@ const IdentityVerificationView = () => { ) return Boolean(mantecaActive) }, - [isBridgeSupportedCountry, user?.user.bridgeKycStatus, user?.user.kycVerifications] - ) - - // view components - const CountrySelectionView = () => ( -
- - isVerifiedForCountry(country.id) ? ( - - ) : undefined - } - onCountryClick={(country) => { - const { id, title } = country - setUserClickedCountry({ id, title }) - - if (isVerifiedForCountry(id)) { - setIsAlreadyVerifiedModalOpen(true) - return - } - - if (isBridgeSupportedCountry(id)) { - setShowUserDetailsForm(true) - return - } - - if (isMantecaSupportedCountry(id)) { - setSelectedCountry({ id, title }) - setIsMantecaModalOpen(true) - } - }} - onCryptoClick={() => console.log('crypto')} - /> -
+ [user] ) - const UserDetailsFormView = () => ( -
-

Provide information to begin verification

- - - - - - - - {(userUpdateError || kycError) && } - - - - -
- ) - - // determine which view to show based on current state - const getCurrentView = () => { - return showUserDetailsForm ? : - } - return (
- {getCurrentView()} + {showUserDetailsForm ? ( +
+

Provide information to begin verification

+ + + + + + + + {(userUpdateError || kycError) && } + + + + { + closeVerificationProgressModal() + handleRedirect() + }} + /> +
+ ) : ( +
+ + isVerifiedForCountry(country.id) ? ( + + ) : undefined + } + onCountryClick={(country) => { + const { id, title } = country + setUserClickedCountry({ id, title }) + + if (isVerifiedForCountry(id)) { + setIsAlreadyVerifiedModalOpen(true) + return + } + + if (isBridgeSupportedCountry(id)) { + setShowUserDetailsForm(true) + return + } + + if (isMantecaSupportedCountry(id)) { + setSelectedCountry({ id, title }) + setIsMantecaModalOpen(true) + } + }} + /> +
+ )} { text: 'Close', shadowSize: '4', className: 'md:py-2', - onClick: () => setIsAlreadyVerifiedModalOpen(false), + onClick: () => { + setIsAlreadyVerifiedModalOpen(false) + handleRedirect() + }, }, ]} /> @@ -252,7 +241,7 @@ const IdentityVerificationView = () => { selectedCountry={selectedCountry} setIsMantecaModalOpen={setIsMantecaModalOpen} isMantecaModalOpen={isMantecaModalOpen} - onKycSuccess={handleMantecaKycSuccess} + onKycSuccess={handleRedirect} /> )}
diff --git a/src/utils/withdraw.utils.ts b/src/utils/withdraw.utils.ts index 9a65ce148..4eeb67bd5 100644 --- a/src/utils/withdraw.utils.ts +++ b/src/utils/withdraw.utils.ts @@ -1,4 +1,4 @@ -import { countryData, countryCodeMap } from '@/components/AddMoney/consts' +import { countryData, ALL_COUNTRIES_ALPHA3_TO_ALPHA2 } from '@/components/AddMoney/consts' /** * Extracts the country name from an IBAN by parsing the first 2 characters (country code) @@ -136,12 +136,14 @@ export const validateMXCLabeAccount = (accountNumber: string) => { // Returns the 3-letter country code for the given country code export const getCountryCodeForWithdraw = (country: string) => { // If the input is already a 3-digit code and exists in the map, return it - if (countryCodeMap[country]) { + if (ALL_COUNTRIES_ALPHA3_TO_ALPHA2[country]) { return country } // If the input is a 2-digit code, find the corresponding 3-digit code - const threeDigitCode = Object.keys(countryCodeMap).find((key) => countryCodeMap[key] === country) + const threeDigitCode = Object.keys(ALL_COUNTRIES_ALPHA3_TO_ALPHA2).find( + (key) => ALL_COUNTRIES_ALPHA3_TO_ALPHA2[key] === country + ) return threeDigitCode || country }