-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
516 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React, { useCallback } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { useOperationContext } from 'contexts/OperationContext'; | ||
import { Box, Typography } from '@mui/material'; | ||
import { MATURITY_DAYS } from 'utils/utils'; | ||
import ModalAlert from 'components/common/modal/ModalAlert'; | ||
import InstallmentsOptions from './InstallmentsOptions'; | ||
|
||
export default function Installments({ setBreakdownSheetOpen }: { setBreakdownSheetOpen: (open: boolean) => void }) { | ||
const { t } = useTranslation(); | ||
const { installments } = useOperationContext(); | ||
|
||
const viewBreakdown = useCallback(() => { | ||
setBreakdownSheetOpen(true); | ||
}, [setBreakdownSheetOpen]); | ||
|
||
return ( | ||
<Box display="flex" flexDirection="column" gap={2.5} flex={1}> | ||
<Box display="flex" justifyContent="space-between"> | ||
<Box display="flex" gap={1} alignItems="center"> | ||
<Typography | ||
fontSize={11} | ||
fontWeight={700} | ||
color="white" | ||
sx={{ | ||
background: ({ palette }) => palette.green, | ||
borderRadius: '4px', | ||
px: 0.5, | ||
textTransform: 'uppercase', | ||
}} | ||
> | ||
{t('New!')} | ||
</Typography> | ||
<Typography fontFamily="fontFamilyMonospaced" color="grey.600" fontSize={12} fontWeight={500} noWrap> | ||
{t('Installments')} | ||
</Typography> | ||
</Box> | ||
<InstallmentsOptions /> | ||
</Box> | ||
{installments >= 2 && ( | ||
<ModalAlert | ||
variant="info" | ||
message={ | ||
<> | ||
{t('Each installment is due every {{interval}} days.', { | ||
interval: MATURITY_DAYS.toString(), | ||
})}{' '} | ||
<a style={{ textDecorationLine: 'underline', cursor: 'pointer' }} onClick={viewBreakdown}> | ||
{t('Payment schedule')} | ||
</a> | ||
</> | ||
} | ||
/> | ||
)} | ||
</Box> | ||
); | ||
} |
57 changes: 57 additions & 0 deletions
57
components/operations/BorrowAtMaturity/InstallmentsBreakdown.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React from 'react'; | ||
import { Box, Button, Skeleton, Table, TableBody, TableCell, TableHead, TableRow, Typography } from '@mui/material'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { useOperationContext } from 'contexts/OperationContext'; | ||
import TableHeadCell from 'components/common/TableHeadCell'; | ||
import parseTimestamp from 'utils/parseTimestamp'; | ||
import useAccountData from 'hooks/useAccountData'; | ||
|
||
export default function InstallmentsBreakdown({ onClose }: { onClose: () => void }) { | ||
const { t } = useTranslation(); | ||
const { installmentsDetails, symbol } = useOperationContext(); | ||
const { marketAccount } = useAccountData(symbol); | ||
if (!installmentsDetails || !marketAccount) return <Skeleton />; | ||
|
||
return ( | ||
<Box display="flex" flexDirection="column" flex={1}> | ||
<Box | ||
sx={{ | ||
border: '1px solid #E3E5E8', | ||
px: 2, | ||
borderRadius: 1, | ||
maxHeight: 392, | ||
overflowY: 'scroll', | ||
'& tr:last-child td': { | ||
border: 'none', | ||
}, | ||
}} | ||
> | ||
<Table> | ||
<TableHead> | ||
<TableRow> | ||
<TableHeadCell title={''} /> | ||
<TableHeadCell title={t('Maturity')} /> | ||
</TableRow> | ||
</TableHead> | ||
<TableBody> | ||
{installmentsDetails.installmentsRepayAmount.map((option, index) => ( | ||
<TableRow key={option.toString()}> | ||
<TableCell> | ||
<Typography fontSize={19} fontWeight={500} color="grey.500"> | ||
{index + 1} | ||
</Typography> | ||
</TableCell> | ||
<TableCell> | ||
<Typography fontWeight={'bold'}>{parseTimestamp(installmentsDetails.maturities[index])}</Typography> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</Box> | ||
<Button onClick={onClose} variant="contained" sx={{ marginTop: 'auto' }}> | ||
{t('Back')} | ||
</Button> | ||
</Box> | ||
); | ||
} |
88 changes: 88 additions & 0 deletions
88
components/operations/BorrowAtMaturity/InstallmentsOptions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import React, { useCallback, useMemo } from 'react'; | ||
import DropdownMenu from 'components/DropdownMenu'; | ||
import formatNumber from 'utils/formatNumber'; | ||
import { useOperationContext } from 'contexts/OperationContext'; | ||
import useAccountData from 'hooks/useAccountData'; | ||
import { formatUnits } from 'viem'; | ||
import { Box, Skeleton, Typography } from '@mui/material'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
type OptionProps = { | ||
installments: number; | ||
repayAmount: bigint; | ||
option?: boolean; | ||
}; | ||
|
||
export function Option({ installments, repayAmount, option = false }: OptionProps) { | ||
const { symbol } = useOperationContext(); | ||
const { marketAccount } = useAccountData(symbol); | ||
|
||
return ( | ||
<Typography | ||
fontWeight={600} | ||
fontSize={option ? 14 : 18} | ||
mt={option ? '4px' : '6px'} | ||
data-testid={!option ? 'modal-date-selector' : undefined} | ||
sx={{ | ||
'& span': { | ||
color: 'grey.600', | ||
}, | ||
}} | ||
> | ||
{installments} x{' '} | ||
<span> | ||
{repayAmount === 0n ? '' : '~'} | ||
{marketAccount ? formatNumber(formatUnits(repayAmount, marketAccount.decimals)) : <Skeleton />} | ||
</span> | ||
</Typography> | ||
); | ||
} | ||
|
||
export default function InstallmentsOptions() { | ||
const { t } = useTranslation(); | ||
const { installments, onInstallmentsChange, installmentsOptions, symbol } = useOperationContext(); | ||
const { marketAccount } = useAccountData(symbol); | ||
|
||
const handleChange = useCallback( | ||
(option: { installments: number }) => { | ||
onInstallmentsChange(option.installments); | ||
}, | ||
[onInstallmentsChange], | ||
); | ||
|
||
const option = useMemo(() => { | ||
if (!installmentsOptions) return; | ||
return installmentsOptions.find((o) => Number(o.installments) === installments); | ||
}, [installments, installmentsOptions]); | ||
|
||
if (!installmentsOptions || !option) return <Skeleton />; | ||
|
||
return ( | ||
<Box display="flex" flexDirection="column" alignItems="end"> | ||
<DropdownMenu | ||
label={t('Maturity')} | ||
options={installmentsOptions} | ||
onChange={handleChange} | ||
renderValue={option ? <Option {...option} /> : null} | ||
renderOption={(o: OptionProps) => <Option option {...o} />} | ||
/> | ||
{option ? ( | ||
<Typography | ||
color="figma.grey.500" | ||
fontWeight={500} | ||
fontSize={13} | ||
fontFamily="fontFamilyMonospaced" | ||
textAlign="right" | ||
marginRight="28.4px" | ||
> | ||
{t('Total')}{' '} | ||
{option && marketAccount ? ( | ||
formatNumber(formatUnits(option.repayAmount * BigInt(option.installments), marketAccount.decimals)) | ||
) : ( | ||
<Skeleton /> | ||
)} | ||
</Typography> | ||
) : null} | ||
</Box> | ||
); | ||
} |
Oops, something went wrong.