diff --git a/packages/widget/src/components/SwapRoute/SwapRoute.style.ts b/packages/widget/src/components/SwapRoute/SwapRoute.style.ts new file mode 100644 index 000000000..90b064e59 --- /dev/null +++ b/packages/widget/src/components/SwapRoute/SwapRoute.style.ts @@ -0,0 +1,20 @@ +import { WaitIcon } from '@lifinance/widget/icons/waitIcon'; +import { keyframes, styled } from '@mui/material/styles'; + +const rotationAnimation = keyframes` + 0% { + transform: rotate(0); + } + 33% { + transform: rotate(360deg); + } + 100% { + transform: rotate(360deg); + } +`; + +export const AnimatedWaitIcon = styled(WaitIcon)(() => ({ + margin: 12, + transform: 'rotate(0)', + animation: `${rotationAnimation} 3s infinite cubic-bezier(0.645, 0.045, 0.355, 1.000)`, +})); diff --git a/packages/widget/src/components/SwapRoute/SwapRoute.tsx b/packages/widget/src/components/SwapRoute/SwapRoute.tsx index 71f639447..0cc9c4b70 100644 --- a/packages/widget/src/components/SwapRoute/SwapRoute.tsx +++ b/packages/widget/src/components/SwapRoute/SwapRoute.tsx @@ -1,20 +1,71 @@ +import { getChainById, Route, StepType } from '@lifinance/sdk'; import { Box, Typography } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { useSwapRoutes } from '../../hooks/useSwapRoutes'; import { SwapStepper } from '../SwapStepper'; +import { AnimatedWaitIcon } from './SwapRoute.style'; + +const parsedStepTypes: { + [K in StepType]: string; +} = { + lifi: 'Li.Fi Bridge via', + cross: 'Bridge', + swap: 'Dex', +}; export const SwapRoute: React.FC = () => { const { t } = useTranslation(); const { routes, isFetching, isFetched } = useSwapRoutes(); - return ( + const renderRoutesLoading = () => { + return ( + + + + {' '} + Requesting Routes ... + + + ); + }; + + const renderNoRoutes = () => { + return ( + + + No Routes + + + ); + }; + + const renderRouteDisplay = (route: Route) => ( { + return { label: parsedStepTypes[step.type], sublabel: step.tool }; + }), + { + label: route.toToken.symbol, + sublabel: getChainById(route.toChainId).name, + }, ]} /> { color="text.primary" sx={{ alignSelf: 'end' }} > - {t(`swap.price`, { price: 20 })} + {t(`swap.price`, { price: route.gasCostUSD })} { color="text.primary" sx={{ alignSelf: 'end' }} > - 20 min + {( + route.steps + .map((step) => step.estimate.executionDuration) + .reduce((cumulated, x) => cumulated + x) / 60 + ).toFixed(1)}{' '} + min ); + + if (routes && routes.length > 0) { + return renderRouteDisplay(routes[0]); + } + if (routes && routes.length > 0 && isFetched) { + return renderNoRoutes(); + } + if (isFetching) { + return renderRoutesLoading(); + } + + // eslint-disable-next-line react/jsx-no-useless-fragment + return <>; }; diff --git a/packages/widget/src/components/SwapStepper/SwapStepper.tsx b/packages/widget/src/components/SwapStepper/SwapStepper.tsx index a560416d4..05655a67b 100644 --- a/packages/widget/src/components/SwapStepper/SwapStepper.tsx +++ b/packages/widget/src/components/SwapStepper/SwapStepper.tsx @@ -26,7 +26,10 @@ export function SwapStepper({ steps }: SwapStepperProps) { connector={} > {steps.map((step) => ( - + { refetchIntervalInBackground: true, refetchInterval: 60_000, staleTime: 60_000, + cacheTime: 60_000, }, ); diff --git a/packages/widget/src/icons/waitIcon.tsx b/packages/widget/src/icons/waitIcon.tsx new file mode 100644 index 000000000..572b6eb2b --- /dev/null +++ b/packages/widget/src/icons/waitIcon.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export function WaitIcon(props: React.SVGProps) { + return ( + + + + + ); +}