diff --git a/packages/widget/src/components/SwapInputAdornment/SwapInputAdornment.tsx b/packages/widget/src/components/SwapInputAdornment/SwapInputAdornment.tsx index 451ab52a5..0a241e243 100644 --- a/packages/widget/src/components/SwapInputAdornment/SwapInputAdornment.tsx +++ b/packages/widget/src/components/SwapInputAdornment/SwapInputAdornment.tsx @@ -5,12 +5,12 @@ import { useTranslation } from 'react-i18next'; import { useTokenBalance } from '../../hooks/useTokenBalance'; import { SwapFormKeyHelper, - SwapFormTypeProps + SwapFormTypeProps, } from '../../providers/SwapFormProvider'; import { formatTokenAmount, formatTokenPrice } from '../../utils/format'; import { SwapMaxAmountTypography, - SwapPriceTypography + SwapPriceTypography, } from './SwapInputAdornment.style'; export const SwapInputAdornment: React.FC = ({ @@ -92,8 +92,8 @@ const SwapPrice: React.FC = ({ return ( - {t(`swap.price`, { - price: formatTokenPrice(value, price), + {t(`swap.approximateCurrency`, { + value: formatTokenPrice(value, price), })} ); diff --git a/packages/widget/src/components/SwapRoute/SwapRoute.tsx b/packages/widget/src/components/SwapRoute/SwapRoute.tsx index 3fd623991..1585d2ad1 100644 --- a/packages/widget/src/components/SwapRoute/SwapRoute.tsx +++ b/packages/widget/src/components/SwapRoute/SwapRoute.tsx @@ -1,9 +1,10 @@ import { Route, StepType } from '@lifinance/sdk'; -import { Box, Typography } from '@mui/material'; +import { formatTokenAmount } from '@lifinance/widget/utils/format'; +import { Box, Skeleton, Stack as MuiStack, Typography } from '@mui/material'; +import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { useChains, useSwapRoutes } from '../../hooks'; -import { SwapStepper } from '../SwapStepper'; -import { AnimatedWaitIcon } from './SwapRoute.style'; +import { SwapRouteCard } from '../SwapRouteCard'; const parsedStepTypes: { [K in StepType]: string; @@ -13,26 +14,44 @@ const parsedStepTypes: { swap: 'Dex', }; +const Stack = styled(MuiStack)(({ theme }) => ({ + alignItems: 'stretch', + display: 'flex', + flexDirection: 'row', + flexWrap: 'nowrap', + overflowX: 'auto', + overflowY: 'hidden', + padding: theme.spacing(2, 0), +})); + export const SwapRoute: React.FC = () => { const { t } = useTranslation(); const { getChainById } = useChains(); const { routes, isFetching, isFetched } = useSwapRoutes(); const renderRoutesLoading = () => { return ( - - - - {t('swap.requestingRoutes')} - - + // + // + // + // {t('swap.requestingRoutes')} + // + // + + + ); }; @@ -51,82 +70,97 @@ export const SwapRoute: React.FC = () => { }; const renderRouteDisplay = (route: Route) => ( - - { - return { label: parsedStepTypes[step.type], sublabel: step.tool }; - }), - { - label: route.toToken.symbol, - sublabel: getChainById(route.toChainId)!.name, - }, - ]} + // + // { + // return { label: parsedStepTypes[step.type], sublabel: step.tool }; + // }), + // { + // label: route.toToken.symbol, + // sublabel: getChainById(route.toChainId)!.name, + // }, + // ]} + // /> + // + // + // {t(`swap.gas`)} + // + // + // {t(`swap.approximateCurrency`, { value: route.gasCostUSD })} + // + // + // + // + // {t(`swap.minutes`)} + // + // + // {`${( + // route.steps + // .map((step) => step.estimate.executionDuration) + // .reduce((cumulated, x) => cumulated + x) / 60 + // ).toFixed(1)} min`} + // + // + // + + step.estimate.executionDuration) + .reduce((cumulated, x) => cumulated + x) / 60 + ).toFixed(0)} + type="recommended" + active /> - - - {t(`swap.gas`)} - - - {t(`swap.price`, { price: route.gasCostUSD })} - - - - - {t(`swap.waitingTime`)} - - - {`${( - route.steps - .map((step) => step.estimate.executionDuration) - .reduce((cumulated, x) => cumulated + x) / 60 - ).toFixed(1)} min`} - - - + ); if (routes && routes.length > 0) { diff --git a/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts new file mode 100644 index 000000000..42c167e94 --- /dev/null +++ b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts @@ -0,0 +1,35 @@ +import { Box } from '@mui/material'; +import { styled } from '@mui/material/styles'; + +export const Card = styled(Box, { + shouldForwardProp: (prop) => prop !== 'active', +})<{ active?: boolean }>(({ theme, active }) => ({ + padding: theme.spacing(2), + border: `2px solid ${ + active ? theme.palette.primary.main : theme.palette.grey[200] + }`, + borderRadius: theme.shape.borderRadius, + boxSizing: 'border-box', + // maxWidth: '50%', + // flexBasis: '50%', + // flexGrow: 0, + // flexShrink: 0, +})); + +export const Label = styled(Box, { + shouldForwardProp: (prop) => prop !== 'active', +})<{ active?: boolean }>(({ theme, active }) => ({ + backgroundColor: active + ? theme.palette.primary.main + : theme.palette.common.white, + border: '1px solid', + borderColor: active ? theme.palette.primary.main : theme.palette.common.black, + borderRadius: 4, + color: active ? theme.palette.common.white : theme.palette.common.black, + padding: theme.spacing(0.5, 0.75), + fontSize: 12, + fontWeight: '600', + letterSpacing: '0.05rem', + textTransform: 'uppercase', + display: 'inline-flex', +})); diff --git a/packages/widget/src/components/SwapRouteCard/SwapRouteCard.tsx b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.tsx new file mode 100644 index 000000000..2631cee9f --- /dev/null +++ b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.tsx @@ -0,0 +1,53 @@ +import { Box, BoxProps, Typography } from '@mui/material'; +import { useTranslation } from 'react-i18next'; +import { Card, Label } from './SwapRouteCard.style'; +import { SwapRouteCardProps } from './types'; + +export const SwapRouteCard: React.FC = ({ + amount, + token, + time, + gas, + active, + type, + ...other +}) => { + const { t } = useTranslation(); + return ( + + + + {amount} + + + {token} + + + + + {gas} + + + {t(`swap.gas`)} + + + + + ~{time} + + + {t(`swap.minutes`)} + + + + + ); +}; diff --git a/packages/widget/src/components/SwapRouteCard/index.ts b/packages/widget/src/components/SwapRouteCard/index.ts new file mode 100644 index 000000000..85eeb2d8f --- /dev/null +++ b/packages/widget/src/components/SwapRouteCard/index.ts @@ -0,0 +1 @@ +export * from './SwapRouteCard'; diff --git a/packages/widget/src/components/SwapRouteCard/types.ts b/packages/widget/src/components/SwapRouteCard/types.ts new file mode 100644 index 000000000..48bde1fc1 --- /dev/null +++ b/packages/widget/src/components/SwapRouteCard/types.ts @@ -0,0 +1,8 @@ +export interface SwapRouteCardProps { + amount: string | number; + token: string; + time: string; + gas: string; + type: 'recommended' | 'fastest' | 'cheapest'; + active?: boolean; +} diff --git a/packages/widget/src/i18n/en/translation.json b/packages/widget/src/i18n/en/translation.json index 4d9680a92..61f482fde 100644 --- a/packages/widget/src/i18n/en/translation.json +++ b/packages/widget/src/i18n/en/translation.json @@ -15,12 +15,13 @@ "enterAmount": "Enter amount", "max": "Max", "maxAmount": "({{amount}})", - "price": "\u2248 {{price, currency(currency: USD)}}", + "approximateCurrency": "\u2248 {{value, currency(currency: USD)}}", + "currency": "{{value, currency(currency: USD)}}", "sendToRecipient": "Send to recipient", "recipientsAddress": "Recipient's {{chain}} address", "addressConfirmation": "I confirm that the address above is correct", - "gas": "Gas:", - "waitingTime": "Waiting time:", + "gas": "gas fee", + "minutes": "mins", "tokenSearch": "Search your token", "selectChain": "Select Chain", "selectToken": "Select Token", diff --git a/packages/widget/src/pages/SwapPage/SwapPage.tsx b/packages/widget/src/pages/SwapPage/SwapPage.tsx index 1a5c28691..ea1637005 100644 --- a/packages/widget/src/pages/SwapPage/SwapPage.tsx +++ b/packages/widget/src/pages/SwapPage/SwapPage.tsx @@ -20,7 +20,6 @@ import { SwapFormKeyHelper, } from '../../providers/SwapFormProvider'; import { ElementId } from '../../utils/elements'; -import { SendToRecipientForm } from './SendToRecipientForm'; import { FormBox, FormContainer } from './SwapPage.style'; import { SwapPageProps } from './types'; @@ -56,15 +55,15 @@ export const SwapPage: React.FC = ({ settingsRef }) => { - + - + {/* */} {/* */} - + diff --git a/packages/widget/src/utils/format.ts b/packages/widget/src/utils/format.ts index 84fbd65ea..b23dd697d 100644 --- a/packages/widget/src/utils/format.ts +++ b/packages/widget/src/utils/format.ts @@ -10,9 +10,16 @@ Big.NE = -21; * @param amount amount to format. * @returns formatted amount. */ -export const formatTokenAmount = (amount: string = '0') => { - const parsedAmount = parseFloat(amount); - if (parsedAmount === 0 || isNaN(Number(amount))) { +export const formatTokenAmount = ( + amount: string = '0', + decimals: number = 0, +) => { + let shiftedAmount = amount; + if (decimals) { + shiftedAmount = (Number(amount) / 10 ** decimals).toString(); + } + const parsedAmount = parseFloat(shiftedAmount); + if (parsedAmount === 0 || isNaN(Number(shiftedAmount))) { return '0'; }