chore: display prices as full number on sales page (#11554)
* chore: display prices as full number on sales page * fix: requested changes and ui fixes * refactor: simplify layout structure in Timeline component --------- Co-authored-by: Arjun Porwal <porwalarjun95@gmail.com>
This commit is contained in:
parent
e24434951d
commit
27b729b2e2
@ -8,11 +8,10 @@ import React, { useMemo } from 'react';
|
||||
|
||||
import { styled } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { formatBalance } from '@polkadot/util';
|
||||
|
||||
import { PhaseName } from '../../constants.js';
|
||||
import { useTranslation } from '../../translate.js';
|
||||
import { getCorePriceAt } from '../../utils/sale.js';
|
||||
import { formatBNToBalance, getCorePriceAt } from '../../utils/sale.js';
|
||||
import { WhiteBox } from '../../WhiteBox.js';
|
||||
|
||||
export const Cores = ({ color, phaseName, salesInfo }: { phaseName: string, salesInfo: CoretimeInformation['salesInfo'], color: string }) => {
|
||||
@ -21,6 +20,10 @@ export const Cores = ({ color, phaseName, salesInfo }: { phaseName: string, sale
|
||||
const bestNumberFinalized = useCall<BlockNumber>(apiCoretime?.derive.chain.bestNumberFinalized);
|
||||
const coretimePrice = useMemo(() => bestNumberFinalized && salesInfo && getCorePriceAt(bestNumberFinalized.toNumber(), salesInfo), [salesInfo, bestNumberFinalized]);
|
||||
|
||||
const formattedCoretimePrice = useMemo(() => {
|
||||
return !coretimePrice ? null : formatBNToBalance(coretimePrice);
|
||||
}, [coretimePrice]);
|
||||
|
||||
const CoresWrapper = styled(WhiteBox)`
|
||||
justify-self: flex-end;
|
||||
|
||||
@ -42,7 +45,7 @@ export const Cores = ({ color, phaseName, salesInfo }: { phaseName: string, sale
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
<div>
|
||||
<p style={{ fontSize: '14px', marginBottom: '0.15rem', opacity: '0.8' }}>{t('current price')}</p>
|
||||
<p style={{ color: `${color}`, fontSize: '20px' }}> {coretimePrice && formatBalance(coretimePrice)}</p>
|
||||
<p style={{ color: `${color}`, fontSize: '20px' }}>{formattedCoretimePrice}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p style={{ fontSize: '14px', marginBottom: '0.15rem', opacity: '0.8' }}>{t('available cores')}</p>
|
||||
|
||||
@ -8,20 +8,12 @@ import type { CoretimeInformation } from '@polkadot/react-hooks/types';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { CardSummary, ProgressBar, styled, SummaryBox } from '@polkadot/react-components';
|
||||
import { formatBalance, formatNumber } from '@polkadot/util';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../../translate.js';
|
||||
import { getCorePriceAt, getSaleProgress } from '../../utils/sale.js';
|
||||
import { formatBNToBalance, getCorePriceAt, getSaleProgress } from '../../utils/sale.js';
|
||||
import { WhiteBox } from '../../WhiteBox.js';
|
||||
|
||||
const TimelineWrapper = styled(WhiteBox)`
|
||||
justify-self: flex-start;
|
||||
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
interface TimelineProps {
|
||||
phaseName: string;
|
||||
saleParams: SaleParameters;
|
||||
@ -45,27 +37,23 @@ export const Timeline = ({ color, coretimeInfo: { salesInfo, status }, phaseName
|
||||
|
||||
const coretimePriceStart = useMemo(() => salesInfo && getCorePriceAt(salesInfo.saleStart, salesInfo), [salesInfo]);
|
||||
|
||||
const endPrice = useMemo(() => salesInfo.endPrice.toNumber() < 10 ** formatBalance.getDefaults().decimals
|
||||
? `${salesInfo.endPrice.toNumber() / 10 ** formatBalance.getDefaults().decimals} ${formatBalance.getDefaults().unit}`
|
||||
: formatBalance(salesInfo.endPrice), [salesInfo.endPrice]);
|
||||
const startPrice = useMemo(() => coretimePriceStart && formatBNToBalance(coretimePriceStart), [coretimePriceStart]);
|
||||
const endPrice = useMemo(() => salesInfo?.endPrice && formatBNToBalance(salesInfo.endPrice), [salesInfo?.endPrice]);
|
||||
|
||||
return (
|
||||
<TimelineWrapper>
|
||||
<p style={{ fontSize: '16px', fontWeight: 'bold' }}>{t('Sale timeline')}</p>
|
||||
<SummaryBox>
|
||||
<section>
|
||||
<StyledSummaryBox>
|
||||
<GridLayout>
|
||||
{phaseName && <>
|
||||
<CardSummary label='current phase'>{phaseName}</CardSummary>
|
||||
<CardSummary label='current phase end'>{saleParams?.phaseConfig?.config[phaseName as keyof typeof saleParams.phaseConfig.config].end.date}</CardSummary>
|
||||
<CardSummary label='last phase block'>{formatNumber(saleParams?.phaseConfig?.config[phaseName as keyof typeof saleParams.phaseConfig.config].end.blocks.relay)}</CardSummary>
|
||||
</>}
|
||||
<CardSummary label='start price'>{formatBalance(coretimePriceStart)}</CardSummary>
|
||||
<CardSummary label='start price'>{startPrice}</CardSummary>
|
||||
<CardSummary label='fixed price'>{endPrice}</CardSummary>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
</section>
|
||||
</SummaryBox>
|
||||
</GridLayout>
|
||||
</StyledSummaryBox>
|
||||
<ProgressBar
|
||||
color={color}
|
||||
sections={progressValues as ProgressBarSection[] ?? []}
|
||||
@ -73,3 +61,33 @@ export const Timeline = ({ color, coretimeInfo: { salesInfo, status }, phaseName
|
||||
</TimelineWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const TimelineWrapper = styled(WhiteBox)`
|
||||
justify-self: flex-start;
|
||||
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSummaryBox = styled(SummaryBox)`
|
||||
margin-top: 0;
|
||||
`;
|
||||
|
||||
const GridLayout = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
column-gap: 0.5rem;
|
||||
row-gap: 1rem;
|
||||
width: 100%;
|
||||
|
||||
/* Override CardSummary styling to align text left and remove padding */
|
||||
article {
|
||||
justify-content: flex-start;
|
||||
padding: 0;
|
||||
|
||||
> .ui--Labelled {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -5,7 +5,7 @@ import type { ChainConstants, PalletBrokerConfigRecord, PalletBrokerSaleInfoReco
|
||||
import type { GetResponse, PhaseConfig, RegionInfo, RelayName, SaleParameters } from '../types.js';
|
||||
|
||||
import { type ProgressBarSection } from '@polkadot/react-components/types';
|
||||
import { BN } from '@polkadot/util';
|
||||
import { BN, formatBalance } from '@polkadot/util';
|
||||
|
||||
import { PhaseName } from '../constants.js';
|
||||
import { createGet, estimateTime, FirstCycleStart, getCurrentRegionStartEndTs } from './index.js';
|
||||
@ -13,6 +13,14 @@ import { createGet, estimateTime, FirstCycleStart, getCurrentRegionStartEndTs }
|
||||
// We are scaling everything to avoid floating point precision issues.
|
||||
const SCALE = new BN(10000);
|
||||
|
||||
/**
|
||||
* Formats a BN value to a human-readable balance string with proper units
|
||||
*
|
||||
* @param num - The BN value to format
|
||||
* @returns A formatted string with the balance value and unit
|
||||
*/
|
||||
export const formatBNToBalance = (num: BN) => formatBalance(num, { forceUnit: formatBalance.getDefaults().unit, withAll: true, withUnit: true });
|
||||
|
||||
export const leadinFactorAt = (scaledWhen: BN): BN => {
|
||||
const scaledHalf = SCALE.div(new BN(2)); // 0.5 scaled to 10000
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user