/ src / modules / migration / MigrationMarketCard.tsx
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  };