diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx index c497c29ce0f..507fb089f88 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx @@ -8,9 +8,11 @@ import type { BuyWithFiatStatus } from "../../../../../../pay/buyWithFiat/getSta import { formatNumber } from "../../../../../../utils/formatNumber.js"; import type { Account } from "../../../../../../wallets/interfaces/wallet.js"; import type { WalletId } from "../../../../../../wallets/wallet-types.js"; +import { useCustomTheme } from "../../../../../core/design-system/CustomThemeProvider.js"; import { type Theme, fontSize, + radius, spacing, } from "../../../../../core/design-system/index.js"; import type { @@ -25,7 +27,7 @@ import { LoadingScreen } from "../../../../wallets/shared/LoadingScreen.js"; import type { PayEmbedConnectOptions } from "../../../PayEmbed.js"; import { ChainName } from "../../../components/ChainName.js"; import { Spacer } from "../../../components/Spacer.js"; -import { Container, Line, ModalHeader } from "../../../components/basic.js"; +import { Container, ModalHeader } from "../../../components/basic.js"; import { Button } from "../../../components/buttons.js"; import { Input } from "../../../components/formElements.js"; import { Text } from "../../../components/text.js"; @@ -54,7 +56,6 @@ import { } from "./main/useUISelectionStates.js"; import { BuyTokenInput } from "./swap/BuyTokenInput.js"; import { FiatValue } from "./swap/FiatValue.js"; -import { PaymentSelectionScreen } from "./swap/PaymentSelectionScreen.js"; import { SwapFlow } from "./swap/SwapFlow.js"; import { SwapScreenContent } from "./swap/SwapScreenContent.js"; import { TokenSelectorScreen } from "./swap/TokenSelectorScreen.js"; @@ -528,6 +529,16 @@ function BuyScreenContent(props: BuyScreenContentProps) { screen.id === "buy-with-fiat") && payer && ( { + setScreen({ + id: mode === "swap" ? "buy-with-crypto" : "buy-with-fiat", + }); + }} disabled={ ("prefillBuy" in payOptions && payOptions.prefillBuy?.allowEdits?.amount === false) || @@ -540,60 +551,9 @@ function BuyScreenContent(props: BuyScreenContentProps) { setTokenAmount={setTokenAmount} client={client} onBack={() => { - if ( - enabledPaymentMethods.buyWithCryptoEnabled && - screen.id === "buy-with-fiat" - ) { - setScreen({ id: "select-payment-method" }); - } else if (screen.id === "buy-with-crypto") { - setScreen({ id: "select-payment-method" }); - } else { - setScreen({ id: "main" }); - } + setScreen({ id: "main" }); }} > - {screen.id === "select-payment-method" && ( - { - setScreen({ id: "buy-with-crypto" }); - }} - onSelectFiat={() => { - setScreen({ id: "buy-with-fiat" }); - }} - onPickToken={() => { - setScreen({ - id: "select-from-token", - backScreen: { - id: "select-payment-method", - }, - }); - }} - showAllWallets={!!props.connectOptions?.showAllWallets} - wallets={props.connectOptions?.wallets} - onBack={() => { - // no-op - }} - onConnect={() => { - setScreen({ - id: "connect-payer-wallet", - backScreen: { - id: "select-payment-method", - }, - }); - }} - /> - )} - {screen.id === "buy-with-crypto" && activeAccount && ( @@ -865,7 +825,7 @@ function MainScreen(props: { if (buyWithFiatEnabled && !buyWithCryptoEnabled) { props.setScreen({ id: "buy-with-fiat" }); } else { - props.setScreen({ id: "select-payment-method" }); + props.setScreen({ id: "buy-with-crypto" }); } }} /> @@ -928,7 +888,7 @@ function MainScreen(props: { if (buyWithFiatEnabled && !buyWithCryptoEnabled) { props.setScreen({ id: "buy-with-fiat" }); } else { - props.setScreen({ id: "select-payment-method" }); + props.setScreen({ id: "buy-with-crypto" }); } }} > @@ -952,7 +912,12 @@ function TokenSelectedLayout(props: { client: ThirdwebClient; onBack: () => void; disabled?: boolean; + mode: "buy" | "swap"; + onModeChange: (mode: "buy" | "swap") => void; + isBuyWithFiatEnabled: boolean; + isBuyWithCryptoEnabled: boolean; }) { + const theme = useCustomTheme(); return ( @@ -975,12 +940,77 @@ function TokenSelectedLayout(props: { disabled={props.disabled} /> - - + + Pay with + {props.isBuyWithFiatEnabled && props.isBuyWithCryptoEnabled && ( + + +
+ + + )} + - Pay with - + {props.children} diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx index e128dc3c779..78a92741aa4 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx @@ -82,7 +82,12 @@ export function PayWithCreditCard(props: { ) : ( - {props.value ? `${formatNumber(Number(props.value), 6)}` : "--"} + {props.value + ? `${props.currency.symbol}${formatNumber( + Number(props.value), + 6, + )}` + : "--"} )}
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx index 0458626ef90..6447e65958c 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx @@ -157,7 +157,7 @@ export function FiatScreenContent(props: { : undefined; return ( - + {isOpen && ( <> @@ -198,74 +198,75 @@ export function FiatScreenContent(props: { )} -
- - - - Provider - - - - {/* Estimated time + View fees button */} - - -
- - {/* Error message */} - {errorMsg && ( +
- {errorMsg.data?.minimumAmountEth ? ( - - Minimum amount is{" "} - {formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "} - + + + + Provider - ) : ( - - {errorMsg.message || defaultMessage} - - )} + + + {/* Estimated time + View fees button */} +
- )} + + {/* Error message */} + {errorMsg && ( +
+ {errorMsg.data?.minimumAmountEth ? ( + + Minimum amount is{" "} + {formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "} + + + ) : ( + + {errorMsg.message || defaultMessage} + + )} +
+ )} +
{errorMsg?.data?.minimumAmountEth ? ( - - - - {props.payWithFiatEnabled && ( - - )} -
- -
- ); -} diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx index 851b1f2b955..0c954b4fe48 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx @@ -220,7 +220,7 @@ export function SwapScreenContent(props: { } return ( - + {isOpen && ( <> @@ -239,62 +239,60 @@ export function SwapScreenContent(props: { )} {/* Quote info */} -
- - {swapRequired && ( - - )} - -
- - {/* Error message */} - {errorMsg && ( +
- {errorMsg.data?.minimumAmountEth ? ( - - Minimum amount is{" "} - {formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "} - - - ) : ( - - {errorMsg.message || defaultMessage} - + + {swapRequired && ( + )}
- )} + {/* Error message */} + {errorMsg && ( +
+ {errorMsg.data?.minimumAmountEth ? ( + + Minimum amount is{" "} + {formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "} + + + ) : ( + + {errorMsg.message || defaultMessage} + + )} +
+ )} - {!errorMsg && isNotEnoughBalance && ( -
- - Not enough funds. - - - Try a different wallet or token. - -
- )} + {!errorMsg && isNotEnoughBalance && ( +
+ + Not enough funds. + +
+ )} +
{/* Button */} {errorMsg?.data?.minimumAmountEth ? ( @@ -313,6 +311,14 @@ export function SwapScreenContent(props: { > Set Minimum + ) : isNotEnoughBalance || errorMsg ? ( + ) : switchChainRequired && !quoteQuery.isLoading && !allowanceQuery.isLoading && diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx index 3bb9118b64b..853576cc1de 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx @@ -6,7 +6,10 @@ import type { ThirdwebClient } from "../../../../../../../client/client.js"; import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js"; import { shortenAddress } from "../../../../../../../utils/address.js"; import type { Wallet } from "../../../../../../../wallets/interfaces/wallet.js"; -import { getWalletBalance } from "../../../../../../../wallets/utils/getWalletBalance.js"; +import { + type GetWalletBalanceResult, + getWalletBalance, +} from "../../../../../../../wallets/utils/getWalletBalance.js"; import type { WalletId } from "../../../../../../../wallets/wallet-types.js"; import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js"; import { @@ -44,7 +47,12 @@ import type { ConnectLocale } from "../../../locale/types.js"; import { formatTokenBalance } from "../../formatTokenBalance.js"; import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js"; import { FiatValue } from "./FiatValue.js"; -import type { TokenBalance } from "./PaymentSelectionScreen.js"; + +type TokenBalance = { + balance: GetWalletBalanceResult; + chain: Chain; + token: TokenInfo; +}; export function TokenSelectorScreen(props: { client: ThirdwebClient; diff --git a/packages/thirdweb/src/react/web/ui/components/token/TokenRow.tsx b/packages/thirdweb/src/react/web/ui/components/token/TokenRow.tsx index d9ec116e61b..c96dba4dd44 100644 --- a/packages/thirdweb/src/react/web/ui/components/token/TokenRow.tsx +++ b/packages/thirdweb/src/react/web/ui/components/token/TokenRow.tsx @@ -2,6 +2,7 @@ import styled from "@emotion/styled"; import { ChevronDownIcon } from "@radix-ui/react-icons"; import type { Chain } from "../../../../../chains/types.js"; import type { ThirdwebClient } from "../../../../../client/client.js"; +import { formatNumber } from "../../../../../utils/formatNumber.js"; import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js"; import { fontSize, @@ -23,6 +24,9 @@ export function TokenRow(props: { client: ThirdwebClient; onSelectToken: () => void; freezeChainAndToken?: boolean; + value?: string; + isLoading?: boolean; + style?: React.CSSProperties; }) { const { name } = useChainName(props.chain); return ( @@ -31,6 +35,7 @@ export function TokenRow(props: { fullWidth style={{ fontSize: fontSize.sm, + ...props.style, }} gap="xxs" onClick={props.onSelectToken} @@ -51,7 +56,31 @@ export function TokenRow(props: { }} > {/* Token Symbol */} - + + {props.isLoading ? ( + + ) : props.value ? ( + + + {formatNumber(Number(props.value), 6) || ""} + + + + ) : ( + + )} + {/* Network Name */} {name ? ( @@ -63,14 +92,9 @@ export function TokenRow(props: { )}
- - + + + ); } @@ -80,7 +104,7 @@ const TokenButton = /* @__PURE__ */ styled(Button)(() => { return { background: theme.colors.tertiaryBg, border: `1px solid ${theme.colors.borderColor}`, - justifyContent: "flex-start", + justifyContent: "space-between", transition: "background 0.3s", padding: spacing.sm, };