LTVContent.tsx
  1  import { valueToBigNumber } from '@aave/math-utils';
  2  import { Trans } from '@lingui/macro';
  3  import { AlertColor, Box, Typography, useTheme } from '@mui/material';
  4  import { BigNumber } from 'bignumber.js';
  5  import React from 'react';
  6  
  7  import { FormattedNumber } from '../../../../components/primitives/FormattedNumber';
  8  
  9  interface LTVContentProps {
 10    loanToValue: string;
 11    currentLoanToValue: string;
 12    currentLiquidationThreshold: string;
 13    color: AlertColor;
 14  }
 15  
 16  export const LTVContent = ({
 17    loanToValue,
 18    currentLoanToValue,
 19    currentLiquidationThreshold,
 20    color,
 21  }: LTVContentProps) => {
 22    const { palette } = useTheme();
 23  
 24    const LTVLineWidth = valueToBigNumber(loanToValue)
 25      .multipliedBy(100)
 26      .precision(20, BigNumber.ROUND_UP)
 27      .toNumber();
 28  
 29    const CurrentLTVLineWidth = valueToBigNumber(currentLoanToValue)
 30      .multipliedBy(100)
 31      .precision(20, BigNumber.ROUND_UP)
 32      .toNumber();
 33  
 34    const currentLiquidationThresholdLeftPosition = valueToBigNumber(currentLiquidationThreshold)
 35      .multipliedBy(100)
 36      .precision(20, BigNumber.ROUND_UP)
 37      .toNumber();
 38  
 39    const liquidationThresholdPercent = Number(currentLiquidationThreshold) * 100;
 40  
 41    return (
 42      <Box sx={{ position: 'relative', margin: '45px 0 55px' }}>
 43        <Box
 44          sx={{
 45            position: 'absolute',
 46            top: 'calc(100% + 6px)',
 47            left: `${
 48              currentLiquidationThresholdLeftPosition > 100
 49                ? 100
 50                : currentLiquidationThresholdLeftPosition
 51            }%`,
 52            zIndex: 2,
 53          }}
 54        >
 55          <Box
 56            sx={{
 57              position: 'relative',
 58              whiteSpace: 'nowrap',
 59              '&:after': {
 60                content: "''",
 61                position: 'absolute',
 62                left: liquidationThresholdPercent > 75 ? 'auto' : '50%',
 63                transform: liquidationThresholdPercent > 75 ? 'translateX(0)' : 'translateX(-50%)',
 64                right: liquidationThresholdPercent > 75 ? 0 : 'auto',
 65                bottom: '100%',
 66                height: '10px',
 67                width: '2px',
 68                bgcolor: 'error.main',
 69              },
 70            }}
 71          >
 72            <Box
 73              sx={{
 74                display: 'flex',
 75                position: 'absolute',
 76                left: liquidationThresholdPercent > 75 ? 'auto' : '50%',
 77                transform: liquidationThresholdPercent > 75 ? 'translateX(0)' : 'translateX(-50%)',
 78                right: liquidationThresholdPercent > 75 ? 0 : 'auto',
 79                flexDirection: 'column',
 80                alignItems: liquidationThresholdPercent > 75 ? 'flex-end' : 'center',
 81                textAlign: liquidationThresholdPercent > 75 ? 'right' : 'center',
 82              }}
 83            >
 84              <FormattedNumber
 85                value={currentLiquidationThreshold}
 86                visibleDecimals={2}
 87                color="error.main"
 88                variant="subheader2"
 89                percent
 90                symbolsColor="error.main"
 91              />
 92              <Typography
 93                sx={{ display: 'flex' }}
 94                variant="helperText"
 95                lineHeight="12px"
 96                color="error.main"
 97              >
 98                <Trans>
 99                  Liquidation <br /> threshold
100                </Trans>
101              </Typography>
102            </Box>
103          </Box>
104        </Box>
105  
106        <Box
107          sx={{
108            position: 'absolute',
109            bottom: 'calc(100% + 6px)',
110            left: `${LTVLineWidth > 100 ? 100 : LTVLineWidth}%`,
111            zIndex: 3,
112          }}
113        >
114          <Box
115            sx={(theme) => ({
116              position: 'relative',
117              whiteSpace: 'nowrap',
118              '&:after': {
119                width: 0,
120                height: 0,
121                borderStyle: 'solid',
122                borderWidth: '6px 4px 0 4px',
123                borderColor: `${theme.palette.primary.main} transparent transparent transparent`,
124                content: "''",
125                position: 'absolute',
126                left: LTVLineWidth > 75 ? 'auto' : '50%',
127                right: LTVLineWidth > 75 ? 0 : 'auto',
128                transform: LTVLineWidth > 75 ? 'translateX(0)' : 'translateX(-50%)',
129              },
130            })}
131          >
132            <Box
133              sx={{
134                display: 'flex',
135                position: 'absolute',
136                left: LTVLineWidth > 75 ? 'auto' : LTVLineWidth < 15 ? '0' : '50%',
137                transform:
138                  LTVLineWidth > 75 || LTVLineWidth < 15 ? 'translateX(0)' : 'translateX(-50%)',
139                right: LTVLineWidth > 75 ? 0 : 'auto',
140                flexDirection: 'column',
141                alignItems:
142                  LTVLineWidth > 75 ? 'flex-end' : LTVLineWidth < 15 ? 'flex-start' : 'center',
143                textAlign: LTVLineWidth > 75 ? 'right' : LTVLineWidth < 15 ? 'left' : 'center',
144                bottom: 'calc(100% + 2px)',
145              }}
146            >
147              <FormattedNumber value={loanToValue} percent visibleDecimals={2} variant="main12" />
148              <Box sx={{ display: 'inline-flex', alignItems: 'center' }}>
149                <Typography variant="helperText" color="text.muted" mr={0.5}>
150                  <Trans>MAX</Trans>
151                </Typography>
152                <FormattedNumber
153                  value={currentLoanToValue}
154                  percent
155                  visibleDecimals={2}
156                  variant="helperText"
157                  color="text.muted"
158                  symbolsColor="text.muted"
159                />
160              </Box>
161            </Box>
162          </Box>
163        </Box>
164  
165        <Box
166          sx={{
167            height: '4px',
168            width: '100%',
169            borderRadius: '1px',
170            position: 'relative',
171            bgcolor: 'divider',
172          }}
173        >
174          <Box
175            sx={{
176              position: 'absolute',
177              left: 0,
178              height: '4px',
179              borderRadius: '1px',
180              width: `${LTVLineWidth > 100 ? 100 : LTVLineWidth}%`,
181              maxWidth: '100%',
182              bgcolor: `${color}.main`,
183              zIndex: 2,
184            }}
185          />
186  
187          {LTVLineWidth < CurrentLTVLineWidth && (
188            <Box
189              sx={{
190                position: 'absolute',
191                left: 0,
192                height: '4px',
193                borderRadius: '1px',
194                width: `${CurrentLTVLineWidth > 100 ? 100 : CurrentLTVLineWidth}%`,
195                maxWidth: '100%',
196                background: `repeating-linear-gradient(-45deg, ${palette.divider}, ${palette.divider} 4px, ${palette[color].main} 4px, ${palette[color].main} 7px)`,
197              }}
198            />
199          )}
200        </Box>
201      </Box>
202    );
203  };