Skip to content

Commit

Permalink
feat: add swap route card draft
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov committed Apr 14, 2022
1 parent 2462ca8 commit 14df8c3
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<SwapFormTypeProps> = ({
Expand Down Expand Up @@ -92,8 +92,8 @@ const SwapPrice: React.FC<SwapFormTypeProps & { price?: string }> = ({

return (
<SwapPriceTypography variant="body2" color="text.secondary">
{t(`swap.price`, {
price: formatTokenPrice(value, price),
{t(`swap.approximateCurrency`, {
value: formatTokenPrice(value, price),
})}
</SwapPriceTypography>
);
Expand Down
218 changes: 126 additions & 92 deletions packages/widget/src/components/SwapRoute/SwapRoute.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 (
<Box
sx={{
py: 8,
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<AnimatedWaitIcon />
<Typography variant="subtitle1" color="text.primary">
{t('swap.requestingRoutes')}
</Typography>
</Box>
// <Box
// sx={{
// py: 8,
// width: '100%',
// display: 'flex',
// justifyContent: 'center',
// alignItems: 'center',
// }}
// >
// <AnimatedWaitIcon />
// <Typography variant="subtitle1" color="text.primary">
// {t('swap.requestingRoutes')}
// </Typography>
// </Box>
<Stack direction="row" sx={{ padding: '0 0 24px' }} spacing={2}>
<Skeleton
variant="rectangular"
width={200}
height={195}
sx={{ borderRadius: 1 }}
/>
</Stack>
);
};

Expand All @@ -51,82 +70,97 @@ export const SwapRoute: React.FC = () => {
};

const renderRouteDisplay = (route: Route) => (
<Box
py={2}
sx={{
display: 'flex',
flexDirection: 'column',
flex: 1,
justifyContent: 'flex-end',
}}
>
<SwapStepper
steps={[
{
label: route.fromToken.symbol,
sublabel: getChainById(route.fromChainId)!.name,
},
...route.steps.map((step) => {
return { label: parsedStepTypes[step.type], sublabel: step.tool };
}),
{
label: route.toToken.symbol,
sublabel: getChainById(route.toChainId)!.name,
},
]}
// <Box
// py={2}
// sx={{
// display: 'flex',
// flexDirection: 'column',
// flex: 1,
// justifyContent: 'flex-end',
// }}
// >
// <SwapStepper
// steps={[
// {
// label: route.fromToken.symbol,
// sublabel: getChainById(route.fromChainId)!.name,
// },
// ...route.steps.map((step) => {
// return { label: parsedStepTypes[step.type], sublabel: step.tool };
// }),
// {
// label: route.toToken.symbol,
// sublabel: getChainById(route.toChainId)!.name,
// },
// ]}
// />
// <Box
// mt={2}
// sx={{
// display: 'flex',
// justifyContent: 'space-between',
// alignItems: 'center',
// }}
// >
// <Typography
// variant="subtitle1"
// color="text.secondary"
// sx={{ alignSelf: 'end' }}
// >
// {t(`swap.gas`)}
// </Typography>
// <Typography
// ml={2}
// variant="subtitle1"
// color="text.primary"
// sx={{ alignSelf: 'end' }}
// >
// {t(`swap.approximateCurrency`, { value: route.gasCostUSD })}
// </Typography>
// </Box>
// <Box
// sx={{
// display: 'flex',
// justifyContent: 'space-between',
// alignItems: 'center',
// }}
// >
// <Typography
// variant="subtitle1"
// color="text.secondary"
// sx={{ alignSelf: 'end' }}
// >
// {t(`swap.minutes`)}
// </Typography>
// <Typography
// ml={2}
// variant="subtitle1"
// color="text.primary"
// sx={{ alignSelf: 'end' }}
// >
// {`${(
// route.steps
// .map((step) => step.estimate.executionDuration)
// .reduce((cumulated, x) => cumulated + x) / 60
// ).toFixed(1)} min`}
// </Typography>
// </Box>
// </Box>
<Stack direction="row" sx={{ padding: '0 0 24px' }} spacing={2}>
<SwapRouteCard
width={200}
amount={formatTokenAmount(route.toAmount, route.toToken.decimals)}
token={route.toToken.name}
gas={t(`swap.currency`, { value: route.gasCostUSD })}
time={(
route.steps
.map((step) => step.estimate.executionDuration)
.reduce((cumulated, x) => cumulated + x) / 60
).toFixed(0)}
type="recommended"
active
/>
<Box
mt={2}
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Typography
variant="subtitle1"
color="text.secondary"
sx={{ alignSelf: 'end' }}
>
{t(`swap.gas`)}
</Typography>
<Typography
ml={2}
variant="subtitle1"
color="text.primary"
sx={{ alignSelf: 'end' }}
>
{t(`swap.price`, { price: route.gasCostUSD })}
</Typography>
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Typography
variant="subtitle1"
color="text.secondary"
sx={{ alignSelf: 'end' }}
>
{t(`swap.waitingTime`)}
</Typography>
<Typography
ml={2}
variant="subtitle1"
color="text.primary"
sx={{ alignSelf: 'end' }}
>
{`${(
route.steps
.map((step) => step.estimate.executionDuration)
.reduce((cumulated, x) => cumulated + x) / 60
).toFixed(1)} min`}
</Typography>
</Box>
</Box>
</Stack>
);

if (routes && routes.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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',
}));
53 changes: 53 additions & 0 deletions packages/widget/src/components/SwapRouteCard/SwapRouteCard.tsx
Original file line number Diff line number Diff line change
@@ -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<SwapRouteCardProps & BoxProps> = ({
amount,
token,
time,
gas,
active,
type,
...other
}) => {
const { t } = useTranslation();
return (
<Card active={active} {...other}>
<Label active={active} mb={2}>
{type}
</Label>
<Typography fontSize={32} fontWeight="bold" lineHeight="normal">
{amount}
</Typography>
<Typography fontSize={14} mb={2} color="text.secondary">
{token}
</Typography>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<Box>
<Typography fontSize={18} fontWeight="500">
{gas}
</Typography>
<Typography fontSize={12} color="text.secondary">
{t(`swap.gas`)}
</Typography>
</Box>
<Box>
<Typography fontSize={18} fontWeight="500">
~{time}
</Typography>
<Typography fontSize={12} color="text.secondary">
{t(`swap.minutes`)}
</Typography>
</Box>
</Box>
</Card>
);
};
1 change: 1 addition & 0 deletions packages/widget/src/components/SwapRouteCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SwapRouteCard';
8 changes: 8 additions & 0 deletions packages/widget/src/components/SwapRouteCard/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface SwapRouteCardProps {
amount: string | number;
token: string;
time: string;
gas: string;
type: 'recommended' | 'fastest' | 'cheapest';
active?: boolean;
}
7 changes: 4 additions & 3 deletions packages/widget/src/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading

0 comments on commit 14df8c3

Please sign in to comment.