Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -528,6 +529,16 @@ function BuyScreenContent(props: BuyScreenContentProps) {
screen.id === "buy-with-fiat") &&
payer && (
<TokenSelectedLayout
isBuyWithFiatEnabled={enabledPaymentMethods.buyWithFiatEnabled}
isBuyWithCryptoEnabled={
enabledPaymentMethods.buyWithCryptoEnabled
}
mode={screen.id === "buy-with-fiat" ? "buy" : "swap"}
onModeChange={(mode) => {
setScreen({
id: mode === "swap" ? "buy-with-crypto" : "buy-with-fiat",
});
}}
disabled={
("prefillBuy" in payOptions &&
payOptions.prefillBuy?.allowEdits?.amount === false) ||
Expand All @@ -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" && (
<PaymentSelectionScreen
client={client}
mode={payOptions.mode}
sourceSupportedTokens={sourceSupportedTokens}
hiddenWallets={props.hiddenWallets}
payWithFiatEnabled={props.payOptions.buyWithFiat !== false}
toChain={toChain}
toToken={toToken}
fromToken={fromToken}
fromChain={fromChain}
tokenAmount={tokenAmount}
onContinue={() => {
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 && (
<SwapScreenContent
setScreen={setScreen}
Expand Down Expand Up @@ -842,7 +802,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" });
}
}}
/>
Expand All @@ -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" });
}
}}
/>
Expand Down Expand Up @@ -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" });
}
}}
>
Expand All @@ -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 (
<Container>
<Container p="lg">
Expand All @@ -975,12 +940,77 @@ function TokenSelectedLayout(props: {
disabled={props.disabled}
/>

<Spacer y="md" />
<Line />
<Spacer y="lg" />
<Container flex="row" gap="md" center="y">
<Text size="sm"> Pay with </Text>
{props.isBuyWithFiatEnabled && props.isBuyWithCryptoEnabled && (
<Container
flex="row"
style={{
flex: 1,
justifyContent: "center",
borderRadius: radius.xl,
border: `1px solid ${theme.colors.borderColor}`,
alignItems: "stretch",
}}
>
<Button
variant="ghost"
style={{
flex: 1,
background:
props.mode === "swap"
? theme.colors.tertiaryBg
: "transparent",
borderRadius: radius.xl,
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
padding: spacing.xs,
}}
onClick={() => props.onModeChange("swap")}
>
<Text
size="sm"
color={
props.mode === "swap" ? "primaryText" : "secondaryText"
}
>
Crypto
</Text>
</Button>
<div
style={{
width: "1px",
background: theme.colors.borderColor,
}}
/>
<Button
variant="ghost"
style={{
flex: 1,
background:
props.mode === "buy"
? theme.colors.tertiaryBg
: "transparent",
borderRadius: radius.xl,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
padding: spacing.xs,
}}
onClick={() => props.onModeChange("buy")}
>
<Text
size="sm"
color={props.mode === "buy" ? "primaryText" : "secondaryText"}
>
Card
</Text>
</Button>
</Container>
)}
</Container>

<Text size="sm"> Pay with </Text>
<Spacer y="sm" />
<Spacer y="lg" />

{props.children}
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ export function PayWithCreditCard(props: {
<Skeleton width="100px" height={fontSize.lg} />
) : (
<Text size="lg" color={props.value ? "primaryText" : "secondaryText"}>
{props.value ? `${formatNumber(Number(props.value), 6)}` : "--"}
{props.value
? `${props.currency.symbol}${formatNumber(
Number(props.value),
6,
)}`
: "--"}
</Text>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export function FiatScreenContent(props: {
: undefined;

return (
<Container flex="column" gap="md" animate="fadein">
<Container flex="column" gap="lg" animate="fadein">
{isOpen && (
<>
<DrawerOverlay ref={drawerOverlayRef} />
Expand Down Expand Up @@ -198,74 +198,75 @@ export function FiatScreenContent(props: {
</>
)}

<div>
<PayWithCreditCard
isLoading={fiatQuoteQuery.isLoading}
value={fiatQuoteQuery.data?.fromCurrencyWithFees.amount}
client={client}
currency={selectedCurrency}
onSelectCurrency={showCurrencySelector}
/>
<Container
bg="tertiaryBg"
flex="row"
borderColor="borderColor"
style={{
paddingLeft: spacing.md,
justifyContent: "space-between",
alignItems: "center",
borderWidth: "1px",
borderStyle: "solid",
borderBottom: "none",
}}
>
<Text size="xs" color="secondaryText">
Provider
</Text>
<Button variant="ghost" onClick={showProviders}>
<Container flex="row" center="y" gap="xxs" color="secondaryText">
<Text size="xs">
{preferredProvider
? `${preferredProvider.charAt(0).toUpperCase() + preferredProvider.slice(1).toLowerCase()}`
: fiatQuoteQuery.data?.provider
? `${fiatQuoteQuery.data?.provider.charAt(0).toUpperCase() + fiatQuoteQuery.data?.provider.slice(1).toLowerCase()}`
: ""}
</Text>
<ChevronDownIcon width={iconSize.sm} height={iconSize.sm} />
</Container>
</Button>
</Container>
{/* Estimated time + View fees button */}
<EstimatedTimeAndFees
quoteIsLoading={fiatQuoteQuery.isLoading}
estimatedSeconds={fiatQuoteQuery.data?.estimatedDurationSeconds}
onViewFees={showFees}
/>
<Spacer y="md" />
</div>

{/* Error message */}
{errorMsg && (
<Container flex="column" gap="sm">
<div>
{errorMsg.data?.minimumAmountEth ? (
<Text color="danger" size="sm" center multiline>
Minimum amount is{" "}
{formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "}
<TokenSymbol
token={toToken}
chain={toChain}
size="sm"
inline
color="danger"
/>
<PayWithCreditCard
isLoading={fiatQuoteQuery.isLoading}
value={fiatQuoteQuery.data?.fromCurrencyWithFees.amount}
client={client}
currency={selectedCurrency}
onSelectCurrency={showCurrencySelector}
/>
<Container
bg="tertiaryBg"
flex="row"
borderColor="borderColor"
style={{
paddingLeft: spacing.md,
justifyContent: "space-between",
alignItems: "center",
borderWidth: "1px",
borderStyle: "solid",
borderBottom: "none",
}}
>
<Text size="xs" color="secondaryText">
Provider
</Text>
) : (
<Text color="danger" size="sm" center multiline>
{errorMsg.message || defaultMessage}
</Text>
)}
<Button variant="ghost" onClick={showProviders}>
<Container flex="row" center="y" gap="xxs" color="secondaryText">
<Text size="xs">
{preferredProvider
? `${preferredProvider.charAt(0).toUpperCase() + preferredProvider.slice(1).toLowerCase()}`
: fiatQuoteQuery.data?.provider
? `${fiatQuoteQuery.data?.provider.charAt(0).toUpperCase() + fiatQuoteQuery.data?.provider.slice(1).toLowerCase()}`
: ""}
</Text>
<ChevronDownIcon width={iconSize.sm} height={iconSize.sm} />
</Container>
</Button>
</Container>
{/* Estimated time + View fees button */}
<EstimatedTimeAndFees
quoteIsLoading={fiatQuoteQuery.isLoading}
estimatedSeconds={fiatQuoteQuery.data?.estimatedDurationSeconds}
onViewFees={showFees}
/>
</div>
)}

{/* Error message */}
{errorMsg && (
<div>
{errorMsg.data?.minimumAmountEth ? (
<Text color="danger" size="sm" center multiline>
Minimum amount is{" "}
{formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "}
<TokenSymbol
token={toToken}
chain={toChain}
size="sm"
inline
color="danger"
/>
</Text>
) : (
<Text color="danger" size="sm" center multiline>
{errorMsg.message || defaultMessage}
</Text>
)}
</div>
)}
</Container>

{errorMsg?.data?.minimumAmountEth ? (
<Button
Expand Down
Loading
Loading