MigrationMarketCard.tsx
1 import { ArrowNarrowRightIcon } from '@heroicons/react/solid'; 2 import { KeyboardArrowDown, KeyboardArrowUp } from '@mui/icons-material'; 3 import { 4 Avatar, 5 Badge, 6 Box, 7 Divider, 8 IconButton, 9 Menu, 10 MenuItem, 11 Skeleton, 12 SvgIcon, 13 Typography, 14 } from '@mui/material'; 15 import { FC, useState } from 'react'; 16 import { HealthFactorNumber } from 'src/components/HealthFactorNumber'; 17 import { MarketDataType } from 'src/ui-config/marketsConfig'; 18 import { getNetworkConfig } from 'src/utils/marketsAndNetworksConfig'; 19 20 const formatMarketName = (market: MarketDataType) => { 21 return `Aave ${market.v3 ? 'V3' : 'V2'} - ${market.marketTitle}${market.isFork ? ' Fork' : ''}`; 22 }; 23 24 type MigrationMarketCardProps = { 25 marketData: MarketDataType; 26 userSummaryAfterMigration?: { 27 healthFactor: string; 28 }; 29 userSummaryBeforeMigration?: { 30 healthFactor: string; 31 }; 32 selectableMarkets?: SelectableMarkets; 33 setFromMarketData?: (marketData: MarketDataType) => void; 34 loading?: boolean; 35 }; 36 37 export type SelectableMarkets = Array<{ 38 title: string; 39 markets: MarketDataType[]; 40 }>; 41 42 export const MigrationMarketCard: FC<MigrationMarketCardProps> = ({ 43 marketData, 44 userSummaryAfterMigration, 45 userSummaryBeforeMigration, 46 selectableMarkets, 47 setFromMarketData, 48 loading, 49 }) => { 50 const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); 51 const open = Boolean(anchorEl); 52 const handleClick = (event: React.MouseEvent<HTMLElement>) => { 53 setAnchorEl(event.currentTarget); 54 }; 55 const handleClose = () => { 56 setAnchorEl(null); 57 }; 58 const handleSelectedMarket = (marketData: MarketDataType) => { 59 setFromMarketData && setFromMarketData(marketData); 60 setAnchorEl(null); 61 }; 62 const networkConfig = getNetworkConfig(marketData.chainId); 63 return ( 64 <Box 65 sx={{ 66 padding: '12px 16px 16px 16px', 67 border: 1, 68 borderColor: 'divider', 69 borderRadius: 3, 70 width: '100%', 71 }} 72 > 73 <Typography variant="subheader2" color="text.primary" sx={{ mb: 2 }}> 74 From 75 </Typography> 76 <Box sx={{ display: 'flex', alignItems: 'center', mb: 6 }}> 77 <Badge 78 overlap="circular" 79 anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} 80 badgeContent={ 81 <Avatar src={networkConfig.networkLogoPath} sx={{ width: 20, height: 20 }} /> 82 } 83 > 84 <Avatar src="/aave.svg" sx={{ width: 36, height: 36 }} /> 85 </Badge> 86 <Typography variant="subheader1" sx={{ ml: 5 }}> 87 {formatMarketName(marketData)} 88 </Typography> 89 {selectableMarkets && setFromMarketData && ( 90 <> 91 <IconButton onClick={handleClick} sx={{ ml: 'auto' }}> 92 {open ? <KeyboardArrowUp /> : <KeyboardArrowDown />} 93 </IconButton> 94 <Menu 95 open={open} 96 onClose={handleClose} 97 anchorEl={anchorEl} 98 anchorOrigin={{ 99 vertical: 'bottom', 100 horizontal: 'right', 101 }} 102 transformOrigin={{ 103 vertical: 'top', 104 horizontal: 'right', 105 }} 106 > 107 {selectableMarkets.map((selectableMarket) => ( 108 <Box key={selectableMarket.title}> 109 <Box sx={{ py: 2, px: 4 }}> 110 <Typography color="text.secondary" variant="subheader2"> 111 {selectableMarket.title} 112 </Typography> 113 </Box> 114 {selectableMarket.markets.map((market) => { 115 const currentNetworkConfig = getNetworkConfig(market.chainId); 116 return ( 117 <MenuItem 118 key={`${market.marketTitle}_${market.isFork}`} 119 onClick={() => handleSelectedMarket(market)} 120 > 121 <Badge 122 overlap="circular" 123 anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} 124 badgeContent={ 125 <Avatar 126 src={currentNetworkConfig.networkLogoPath} 127 sx={{ width: 16, height: 16 }} 128 /> 129 } 130 > 131 <Avatar src="/aave.svg" sx={{ width: 24, height: 24 }} /> 132 </Badge> 133 <Typography variant="secondary14" sx={{ ml: 3 }}> 134 {`${market.marketTitle}${market.isFork ? ' Fork' : ''}`} 135 </Typography> 136 </MenuItem> 137 ); 138 })} 139 </Box> 140 ))} 141 </Menu> 142 </> 143 )} 144 </Box> 145 <Divider /> 146 <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mt: 3 }}> 147 <Typography>Health Factor</Typography> 148 <Box sx={{ textAlign: 'right' }}> 149 <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}> 150 {!loading && userSummaryBeforeMigration ? ( 151 <HealthFactorNumber value={userSummaryBeforeMigration.healthFactor} /> 152 ) : ( 153 <Skeleton width={50} /> 154 )} 155 <SvgIcon sx={{ fontSize: '16px', color: 'text.primary', mx: 1 }}> 156 <ArrowNarrowRightIcon /> 157 </SvgIcon> 158 {!loading && userSummaryAfterMigration ? ( 159 <HealthFactorNumber value={userSummaryAfterMigration.healthFactor} /> 160 ) : ( 161 <Skeleton width={50} /> 162 )} 163 </Box> 164 </Box> 165 </Box> 166 </Box> 167 ); 168 };