144 lines
5.8 KiB
JavaScript
144 lines
5.8 KiB
JavaScript
import { useMemo } from "react";
|
||
import { Box, Paper, Grid, Typography, LinearProgress, useTheme } from "@mui/material"
|
||
|
||
import Metric from "../../components/Metric/Metric";
|
||
import Countdown from "../../components/Countdown/Countdown";
|
||
import InfoTooltip from "../../components/Tooltip/InfoTooltip";
|
||
import { formatNumber } from "../../helpers";
|
||
|
||
export const BridgeHeader = ({
|
||
totalValidators,
|
||
disabledValidators,
|
||
bridgeStability,
|
||
transactionEta,
|
||
timeToNextEpoch,
|
||
isSmallScreen
|
||
}) => {
|
||
const theme = useTheme();
|
||
const disabledPercentage = useMemo(() => {
|
||
if (totalValidators === undefined || disabledValidators === undefined) {
|
||
return 0;
|
||
}
|
||
return ((totalValidators - disabledValidators) / totalValidators) * 100;
|
||
}, [totalValidators, disabledValidators]);
|
||
|
||
const validatorsColor = useMemo(() => {
|
||
if (disabledPercentage < 50) {
|
||
return theme.colors.validatorsColor.red;
|
||
}
|
||
return theme.colors.validatorsColor.green;
|
||
}, [disabledPercentage, theme]);
|
||
|
||
const stabilityColor = useMemo(() => {
|
||
if (bridgeStability > 80) {
|
||
return theme.colors.bridgeProgress.success;
|
||
} else if (bridgeStability > 50) {
|
||
return theme.colors.bridgeProgress.warning;
|
||
} else {
|
||
return theme.colors.bridgeProgress.error;
|
||
}
|
||
}, [bridgeStability, theme]);
|
||
|
||
const progressBarPostfix = useMemo(() => {
|
||
if (bridgeStability > 90) {
|
||
return "✅ Safe";
|
||
} else if (bridgeStability > 80) {
|
||
return "✅ Moderate Risk";
|
||
} else if (bridgeStability > 70) {
|
||
return "⚠️ High Risk";
|
||
} else if (bridgeStability > 50) {
|
||
return "⚠️ Critical Risk";
|
||
} else {
|
||
return "❌ Do NOT Bridge";
|
||
}
|
||
}, [bridgeStability]);
|
||
|
||
const formatTime = (totalSeconds) => {
|
||
const hours = Math.floor(totalSeconds / 3600);
|
||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||
const secs = Math.floor(totalSeconds % 60);
|
||
|
||
if (hours > 0) {
|
||
return `${hours} hours ${minutes} mins`;
|
||
} else if (minutes > 0) {
|
||
return `${minutes} mins`;
|
||
} else {
|
||
return `${secs} secs`;
|
||
}
|
||
}
|
||
|
||
return (
|
||
<Grid container spacing={isSmallScreen ? 4 : 1}>
|
||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||
<Metric
|
||
isLoading={totalValidators === undefined || disabledValidators === undefined}
|
||
metric={
|
||
<Typography color={validatorsColor} fontSize="24px" fontWeight="700" lineHeight="33px">
|
||
{totalValidators} ({formatNumber(disabledPercentage, 0)}% active)
|
||
</Typography>
|
||
}
|
||
label="Total Validators"
|
||
tooltip="Active and disabled GHOST Validators in the current GHOST Epoch."
|
||
/>
|
||
</Grid>
|
||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||
<Metric
|
||
isLoading={timeToNextEpoch === undefined}
|
||
metric={timeToNextEpoch < 30 ? "Rotating..." : formatTime(timeToNextEpoch)}
|
||
label="Rotation in"
|
||
tooltip="Bridge Stability Index refreshes every 10 minutes with new validator blocks; resets each Era when the validator set is updated."
|
||
/>
|
||
</Grid>
|
||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||
<Metric
|
||
isLoading={transactionEta === undefined}
|
||
metric={transactionEta > 14400 ? "∞" : formatTime(transactionEta)}
|
||
label="Max Bridge ETA"
|
||
tooltip="Maximum estimated time for finalizing bridge transactions based on the latest update."
|
||
/>
|
||
</Grid>
|
||
<Grid item gap={2} xs={12} style={{ paddingTop: "0" }} >
|
||
<Box position="relative" margin="4.5px 0">
|
||
<LinearProgress
|
||
variant="determinate"
|
||
value={bridgeStability ?? 0}
|
||
sx={{
|
||
borderRadius: "5px",
|
||
height: "40px",
|
||
'& .MuiLinearProgress-bar': {
|
||
backgroundColor: stabilityColor,
|
||
}
|
||
}}
|
||
/>
|
||
<Box sx={{
|
||
top: 0,
|
||
left: 0,
|
||
bottom: 0,
|
||
right: 0,
|
||
position: 'absolute',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
}}>
|
||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||
Bridge Stability {bridgeStability
|
||
? `${formatNumber(bridgeStability, 0)}% ${progressBarPostfix}`
|
||
: "N/A"
|
||
}
|
||
</Typography>
|
||
<InfoTooltip message={
|
||
<Box width="220px">
|
||
<Typography>0% - 50%: ❌ Do NOT Bridge</Typography>
|
||
<Typography>50% - 70%: ⚠️ Critical Risk</Typography>
|
||
<Typography>70% - 80%: ⚠️ High Risk</Typography>
|
||
<Typography>80% - 90%: ✅ Moderate Risk</Typography>
|
||
<Typography>90% - 100%: ✅ Safe</Typography>
|
||
</Box>
|
||
} />
|
||
</Box>
|
||
</Box>
|
||
</Grid>
|
||
</Grid>
|
||
)
|
||
}
|