diff --git a/packages/page-coretime/src/Sale/boxes/Cores.tsx b/packages/page-coretime/src/Sale/boxes/Cores.tsx index bb1cf01e99..32984631fe 100644 --- a/packages/page-coretime/src/Sale/boxes/Cores.tsx +++ b/packages/page-coretime/src/Sale/boxes/Cores.tsx @@ -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(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

{t('current price')}

-

{coretimePrice && formatBalance(coretimePrice)}

+

{formattedCoretimePrice}

{t('available cores')}

diff --git a/packages/page-coretime/src/Sale/boxes/Timeline.tsx b/packages/page-coretime/src/Sale/boxes/Timeline.tsx index 6073f637eb..228d284e6c 100644 --- a/packages/page-coretime/src/Sale/boxes/Timeline.tsx +++ b/packages/page-coretime/src/Sale/boxes/Timeline.tsx @@ -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 (

{t('Sale timeline')}

- -
+ + {phaseName && <> {phaseName} {saleParams?.phaseConfig?.config[phaseName as keyof typeof saleParams.phaseConfig.config].end.date} {formatNumber(saleParams?.phaseConfig?.config[phaseName as keyof typeof saleParams.phaseConfig.config].end.blocks.relay)} } - {formatBalance(coretimePriceStart)} + {startPrice} {endPrice} -
-
- -
-
+ + ); }; + +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; + } + } +`; diff --git a/packages/page-coretime/src/utils/sale.ts b/packages/page-coretime/src/utils/sale.ts index 34df2c20fd..80be2201b0 100644 --- a/packages/page-coretime/src/utils/sale.ts +++ b/packages/page-coretime/src/utils/sale.ts @@ -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