-
Notifications
You must be signed in to change notification settings - Fork 18
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
1 parent
9b23a16
commit f16b391
Showing
30 changed files
with
492 additions
and
128 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import LoadingSpinner from '../LoadingSpinner/LoadingSpinner' | ||
|
||
const AppLoadFallback = () => { | ||
return ( | ||
<div className='relative w-screen h-screen bg-gradient-to-r from-primary to-tertiary'> | ||
<div className='absolute top-0 left-0 w-full h-full bg-cover bg-lighthouse' /> | ||
<div className='absolute top-1/2 -translate-y-1/2 left-1/2 -translate-x-1/2'> | ||
<LoadingSpinner /> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default AppLoadFallback |
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,76 @@ | ||
import { ProposerDuty, StatusColor } from '../../types' | ||
import { FC, useState } from 'react' | ||
import StatusBar from '../StatusBar/StatusBar' | ||
import Typography from '../Typography/Typography' | ||
import ProposalAlert from './ProposalAlert' | ||
import getSlotTimeData from '../../utilities/getSlotTimeData' | ||
import { useTranslation } from 'react-i18next' | ||
|
||
export interface AlertGroupProps { | ||
duties: ProposerDuty[] | ||
onClick: (ids: string[]) => void | ||
genesis: number | ||
secondsPerSlot: number | ||
} | ||
|
||
const AlertGroup: FC<AlertGroupProps> = ({ duties, genesis, secondsPerSlot, onClick }) => { | ||
const { t } = useTranslation() | ||
const indices = duties.map(({ validator_index }) => validator_index) | ||
const uuids = duties.map(({ uuid }) => uuid) | ||
const isFullGroup = duties.length > 1 | ||
const [isExpand, toggleGroup] = useState(false) | ||
|
||
const sortedDutiesBySlot = [...duties].sort((a, b) => Number(b.slot) - Number(a.slot)) | ||
const latestDuty = sortedDutiesBySlot[0] | ||
const latestDutyTime = getSlotTimeData(Number(latestDuty.slot), genesis, secondsPerSlot) | ||
|
||
const toggle = () => toggleGroup(!isExpand) | ||
const removeGroup = () => onClick(uuids) | ||
|
||
const renderMappedDuties = () => | ||
duties?.map((duty, index) => { | ||
const { isFuture, shortHand } = getSlotTimeData(Number(duty.slot), genesis, secondsPerSlot) | ||
|
||
return ( | ||
<ProposalAlert | ||
onDelete={!isFullGroup ? removeGroup : undefined} | ||
isFuture={isFuture} | ||
key={index} | ||
duty={duty} | ||
time={shortHand} | ||
/> | ||
) | ||
}) | ||
|
||
return ( | ||
<> | ||
{isFullGroup ? ( | ||
<> | ||
<div className='w-full @1540:h-22 group border-b-style500 flex justify-between items-center space-x-2 @1540:space-x-4 p-2'> | ||
<StatusBar count={3} status={StatusColor.SUCCESS} /> | ||
<div onClick={toggle} className='cursor-pointer w-full max-w-tiny @1540:max-w-full'> | ||
<Typography type='text-caption2'> | ||
{t( | ||
`alertMessages.groupedProposers.${latestDutyTime.isFuture ? 'future' : 'past'}`, | ||
{ count: duties?.length, indices: indices.join(', ') }, | ||
)} | ||
</Typography> | ||
<Typography color='text-primary' darkMode='text-primary' type='text-caption2'> | ||
{isExpand ? t('collapseInfo') : t('expandInfo')} | ||
</Typography> | ||
</div> | ||
<i | ||
onClick={removeGroup} | ||
className='bi-trash-fill cursor-pointer opacity-0 group-hover:opacity-100 text-dark200 dark:text-dark300' | ||
/> | ||
</div> | ||
{isExpand && renderMappedDuties()} | ||
</> | ||
) : ( | ||
renderMappedDuties() | ||
)} | ||
</> | ||
) | ||
} | ||
|
||
export default AlertGroup |
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,41 @@ | ||
import { ProposerDuty, StatusColor } from '../../types' | ||
import { FC } from 'react' | ||
import StatusBar from '../StatusBar/StatusBar' | ||
import Typography from '../Typography/Typography' | ||
import { Trans } from 'react-i18next' | ||
|
||
export interface ProposalAlertProps { | ||
duty: ProposerDuty | ||
time: string | ||
isFuture?: boolean | ||
onDelete?: (uuid: string[]) => void | ||
} | ||
|
||
const ProposalAlert: FC<ProposalAlertProps> = ({ duty, time, isFuture, onDelete }) => { | ||
const { validator_index, slot, uuid } = duty | ||
|
||
const removeAlert = () => onDelete?.([uuid]) | ||
return ( | ||
<div className='w-full @1540:h-22 group border-b-style500 flex justify-between items-center space-x-2 @1540:space-x-4 p-2'> | ||
<StatusBar count={3} status={StatusColor.SUCCESS} /> | ||
<div className='w-full max-w-tiny @1540:max-w-full'> | ||
<Typography type='text-caption2'> | ||
<Trans | ||
i18nKey={`alertMessages.proposerAlert.${isFuture ? 'future' : 'past'}`} | ||
values={{ validator_index, slot, time }} | ||
> | ||
<span className='font-bold underline' /> | ||
</Trans> | ||
</Typography> | ||
</div> | ||
{onDelete && ( | ||
<i | ||
onClick={removeAlert} | ||
className='bi-trash-fill cursor-pointer opacity-0 group-hover:opacity-100 text-dark200 dark:text-dark300' | ||
/> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default ProposalAlert |
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,58 @@ | ||
import { FC } from 'react' | ||
import { ProposerDuty } from '../../types' | ||
import groupArray from '../../utilities/groupArray' | ||
import AlertGroup from './AlertGroup' | ||
import ProposalAlert from './ProposalAlert' | ||
import { useRecoilValue, useSetRecoilState } from 'recoil' | ||
import { selectGenesisBlock } from '../../recoil/selectors/selectGenesisBlock' | ||
import { selectBnSpec } from '../../recoil/selectors/selectBnSpec' | ||
import { proposerDuties } from '../../recoil/atoms' | ||
import getSlotTimeData from '../../utilities/getSlotTimeData' | ||
|
||
export interface ProposerAlertsProps { | ||
duties: ProposerDuty[] | ||
} | ||
|
||
const ProposerAlerts: FC<ProposerAlertsProps> = ({ duties }) => { | ||
const { SECONDS_PER_SLOT } = useRecoilValue(selectBnSpec) | ||
const genesis = useRecoilValue(selectGenesisBlock) as number | ||
const setProposers = useSetRecoilState(proposerDuties) | ||
const groups = groupArray(duties, 10) | ||
|
||
const removeAlert = (uuids: string[]) => { | ||
setProposers((prev) => prev.filter(({ uuid }) => !uuids.includes(uuid))) | ||
} | ||
|
||
return ( | ||
<> | ||
{duties.length >= 10 | ||
? groups.map((group, index) => ( | ||
<AlertGroup | ||
onClick={removeAlert} | ||
genesis={genesis} | ||
secondsPerSlot={SECONDS_PER_SLOT} | ||
duties={group} | ||
key={index} | ||
/> | ||
)) | ||
: duties.map((duty, index) => { | ||
const { isFuture, shortHand } = getSlotTimeData( | ||
Number(duty.slot), | ||
genesis, | ||
SECONDS_PER_SLOT, | ||
) | ||
return ( | ||
<ProposalAlert | ||
onDelete={removeAlert} | ||
isFuture={isFuture} | ||
time={shortHand} | ||
key={index} | ||
duty={duty} | ||
/> | ||
) | ||
})} | ||
</> | ||
) | ||
} | ||
|
||
export default ProposerAlerts |
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
Oops, something went wrong.