You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
6.0 KiB
191 lines
6.0 KiB
import React from "https://esm.sh/react@17.0.2";
|
|
import styled from "https://esm.sh/styled-components";
|
|
|
|
import { computeStats } from "../back/common/data.ts";
|
|
import { useStoreState } from "../state/index.ts";
|
|
|
|
export const DonateContainer = styled.div`
|
|
margin: 0 auto 100px;
|
|
max-width: 400px;
|
|
text-align: center;
|
|
`;
|
|
|
|
const Container = styled.div`
|
|
padding: 10px 0;
|
|
margin-top: 35px;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
`;
|
|
|
|
const ProgressBarInfoContainer = styled.div`
|
|
padding-top: 10px;
|
|
display: flex;
|
|
`;
|
|
|
|
const ProgressBarInfoText = styled.div`
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
text-align: center;
|
|
color: #f7f7f7;
|
|
font-size: 13px;
|
|
`;
|
|
|
|
const ProgressBarContainer = styled.div`
|
|
display: flex;
|
|
height: 44px;
|
|
`;
|
|
|
|
const Green = styled.div<{ roundedRightBorder?: boolean }>`
|
|
display: flex;
|
|
font-size: 13px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: linear-gradient(45deg, #217f35 0%, rgba(9, 89, 0, 1) 100%);
|
|
border: 1px solid #1ed947;
|
|
border-top-left-radius: 6px;
|
|
border-bottom-left-radius: 6px;
|
|
border-top-right-radius: ${(props) => (props.roundedRightBorder ? "6px" : "0px")};
|
|
border-bottom-right-radius: ${(props) => (props.roundedRightBorder ? "6px" : "0px")};
|
|
color: #f7f7f7;
|
|
`;
|
|
|
|
const White = styled.div<{ roundedLeftBorder?: boolean; roundedRightBorder?: boolean }>`
|
|
display: flex;
|
|
font-size: 13px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: linear-gradient(45deg, #8e8e8e 0%, #afafaf 100%);
|
|
border: 1px solid #f7f7f7;
|
|
border-top-left-radius: ${(props) => (props.roundedLeftBorder ? "6px" : "0px")};
|
|
border-bottom-left-radius: ${(props) => (props.roundedLeftBorder ? "6px" : "0px")};
|
|
border-top-right-radius: ${(props) => (props.roundedRightBorder ? "6px" : "0px")};
|
|
border-bottom-right-radius: ${(props) => (props.roundedRightBorder ? "6px" : "0px")};
|
|
color: #f7f7f7;
|
|
`;
|
|
|
|
const Red = styled.div<{ roundedLeftBorder?: boolean }>`
|
|
display: flex;
|
|
font-size: 13px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: linear-gradient(45deg, #731212 0%, rgba(89, 0, 0, 1) 100%);
|
|
border: 1px solid #c30000;
|
|
box-sizing: border-box;
|
|
border-radius: 0px 6px 6px 0px;
|
|
border-top-right-radius: 6px;
|
|
border-bottom-right-radius: 6px;
|
|
border-top-left-radius: ${(props) => (props.roundedLeftBorder ? "6px" : "0px")};
|
|
border-bottom-left-radius: ${(props) => (props.roundedLeftBorder ? "6px" : "0px")};
|
|
color: #f7f7f7;
|
|
`;
|
|
|
|
const NinetyPercentHolder = styled.div`
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 15px;
|
|
position: absolute;
|
|
top: 10px;
|
|
left: calc(90% - 2px);
|
|
font-size: 12px;
|
|
`;
|
|
|
|
const NinetyPercentIndicator = styled.div`
|
|
width: 3px;
|
|
height: 44px;
|
|
background: #f7f7f7;
|
|
`;
|
|
|
|
const NinetyPercentText = styled.div`
|
|
color: #fff;
|
|
height: 20px;
|
|
margin-top: -20px;
|
|
margin-left: -9px;
|
|
`;
|
|
|
|
function ProgressBar() {
|
|
const blocks = useStoreState((store) => store.blocks);
|
|
|
|
const {
|
|
currentNumberOfBlocks,
|
|
blocksLeftInThisPeriod,
|
|
currentNumberOfSignallingBlocks,
|
|
currentSignallingRatioToAll,
|
|
currentSignallingPercentageToAll,
|
|
currentNumberOfNonSignallingBlocks,
|
|
} = computeStats(blocks);
|
|
|
|
const nonSignallingRatio = currentNumberOfNonSignallingBlocks / 2016;
|
|
const nonSignallingPercentage = (nonSignallingRatio * 100).toFixed(currentNumberOfNonSignallingBlocks < 20 ? 2 : 0);
|
|
|
|
const blocksLeftRatio = blocksLeftInThisPeriod / 2016;
|
|
let blocksLeftPercentage = (blocksLeftRatio * 100).toFixed(blocksLeftInThisPeriod < 20 ? 2 : 0);
|
|
|
|
// Add rounding error leftovers to blocks left percentage
|
|
const leftOver =
|
|
100 -
|
|
(Number.parseFloat(currentSignallingPercentageToAll) +
|
|
Number.parseFloat(nonSignallingPercentage) +
|
|
Number.parseFloat(blocksLeftPercentage));
|
|
if (leftOver != 0) {
|
|
blocksLeftPercentage = (Number.parseFloat(blocksLeftPercentage) + leftOver).toFixed(2);
|
|
if (blocksLeftPercentage.endsWith(".00")) {
|
|
blocksLeftPercentage = blocksLeftPercentage.slice(0, -3);
|
|
}
|
|
if (blocksLeftPercentage.startsWith("-")) {
|
|
blocksLeftPercentage = blocksLeftPercentage.slice(1);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Container>
|
|
<ProgressBarContainer>
|
|
{currentSignallingRatioToAll > 0 && (
|
|
<Green
|
|
roundedRightBorder={currentNumberOfSignallingBlocks === 2016}
|
|
style={{ flex: currentSignallingRatioToAll }}
|
|
>
|
|
{currentSignallingRatioToAll > 0.035 && `${currentSignallingPercentageToAll}%`}
|
|
</Green>
|
|
)}
|
|
{blocksLeftRatio > 0 && (
|
|
<White
|
|
roundedLeftBorder={currentNumberOfSignallingBlocks === 0}
|
|
roundedRightBorder={currentNumberOfNonSignallingBlocks === 0}
|
|
style={{ flex: blocksLeftRatio }}
|
|
>
|
|
{blocksLeftPercentage}%
|
|
</White>
|
|
)}
|
|
{nonSignallingRatio > 0 && (
|
|
<Red roundedLeftBorder={currentNumberOfNonSignallingBlocks === 2016} style={{ flex: nonSignallingRatio }}>
|
|
{nonSignallingPercentage}%
|
|
</Red>
|
|
)}
|
|
</ProgressBarContainer>
|
|
<ProgressBarInfoContainer>
|
|
{currentSignallingRatioToAll > 0 && (
|
|
<ProgressBarInfoText style={{ flex: currentSignallingRatioToAll }}>
|
|
{currentNumberOfSignallingBlocks} signalling block{currentNumberOfSignallingBlocks > 1 && <>s</>}
|
|
</ProgressBarInfoText>
|
|
)}
|
|
{blocksLeftRatio > 0 && (
|
|
<ProgressBarInfoText style={{ flex: blocksLeftRatio }}>
|
|
{blocksLeftInThisPeriod} upcoming block{blocksLeftInThisPeriod > 1 && <>s</>}
|
|
</ProgressBarInfoText>
|
|
)}
|
|
{nonSignallingRatio > 0 && (
|
|
<ProgressBarInfoText style={{ flex: nonSignallingRatio }}>
|
|
{currentNumberOfNonSignallingBlocks} non-signalling block{currentNumberOfNonSignallingBlocks > 1 && <>s</>}
|
|
</ProgressBarInfoText>
|
|
)}
|
|
</ProgressBarInfoContainer>
|
|
<NinetyPercentHolder>
|
|
<NinetyPercentText>90%</NinetyPercentText>
|
|
<NinetyPercentIndicator />
|
|
</NinetyPercentHolder>
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
export default ProgressBar;
|
|
|