/* eslint-disable react/no-array-index-key */
import type { Route } from '@lifi/sdk';
import { Collapse, Grow, Stack, Typography } from '@mui/material';
import { useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import type { RouteObject } from 'react-router-dom';
import { useRoutes as useDOMRoutes, useNavigate } from 'react-router-dom';
import { useAccount } from '../../hooks/useAccount.js';
import { useRoutes } from '../../hooks/useRoutes.js';
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js';
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
import { useFieldValues } from '../../stores/form/useFieldValues.js';
import { WidgetEvent } from '../../types/events.js';
import { navigationRoutes } from '../../utils/navigationRoutes.js';
import { PageContainer } from '../PageContainer.js';
import { ProgressToNextUpdate } from '../ProgressToNextUpdate.js';
import { RouteCard } from '../RouteCard/RouteCard.js';
import { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js';
import { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js';
import {
CollapseContainer,
Container,
Header,
RouteTopLevelGrow,
RoutesExpandedCollapse,
ScrollableContainer,
} from './RoutesExpanded.style.js';
const timeout = { enter: 225, exit: 225, appear: 0 };
const routes: RouteObject[] = [
{
path: '/',
element: true,
},
{
path: '*',
element: null,
},
];
export const RoutesExpanded = () => {
const element = useDOMRoutes(routes);
const match = Boolean(element?.props?.children);
return (
);
};
export const RoutesExpandedElement = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const { subvariant } = useWidgetConfig();
const routesRef = useRef();
const emitter = useWidgetEvents();
const routesActiveRef = useRef(false);
const {
routes,
isLoading,
isFetching,
isFetched,
dataUpdatedAt,
refetchTime,
fromChain,
refetch,
setReviewableRoute,
} = useRoutes();
const { account } = useAccount({ chainType: fromChain?.chainType });
const [toAddress] = useFieldValues('toAddress');
const { requiredToAddress } = useToAddressRequirements();
const handleRouteClick = (
e: React.MouseEvent,
route: Route,
) => {
e.preventDefault();
e.stopPropagation();
setReviewableRoute(route);
navigate(navigationRoutes.transactionExecution, {
state: { routeId: route.id },
});
};
const onExit = () => {
// Clean routes cache on exit
routesRef.current = undefined;
};
// We cache routes results in ref for a better exit animation
if (routesRef.current && !routes) {
routesActiveRef.current = false;
} else {
routesRef.current = routes;
routesActiveRef.current = Boolean(routes);
}
const currentRoute = routesRef.current?.[0];
const expanded = Boolean(
routesActiveRef.current || isLoading || isFetching || isFetched,
);
const routeNotFound = !currentRoute && !isLoading && !isFetching && expanded;
const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress;
const allowInteraction = account.isConnected && !toAddressUnsatisfied;
useEffect(() => {
emitter.emit(WidgetEvent.WidgetExpanded, expanded);
}, [emitter, expanded]);
return (
{subvariant === 'custom'
? t('header.youPay')
: t('header.receive')}
refetch()}
sx={{ marginRight: -1 }}
/>
{routeNotFound ? (
) : isLoading || (isFetching && !routesRef.current?.length) ? (
Array.from({ length: 3 }).map((_, index) => (
))
) : (
routesRef.current?.map((route: Route, index: number) => (
handleRouteClick(e, route)
: undefined
}
active={index === 0}
expanded={routesRef.current?.length === 1}
/>
))
)}
);
};