diff --git a/src/components/BuyProgressBar/index.tsx b/src/components/BuyProgressBar/index.tsx new file mode 100644 index 000000000..8065b79a4 --- /dev/null +++ b/src/components/BuyProgressBar/index.tsx @@ -0,0 +1,203 @@ +import React, { useEffect, useState, useMemo } from 'react' +import { Box, HStack, Circle, Text } from 'native-base' + +export type BuyStep = 1 | 2 | 3 + +export interface StepConfig { + number: number + label: string +} + +interface BuyProgressBarProps { + currentStep: BuyStep + isLoading?: boolean + steps?: StepConfig[] +} + +const BuyProgressBar: React.FC = ({ + currentStep, + isLoading = false, + steps = [ + { number: 1, label: 'Buy cUSD' }, + { number: 2, label: 'We swap cUSD to G$' }, + { number: 3, label: 'Done' }, + ], +}) => { + const [animatedWidth, setAnimatedWidth] = useState(0) + + // Handle animated progress line + useEffect(() => { + if (isLoading && currentStep >= 1) { + // Explicitly reset animatedWidth to 0 at the start of a new loading phase + setAnimatedWidth(0) + // Animate progress line when loading + let progress = 0 + const interval = setInterval(() => { + progress += 2 + if (progress <= 100) { + setAnimatedWidth(progress) + } else { + clearInterval(interval) + } + }, 50) // 50ms intervals for smooth animation + + return () => clearInterval(interval) + } else { + // Set to 100% if not loading (completed state) + setAnimatedWidth(100) + } + }, [isLoading, currentStep]) + + const getStepStatus = (stepNumber: number) => { + // Step 1 should ALWAYS be blue (active when current, completed when past) + if (stepNumber === 1) { + if (currentStep === 1) { + return isLoading ? 'loading' : 'active' + } else { + return 'completed' // Step 1 is completed when we're on step 2 or 3 + } + } + // Steps 2 and 3 follow normal logic + if (stepNumber < currentStep) return 'completed' + if (stepNumber === currentStep) return isLoading ? 'loading' : 'active' + return 'pending' + } + + // Memoize circle props objects to avoid recreation on every render + const circlePropsMap = useMemo( + () => ({ + completed: { + size: '12', + mb: 2, + justifyContent: 'center', + alignItems: 'center', + bg: 'blue.500', + }, + active: { + size: '12', + mb: 2, + justifyContent: 'center', + alignItems: 'center', + bg: 'blue.500', + }, + loading: { + size: '12', + mb: 2, + justifyContent: 'center', + alignItems: 'center', + bg: 'blue.500', + borderWidth: 3, + borderColor: 'blue.200', + animation: 'pulse 2s infinite', + }, + pending: { + size: '12', + mb: 2, + justifyContent: 'center', + alignItems: 'center', + bg: 'gray.300', + }, + }), + [] + ) + + const getCircleProps = (status: string) => { + return circlePropsMap[status as keyof typeof circlePropsMap] || circlePropsMap.pending + } + + const getLineProps = (stepNumber: number, lineIndex: number) => { + // Line between step 1 and 2 (lineIndex = 0) + if (lineIndex === 0) { + if (currentStep === 1 && isLoading) { + // Animation state: "1 Blue with progress bar animation" + return { + bg: 'blue.500', + width: `${animatedWidth}%`, + transition: 'width 0.1s ease-out', + } + } else if (currentStep >= 2) { + // Static line when step 2 or higher + return { + bg: 'blue.500', + width: '100%', + } + } + } + + // Line between step 2 and 3 (lineIndex = 1) + if (lineIndex === 1) { + if (currentStep === 2 && isLoading) { + // Animation state: "2 Blue with progress bar animation" + return { + bg: 'blue.500', + width: `${animatedWidth}%`, + transition: 'width 0.1s ease-out', + } + } else if (currentStep >= 3) { + // Static line when step 3 + return { + bg: 'blue.500', + width: '100%', + } + } + } + + // Default: gray line (not active) + return { + bg: 'gray.300', + width: '100%', + } + } + + const getTextColor = (status: string) => { + return status === 'pending' ? 'gray.500' : 'black' + } + + return ( + + + {steps.map((step, index) => { + const status = getStepStatus(step.number) + + return ( + + + + + {step.number} + + + + {step.label} + + + + {index < steps.length - 1 && ( + + + + )} + + ) + })} + + + ) +} + +export { BuyProgressBar } diff --git a/src/components/CustomGdOnramperWidget/CustomGdOnramperWidget.tsx b/src/components/CustomGdOnramperWidget/CustomGdOnramperWidget.tsx new file mode 100644 index 000000000..a7d53e3a2 --- /dev/null +++ b/src/components/CustomGdOnramperWidget/CustomGdOnramperWidget.tsx @@ -0,0 +1,177 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react' +import { useEthers, useEtherBalance, useTokenBalance } from '@usedapp/core' +import { WebViewMessageEvent } from 'react-native-webview' +import { AsyncStorage, useBuyGd } from '@gooddollar/web3sdk-v2' +import { noop } from 'lodash' + +import { useModal } from '@gooddollar/good-design/dist/hooks/useModal' +import { View, Text } from 'native-base' +import { WalletAndChainGuard } from '@gooddollar/good-design' +import { useSignWalletModal } from '@gooddollar/good-design/dist/hooks/useSignWalletModal' +import { CustomOnramper } from './CustomOnramper' + +interface ErrorModalProps { + message?: string +} + +const ErrorModal: React.FC = ({ message = 'Something went wrong.' }) => ( + + {message} + +) + +interface ICustomGdOnramperProps { + onEvents: (action: string, data?: any, error?: string) => void + selfSwap?: boolean + withSwap?: boolean + donateOrExecTo?: string + callData?: string + apiKey?: string +} + +export const CustomGdOnramperWidget = ({ + onEvents = noop, + selfSwap = false, + withSwap = true, + donateOrExecTo = undefined, + callData = '0x', + apiKey = undefined, +}: ICustomGdOnramperProps) => { + const cusd = '0x765de816845861e75a25fca122bb6898b8b1282a' + const { account, library } = useEthers() + const swapLock = useRef(false) + + const { createAndSwap, swap, swapState, createState, gdHelperAddress, triggerSwapTx } = useBuyGd({ + donateOrExecTo, + callData, + withSwap, + }) + + const { SignWalletModal } = useSignWalletModal() + + const celoBalance = useEtherBalance(gdHelperAddress) + const cusdBalance = useTokenBalance(cusd, gdHelperAddress) + + const { showModal, Modal } = useModal() + + const [step, setStep] = useState(0) + + /** + * callback to get event from onramper iframe + * Optimized to avoid unnecessary parsing and improve error handling + */ + const callback = useCallback( + async (event: WebViewMessageEvent) => { + const rawData = event.nativeEvent?.data + if (!rawData) return + + let eventData + try { + // Only parse if it's a string, otherwise use directly + eventData = typeof rawData === 'string' ? JSON.parse(rawData) : rawData + } catch (error) { + // Silent fail for invalid JSON - expected for non-JSON messages + return + } + + // Early return if no valid event data + if (!eventData?.type && !eventData?.title) return + + // Handle different Onramper event types + switch (eventData.type || eventData.title) { + case 'initiated': + case 'opened': + // User opened/interacted with the widget + onEvents('widget_clicked') + break + case 'success': + await AsyncStorage.setItem('gdOnrampSuccess', 'true') + setStep(2) + break + default: + break + } + }, + [onEvents] + ) + + const triggerSwap = async () => { + if (swapLock.current) return //prevent from useEffect retriggering this + swapLock.current = true + + try { + setStep(3) + // Emit swap_started event to animate progress bar step 2 + onEvents('swap_started') + + //user sends swap tx + if (selfSwap && gdHelperAddress && library && account) { + const minAmount = 0 // we let contract use oracle for minamount, we might calculate it for more precision in the future + const code = await library.getCode(gdHelperAddress) + let swapTx + if (code.length <= 2) { + swapTx = createAndSwap(minAmount) + } else { + swapTx = swap(minAmount) + } + + setStep(4) + // after tx sent progress the stepper + const res = await swapTx + if (res?.status !== 1) throw Error('reverted') + } else { + if (account) { + //or backends sends swap tx + setStep(4) + const tx = await triggerSwapTx() + + if (!tx?.ok) throw Error('reverted') + } + } + // when done set stepper at final step + setStep(5) + swapLock.current = false + // Emit swap_completed event to move progress bar to step 3 + onEvents('swap_completed') + onEvents('buy_success') + } catch (e: any) { + swapLock.current = false // Reset lock on error + showModal() + onEvents('buygd_swap_failed', e.message) + setStep(0) + } + } + + // when the helper contract has some balance we trigger the swap + useEffect(() => { + if (cusdBalance?.gt(0) || celoBalance?.gt(0)) { + void AsyncStorage.removeItem('gdOnrampSuccess') + // Emit funds_received event to update progress bar to step 2 + onEvents('funds_received') + triggerSwap().catch((e) => { + showModal() + onEvents('buygd_swap_failed', e.message) + }) + } + }, [celoBalance, cusdBalance]) + + return ( + <> + } _modalContainer={{ paddingBottom: 18, paddingLeft: 18, paddingRight: 18 }} /> + + + + + + + ) +} diff --git a/src/components/CustomGdOnramperWidget/CustomOnramper.tsx b/src/components/CustomGdOnramperWidget/CustomOnramper.tsx new file mode 100644 index 000000000..c2600f213 --- /dev/null +++ b/src/components/CustomGdOnramperWidget/CustomOnramper.tsx @@ -0,0 +1,181 @@ +import React, { useEffect, useMemo, useState } from 'react' +import { WebView, WebViewMessageEvent } from 'react-native-webview' +import { Box, Divider, useBreakpointValue } from 'native-base' +import { AsyncStorage, isMobile as deviceDetect } from '@gooddollar/web3sdk-v2' + +import { CentreBox } from '@gooddollar/good-design/dist/core/layout/CentreBox' +import { useWindowFocus } from '@gooddollar/good-design/dist/hooks' + +export type OnramperCallback = (event: WebViewMessageEvent) => void + +export interface WidgetParams { + onlyCryptos?: string + isAddressEditable?: boolean + supportSell?: boolean + supportSwap?: boolean + [key: string]: string | boolean | undefined +} + +export const CustomOnramper = ({ + onEvent, + onGdEvent, + step, + setStep, + apiKey, + widgetParams = { onlyCryptos: 'CUSD_CELO', isAddressEditable: false, supportSell: false, supportSwap: false }, + targetNetwork = 'CELO', + targetWallet, +}: { + onEvent?: OnramperCallback + onGdEvent: (action: string) => void + step: number + setStep: (step: number) => void + widgetParams?: WidgetParams + targetWallet?: string + targetNetwork?: string + apiKey?: string +}) => { + // Memoize URL construction to avoid reconstruction on every render + const uri = useMemo(() => { + const url = new URL('https://buy.onramper.com/') + + // Always include API key for proper authentication + // SECURITY NOTE: Onramper API keys are designed for client-side use + // - These are PUBLIC API keys specifically intended for browser environments + // - They are NOT secret keys and are safe to expose in client-side code + // - Similar to Google Maps API keys, they're restricted by domain/referrer + // - This follows Onramper's official integration documentation + // - See: https://docs.onramper.com for official security guidelines + if (apiKey) { + url.searchParams.set('apiKey', apiKey) + } else { + console.warn('Onramper: No API key provided') + } + url.searchParams.set('networkWallets', `${targetNetwork}:${targetWallet}`) + Object.entries(widgetParams).forEach(([k, v]) => { + if (v !== undefined) { + url.searchParams.set(k, String(v)) + } + }) + + return url.toString() + }, [apiKey, targetNetwork, targetWallet, widgetParams]) + + const { title } = useWindowFocus() + + // Cache AsyncStorage value to avoid repeated reads + const [cachedOnrampStatus, setCachedOnrampStatus] = useState(null) + + const isMobile = deviceDetect() + + // Responsive dimensions for the widget + const widgetDimensions = useBreakpointValue({ + base: { + maxWidth: '100%', + width: '95vw', + height: 500, + webViewWidth: '100%', + webViewHeight: 500, + }, + sm: { + maxWidth: 400, + width: '90%', + height: 550, + webViewWidth: 380, + webViewHeight: 550, + }, + md: { + maxWidth: 450, + width: '80%', + height: 600, + webViewWidth: 430, + webViewHeight: 600, + }, + lg: { + maxWidth: 480, + width: '100%', + height: 630, + webViewWidth: 480, + webViewHeight: 630, + }, + xl: { + maxWidth: 480, + width: '200%', + height: 630, + webViewWidth: 480, + webViewHeight: 630, + }, + }) + + // on page load check if a returning user is awaiting funds + // Cache the value to avoid repeated AsyncStorage reads + useEffect(() => { + const isOnramping = async () => { + if (cachedOnrampStatus === null) { + const status = await AsyncStorage.getItem('gdOnrampSuccess') + setCachedOnrampStatus(status) + if (status === 'true') { + setStep(2) + } + } + } + + void isOnramping() + }, [cachedOnrampStatus]) + + useEffect(() => { + if (title === 'Onramper widget' && step === 0) { + onGdEvent('buy_start') + setStep(1) + } + }, [title, step, onGdEvent, setStep]) + + if (!targetWallet) { + return ( +
+ Wallet not found. Please select a valid wallet to continue. +
+ ) + } + + return ( + + + { + const { nativeEvent } = syntheticEvent + console.error('Onramper WebView error:', nativeEvent) + }} + onHttpError={(syntheticEvent) => { + const { nativeEvent } = syntheticEvent + console.error('Onramper HTTP error:', nativeEvent.statusCode, nativeEvent.description) + }} + height={widgetDimensions?.webViewHeight} + width={widgetDimensions?.webViewWidth} + title="Onramper widget" + allow="accelerometer; autoplay; camera; gyroscope; payment" + /> + + {isMobile && } + + ) +} diff --git a/src/components/CustomGdOnramperWidget/index.ts b/src/components/CustomGdOnramperWidget/index.ts new file mode 100644 index 000000000..ab5a2b2bd --- /dev/null +++ b/src/components/CustomGdOnramperWidget/index.ts @@ -0,0 +1 @@ +export { CustomGdOnramperWidget } from './CustomGdOnramperWidget' diff --git a/src/language/locales/af/catalog.po b/src/language/locales/af/catalog.po index a6fadfb18..fb1f78e89 100644 --- a/src/language/locales/af/catalog.po +++ b/src/language/locales/af/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Verander" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "Sukses!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ar/catalog.po b/src/language/locales/ar/catalog.po index 696a64aae..534537d89 100644 --- a/src/language/locales/ar/catalog.po +++ b/src/language/locales/ar/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "تغيير" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "النجاح!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ca/catalog.po b/src/language/locales/ca/catalog.po index 6db0d4b3b..87e551986 100644 --- a/src/language/locales/ca/catalog.po +++ b/src/language/locales/ca/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/cs/catalog.po b/src/language/locales/cs/catalog.po index 2e7408a57..13e84d1e6 100644 --- a/src/language/locales/cs/catalog.po +++ b/src/language/locales/cs/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/da/catalog.po b/src/language/locales/da/catalog.po index 9d47af878..2503e4ba8 100644 --- a/src/language/locales/da/catalog.po +++ b/src/language/locales/da/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/de/catalog.po b/src/language/locales/de/catalog.po index 70f46c3fb..6d1c7f3ed 100644 --- a/src/language/locales/de/catalog.po +++ b/src/language/locales/de/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Ändern" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "Ab 1.0 steigt Ihr Multiplikator nach einem Monat nach einem Monat zum Ve msgid "Success!" msgstr "Erfolg!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/el/catalog.po b/src/language/locales/el/catalog.po index 508db7aee..66b56aef9 100644 --- a/src/language/locales/el/catalog.po +++ b/src/language/locales/el/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/en/catalog.po b/src/language/locales/en/catalog.po index 63421a014..8e572f95d 100644 --- a/src/language/locales/en/catalog.po +++ b/src/language/locales/en/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/es-419/catalog.po b/src/language/locales/es-419/catalog.po index 891a8a53c..81e15d8b8 100644 --- a/src/language/locales/es-419/catalog.po +++ b/src/language/locales/es-419/catalog.po @@ -134,7 +134,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -646,7 +646,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/es/catalog.po b/src/language/locales/es/catalog.po index 6be0282f2..54a60fff0 100644 --- a/src/language/locales/es/catalog.po +++ b/src/language/locales/es/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Cambio" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "A partir de 1.0, su multiplicador aumentará a 2.0 después de un mes de msgid "Success!" msgstr "¡Éxito!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/fi/catalog.po b/src/language/locales/fi/catalog.po index fb7e9e6c5..097158e9c 100644 --- a/src/language/locales/fi/catalog.po +++ b/src/language/locales/fi/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/fr/catalog.po b/src/language/locales/fr/catalog.po index 1717f27f1..843a01cf5 100644 --- a/src/language/locales/fr/catalog.po +++ b/src/language/locales/fr/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/he/catalog.po b/src/language/locales/he/catalog.po index 95175a3cc..d1f11c2c4 100644 --- a/src/language/locales/he/catalog.po +++ b/src/language/locales/he/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "שינוי" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "החל מ 1.0, מכפיל שלך יגדל ל 2.0 לאחר חודש אח msgid "Success!" msgstr "הַצלָחָה!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/hi/catalog.po b/src/language/locales/hi/catalog.po index 558a44b8d..026a24d74 100644 --- a/src/language/locales/hi/catalog.po +++ b/src/language/locales/hi/catalog.po @@ -1527,7 +1527,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -2069,7 +2069,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/hu/catalog.po b/src/language/locales/hu/catalog.po index fe7e5631b..9e8dd70f7 100644 --- a/src/language/locales/hu/catalog.po +++ b/src/language/locales/hu/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/it/catalog.po b/src/language/locales/it/catalog.po index f483de6e8..f5db41060 100644 --- a/src/language/locales/it/catalog.po +++ b/src/language/locales/it/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Modificare" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "A partire da 1,0, il tuo moltiplicatore aumenterà fino a 2.0 dopo un me msgid "Success!" msgstr "Successo!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ja/catalog.po b/src/language/locales/ja/catalog.po index 10b3c6847..35bd1b289 100644 --- a/src/language/locales/ja/catalog.po +++ b/src/language/locales/ja/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ko/catalog.po b/src/language/locales/ko/catalog.po index a8e9df18e..4f2bd053b 100644 --- a/src/language/locales/ko/catalog.po +++ b/src/language/locales/ko/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/nl/catalog.po b/src/language/locales/nl/catalog.po index 855e6fad0..10bf2f787 100644 --- a/src/language/locales/nl/catalog.po +++ b/src/language/locales/nl/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/no/catalog.po b/src/language/locales/no/catalog.po index 3c3ba563b..9d017688d 100644 --- a/src/language/locales/no/catalog.po +++ b/src/language/locales/no/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/pl/catalog.po b/src/language/locales/pl/catalog.po index 685050902..a275dc8e5 100644 --- a/src/language/locales/pl/catalog.po +++ b/src/language/locales/pl/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/pt-BR/catalog.po b/src/language/locales/pt-BR/catalog.po index 8b8e2af53..26b6144d3 100644 --- a/src/language/locales/pt-BR/catalog.po +++ b/src/language/locales/pt-BR/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/pt/catalog.po b/src/language/locales/pt/catalog.po index 05ce94829..1c32b8b66 100644 --- a/src/language/locales/pt/catalog.po +++ b/src/language/locales/pt/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ro/catalog.po b/src/language/locales/ro/catalog.po index b1856b8b3..3ed7c6200 100644 --- a/src/language/locales/ro/catalog.po +++ b/src/language/locales/ro/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Schimbare" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "Începând cu 1.0, multiplicatorul dvs. va crește la 2.0 după o lună msgid "Success!" msgstr "Succes!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/ru/catalog.po b/src/language/locales/ru/catalog.po index d3dd7aa7c..9e96bbba0 100644 --- a/src/language/locales/ru/catalog.po +++ b/src/language/locales/ru/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Изменять" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "Начиная с 1.0, ваш множитель увеличится д msgid "Success!" msgstr "Успех!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/sr/catalog.po b/src/language/locales/sr/catalog.po index f210930f3..1145dd1d8 100644 --- a/src/language/locales/sr/catalog.po +++ b/src/language/locales/sr/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/sv/catalog.po b/src/language/locales/sv/catalog.po index 2819ae77b..3519fc12d 100644 --- a/src/language/locales/sv/catalog.po +++ b/src/language/locales/sv/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/tr/catalog.po b/src/language/locales/tr/catalog.po index 254aeb70a..393e28a0f 100644 --- a/src/language/locales/tr/catalog.po +++ b/src/language/locales/tr/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/uk/catalog.po b/src/language/locales/uk/catalog.po index a52fe3cb2..904639c85 100644 --- a/src/language/locales/uk/catalog.po +++ b/src/language/locales/uk/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/vi/catalog.po b/src/language/locales/vi/catalog.po index 699e8e673..bda52ef85 100644 --- a/src/language/locales/vi/catalog.po +++ b/src/language/locales/vi/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "Thay đổi" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "Bắt đầu từ 1.0, hệ số nhân của bạn sẽ tăng lên 2.0 s msgid "Success!" msgstr "Sự thành công!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/zh-CN/catalog.po b/src/language/locales/zh-CN/catalog.po index f9588ed37..265e8ee89 100644 --- a/src/language/locales/zh-CN/catalog.po +++ b/src/language/locales/zh-CN/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "改变" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "从1.0开始,您的乘数将增加到2.0,在一个月的绑定到信 msgid "Success!" msgstr "成功!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/zh-TW/catalog.po b/src/language/locales/zh-TW/catalog.po index 66b576979..79909261d 100644 --- a/src/language/locales/zh-TW/catalog.po +++ b/src/language/locales/zh-TW/catalog.po @@ -2772,7 +2772,7 @@ msgstr "" msgid "Change" msgstr "改變" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -3314,7 +3314,7 @@ msgstr "從1.0開始,您的乘數將增加到2.0,在一個月的綁定到信 msgid "Success!" msgstr "成功!" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/language/locales/zh/catalog.po b/src/language/locales/zh/catalog.po index 379bae351..526d05054 100644 --- a/src/language/locales/zh/catalog.po +++ b/src/language/locales/zh/catalog.po @@ -2243,7 +2243,7 @@ msgstr "" msgid "Change" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:84 +#: src/pages/gd/BuyGD/index.tsx:113 msgid "Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$." msgstr "" @@ -2785,7 +2785,7 @@ msgstr "" msgid "Success!" msgstr "" -#: src/pages/gd/BuyGD/index.tsx:71 +#: src/pages/gd/BuyGD/index.tsx:100 msgid "Support global financial inclusion and contribute to social impact by purchasing GoodDollars (G$)." msgstr "" diff --git a/src/pages/gd/BuyGD/BuyGD.css b/src/pages/gd/BuyGD/BuyGD.css new file mode 100644 index 000000000..dbf429fac --- /dev/null +++ b/src/pages/gd/BuyGD/BuyGD.css @@ -0,0 +1,44 @@ +/* Ensure our custom progress bar is always visible and properly styled */ +[data-testid="custom-progress-bar"] { + display: block !important; + visibility: visible !important; + z-index: 1000; +} + +/* Style the onramper widget container */ +.onramper-widget-container { + width: 100%; + display: flex; + justify-content: center; +} + +/* Hide the built-in Onramper progress bar/stepper */ +iframe[title="Onramper widget"] { + /* Target elements inside the Onramper iframe */ +} + +/* Alternative approach - hide progress elements by common selectors */ +.progress-bar, +.stepper, +.steps-container, +[class*="progress"], +[class*="stepper"], +[class*="step"] { + display: none !important; +} + +/* More specific targeting for Onramper built-in progress elements - using broader compatibility selectors */ +div[style*="justify-content: space-between"] div, +div[style*="flex-direction: row"] div, +div[style*="display: flex"] div { + /* Target potential progress elements - may need refinement based on actual Onramper structure */ +} + +/* Hide elements containing specific text using data attributes or classes if available */ +[data-step="1"], +[data-step="2"], +[data-step="3"], +.onramper-step, +.onramper-progress { + display: none !important; +} \ No newline at end of file diff --git a/src/pages/gd/BuyGD/index.tsx b/src/pages/gd/BuyGD/index.tsx index 4a644d658..536106c98 100644 --- a/src/pages/gd/BuyGD/index.tsx +++ b/src/pages/gd/BuyGD/index.tsx @@ -1,12 +1,15 @@ -import React, { memo, useCallback } from 'react' +import { memo, useCallback, useState } from 'react' import { i18n } from '@lingui/core' import { t } from '@lingui/macro' -import { Converter, GdOnramperWidget, SlideDownTab } from '@gooddollar/good-design' +import { Converter, SlideDownTab } from '@gooddollar/good-design' import { Box, Text, useBreakpointValue } from 'native-base' -import { useG$Price, useGetEnvChainId } from '@gooddollar/web3sdk-v2' +import { useG$Price } from '@gooddollar/web3sdk-v2' import useSendAnalyticsData from 'hooks/useSendAnalyticsData' import { PageLayout } from 'components/Layout/PageLayout' +import { CustomGdOnramperWidget } from 'components/CustomGdOnramperWidget' +import { BuyProgressBar } from 'components/BuyProgressBar' +import './BuyGD.css' const CalculatorTab = () => { const G$Price = useG$Price(3) @@ -19,7 +22,9 @@ const CalculatorTab = () => { titleFont: { fontSize: 'l', fontFamily: 'heading', fontWeight: '700', paddingLeft: 2 }, }} > - + + + ) } @@ -27,12 +32,45 @@ const CalculatorTab = () => { const BuyGd = memo(() => { const sendData = useSendAnalyticsData() - const { connectedEnv } = useGetEnvChainId(42220) - const isProd = connectedEnv.includes('production') + // Batch state updates for better performance + const [buyState, setBuyState] = useState({ currentStep: 1 as 1 | 2 | 3, isLoading: false }) + const { currentStep, isLoading } = buyState const handleEvents = useCallback( (event: string, data?: any, error?: string) => { - sendData({ event: 'buy', action: event, ...(error && { error: error }) }) + const eventData: any = { event: 'buy', action: event } + if (data) eventData.data = data + if (error) eventData.error = error + sendData(eventData) + + switch (event) { + case 'widget_clicked': + case 'widget_opened': + setBuyState({ currentStep: 1, isLoading: true }) + break + case 'transaction_started': + setBuyState({ currentStep: 1, isLoading: true }) + break + case 'funds_received': + setBuyState({ currentStep: 2, isLoading: false }) + break + case 'transaction_sent': + case 'swap_started': + setBuyState({ currentStep: 2, isLoading: true }) + break + case 'swap_completed': + case 'transaction_completed': + setBuyState({ currentStep: 3, isLoading: false }) + break + case 'error': + setBuyState((prev) => ({ ...prev, isLoading: false })) + break + case 'reset': + setBuyState({ currentStep: 1, isLoading: false }) + break + default: + break + } }, [sendData] ) @@ -47,17 +85,8 @@ const BuyGd = memo(() => { }, }) - const onrampWrapper = useBreakpointValue({ - base: { - width: '110%', - }, - lg: { - width: '100%', - }, - }) - return ( - ]}> + ]}> { mb={6} > {i18n._( - t` - Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$.` + t`Choose the currency you want to use and buy cUSD. Your cUSD is then automatically converted into G$.` )} + + + {/* todo: width on mobile should be more responsive */} - - - + ) })