From daf519b199281b85e0ab685bbba85a31d34e8211 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:03:02 +0200 Subject: [PATCH 1/6] High resolution logo (#75) * High resolutino logo * fix --- src/assets/logo.png | Bin 4453 -> 66517 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/assets/logo.png b/src/assets/logo.png index 79ec9546485129ac091420d17f8f35d9d38b70df..1200586b4a88f8bfd312106e624ad5664de439f9 100644 GIT binary patch literal 66517 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 z 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 CKW60s literal 4453 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 rHLIPw=S~L)hiDHE4;yNw$A Date: Mon, 22 Apr 2024 08:59:24 -0700 Subject: [PATCH 2/6] fix wss connections made twice in dev mode (#76) --- next.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next.config.js b/next.config.js index 069ea9b1..7bee534b 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,6 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - reactStrictMode: true, + reactStrictMode: false, images: { domains: ['github.com'], }, From f06ad34a257a896e0868b1ae19d07ad3276ce8c9 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:38:39 +0200 Subject: [PATCH 3/6] Fix invalid CoreMask issue (#77) * Fix invalid CoreMask issue * better fix --- src/components/Elements/ListingCard/index.tsx | 2 +- src/components/Modals/Sell/index.tsx | 4 ++- src/contexts/regions/native/index.ts | 34 ++++++++----------- src/contexts/tasks/index.tsx | 2 +- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/components/Elements/ListingCard/index.tsx b/src/components/Elements/ListingCard/index.tsx index a6aadda8..029f5276 100644 --- a/src/components/Elements/ListingCard/index.tsx +++ b/src/components/Elements/ListingCard/index.tsx @@ -196,7 +196,7 @@ const ListingCardInner = ({ > Price/timeslice: - {`${formatBalance(listing.timeslicePrice.toString(),true)} ${symbol}`} + {`${formatBalance(listing.timeslicePrice.toString(), true)} ${symbol}`} { const { activeAccount, api } = useInkathon(); - const {state: {symbol}} = useCoretimeApi(); + const { + state: { symbol }, + } = useCoretimeApi(); const { fetchRegions } = useRegions(); const { toastError, toastSuccess } = useToast(); diff --git a/src/contexts/regions/native/index.ts b/src/contexts/regions/native/index.ts index 279e74d9..e23540a7 100644 --- a/src/contexts/regions/native/index.ts +++ b/src/contexts/regions/native/index.ts @@ -14,28 +14,24 @@ export const fetchRegions = async ( const brokerRegions: Array = brokerEntries .map(([key, value]) => { - const keyTuple: any = key.toHuman(); + const keyTuple: any = key.toHuman(undefined, true); const { begin, core, mask } = keyTuple[0] as any; const { end, owner, paid } = value.toHuman() as any; - try { - const regionId = { - begin: parseHNString(begin.toString()), - core: parseHNString(core.toString()), - mask: new CoreMask(mask), - }; - return new Region( - regionId, - { - end: parseHNString(end), - owner, - paid: paid ? parseHNString(paid) : null, - }, - 0 - ); - } catch (_e) { - /** */ - } + const regionId = { + begin: parseHNString(begin.toString()), + core: parseHNString(core.toString()), + mask: new CoreMask(mask), + }; + return new Region( + regionId, + { + end: parseHNString(end), + owner, + paid: paid ? parseHNString(paid) : null, + }, + 0 + ); }) .filter((entry) => !!entry) as Array; return brokerRegions; diff --git a/src/contexts/tasks/index.tsx b/src/contexts/tasks/index.tsx index 3fc9a6ab..0c67dcd3 100644 --- a/src/contexts/tasks/index.tsx +++ b/src/contexts/tasks/index.tsx @@ -63,7 +63,7 @@ const TaskDataProvider = ({ children }: Props) => { for await (const [key, value] of workplan) { const [[begin, core]] = key.toHuman() as [[number, number]]; - const records = value.toHuman() as ScheduleItem[]; + const records = value.toHuman(undefined, true) as ScheduleItem[]; records.forEach((record) => { const { From 8329716731dbf6fcfbbae8f497d14412e6622fe3 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:28:59 +0200 Subject: [PATCH 4/6] Purchase components refactor (#78) * Purchase components refactor * lint fix --- src/components/Elements/SaleInfo/index.tsx | 35 +---- src/hooks/balance.tsx | 42 ++++++ src/hooks/salePhase.tsx | 104 ++++++++++++++ src/hooks/salePrice.tsx | 32 +++++ src/pages/purchase.tsx | 151 ++++----------------- 5 files changed, 207 insertions(+), 157 deletions(-) create mode 100644 src/hooks/balance.tsx create mode 100644 src/hooks/salePhase.tsx create mode 100644 src/hooks/salePrice.tsx diff --git a/src/components/Elements/SaleInfo/index.tsx b/src/components/Elements/SaleInfo/index.tsx index 5e70657a..338e29a3 100644 --- a/src/components/Elements/SaleInfo/index.tsx +++ b/src/components/Elements/SaleInfo/index.tsx @@ -1,13 +1,10 @@ import { Box, Typography } from '@mui/material'; -import { ApiPromise } from '@polkadot/api'; import TimeAgo from 'javascript-time-ago'; import en from 'javascript-time-ago/locale/en.json'; -import React, { useCallback, useEffect, useState } from 'react'; -import { formatBalance, getBlockTimestamp } from '@/utils/functions'; +import { formatBalance } from '@/utils/functions'; import { useCoretimeApi } from '@/contexts/apis'; -import { ApiState } from '@/contexts/apis/types'; import { SaleInfo, SalePhase } from '@/models'; import styles from './index.module.scss'; @@ -16,22 +13,22 @@ interface SaleInfoGridProps { saleInfo: SaleInfo; currentPhase: SalePhase; currentPrice: number; - saleEnd: number; + saleEndTimestamp: number; + saleStartTimestamp: number; } export const SaleInfoGrid = ({ saleInfo, currentPhase, currentPrice, - saleEnd, + saleEndTimestamp, + saleStartTimestamp, }: SaleInfoGridProps) => { TimeAgo.addLocale(en); const timeAgo = new TimeAgo('en-US'); - const [saleStartTimestamp, setSaleStartTimestamp] = useState(0); - const [saleEndTimestamp, setSaleEndTimestamp] = useState(0); const { - state: { api, apiState, symbol }, + state: { symbol }, } = useCoretimeApi(); const nextPhase = (): SalePhase => { @@ -43,26 +40,6 @@ export const SaleInfoGrid = ({ return phases[nextIndex]; }; - const setTimestamps = useCallback( - (api: ApiPromise) => { - getBlockTimestamp(api, saleInfo.saleStart).then((value) => - setSaleStartTimestamp(value) - ); - getBlockTimestamp(api, saleEnd).then((value) => - setSaleEndTimestamp(value) - ); - }, - [saleInfo.saleStart, saleEnd] - ); - - useEffect(() => { - if (!api || apiState !== ApiState.READY) { - return; - } - - setTimestamps(api); - }, [api, apiState, setTimestamps]); - return ( diff --git a/src/hooks/balance.tsx b/src/hooks/balance.tsx new file mode 100644 index 00000000..34cc3502 --- /dev/null +++ b/src/hooks/balance.tsx @@ -0,0 +1,42 @@ +import { useInkathon } from '@scio-labs/use-inkathon'; +import { useCallback, useEffect, useState } from 'react'; + +import { useCoretimeApi } from '@/contexts/apis'; +import { ApiState } from '@/contexts/apis/types'; +import { useToast } from '@/contexts/toast'; + +// React hook for fetching balance. +const useBalance = () => { + const { + state: { api, apiState, symbol }, + } = useCoretimeApi(); + const { activeAccount } = useInkathon(); + + const [balance, setBalance] = useState(0); + + const { toastWarning } = useToast(); + + const fetchBalance = useCallback(async () => { + if (api && apiState == ApiState.READY && activeAccount) { + const accountData: any = ( + await api.query.system.account(activeAccount.address) + ).toHuman(); + const balance = parseFloat(accountData.data.free.toString()); + setBalance(balance); + + if (balance === 0) { + toastWarning( + `The selected account does not have any ${symbol} tokens on the Coretime chain.` + ); + } + } + }, [api, apiState, activeAccount, toastWarning, symbol]); + + useEffect(() => { + fetchBalance(); + }, [fetchBalance]); + + return balance; +}; + +export default useBalance; diff --git a/src/hooks/salePhase.tsx b/src/hooks/salePhase.tsx new file mode 100644 index 00000000..aba6ba7e --- /dev/null +++ b/src/hooks/salePhase.tsx @@ -0,0 +1,104 @@ +import { ApiPromise } from '@polkadot/api'; +import { useCallback, useEffect, useState } from 'react'; + +import { + getBlockTimestamp, + parseHNString, +} from '@/utils/functions'; +import { + getCurrentPhase, + getSaleEndInBlocks, + getSaleProgress, + getSaleStartInBlocks, +} from '@/utils/sale/utils'; + +import { Section } from '@/components/Elements'; + +import { useCoretimeApi } from '@/contexts/apis'; +import { ApiState } from '@/contexts/apis/types'; +import { useSaleInfo } from '@/contexts/sales'; +import { SalePhase } from '@/models'; + +// Custom hook for fetching current phase +const useSalePhase = () => { + const { + state: { api, apiState }, + } = useCoretimeApi(); + const { saleInfo, config } = useSaleInfo(); + + const [currentPhase, setCurrentPhase] = useState(null); + + const [saleEndTimestamp, setSaleEndTimestamp] = useState(0); + const [saleStartTimestamp, setSaleStartTimestamp] = useState(0); + + const [progress, setProgress] = useState(0); + const [saleSections, setSaleSections] = useState([]); + + const fetchCurrentPhase = useCallback( + async (api: ApiPromise) => { + const blockNumber = (await api.query.system.number()).toJSON() as number; + const lastCommittedTimeslice = parseHNString( + ( + (await api.query.broker.status()).toHuman() as any + ).lastCommittedTimeslice.toString() + ); + + const _saleStart = getSaleStartInBlocks(saleInfo, config); + const _saleEnd = getSaleEndInBlocks( + saleInfo, + blockNumber, + lastCommittedTimeslice, + ); + + getBlockTimestamp(api, _saleStart).then( + (value: number) => setSaleStartTimestamp(value) + ); + getBlockTimestamp(api, _saleEnd).then( + (value: number) => setSaleEndTimestamp(value) + ); + + const progress = getSaleProgress( + saleInfo, + config, + blockNumber, + lastCommittedTimeslice, + ); + setProgress(progress); + + setCurrentPhase(getCurrentPhase(saleInfo, blockNumber)); + + const saleDuration = _saleEnd - _saleStart; + + setSaleSections([ + { name: 'Interlude', value: 0 }, + { + name: 'Leadin phase', + value: (config.interludeLength / saleDuration) * 100, + }, + { + name: 'Fixed price phase', + value: + ((config.interludeLength + config.leadinLength) / saleDuration) * + 100, + }, + ]); + }, + [saleInfo, config] + ); + + useEffect(() => { + if (!api || apiState !== ApiState.READY) return; + + fetchCurrentPhase(api); + }, [fetchCurrentPhase, api, apiState]); + + return { + currentPhase, + saleStartTimestamp, + saleEndTimestamp, + progress, + saleSections, + }; +}; + +export default useSalePhase; diff --git a/src/hooks/salePrice.tsx b/src/hooks/salePrice.tsx new file mode 100644 index 00000000..c1207de7 --- /dev/null +++ b/src/hooks/salePrice.tsx @@ -0,0 +1,32 @@ +import { useCallback, useEffect, useState } from 'react'; + +import { getCurrentPrice } from '@/utils/sale/utils'; + +import { useCoretimeApi } from '@/contexts/apis'; +import { ApiState } from '@/contexts/apis/types'; +import { useSaleInfo } from '@/contexts/sales'; + +const useSalePrice = () => { + const { + state: { api, apiState }, + } = useCoretimeApi(); + const { saleInfo } = useSaleInfo(); + + const [currentPrice, setCurrentPrice] = useState(0); + + const fetchCurrentPrice = useCallback(async () => { + if (api && apiState === ApiState.READY) { + const blockNumber = (await api.query.system.number()).toJSON() as number; + const price = getCurrentPrice(saleInfo, blockNumber); + setCurrentPrice(price); + } + }, [api, apiState, saleInfo]); + + useEffect(() => { + fetchCurrentPrice(); + }, [fetchCurrentPrice]); + + return currentPrice; +}; + +export default useSalePrice; diff --git a/src/pages/purchase.tsx b/src/pages/purchase.tsx index e827b48b..5101bc8a 100644 --- a/src/pages/purchase.tsx +++ b/src/pages/purchase.tsx @@ -1,143 +1,51 @@ import { LoadingButton } from '@mui/lab'; import { Box, Button, Typography, useTheme } from '@mui/material'; -import { ApiPromise } from '@polkadot/api'; -import { InjectedAccount } from '@polkadot/extension-inject/types'; import { useInkathon } from '@scio-labs/use-inkathon'; import TimeAgo from 'javascript-time-ago'; import en from 'javascript-time-ago/locale/en.json'; import Link from 'next/link'; -import { useCallback, useEffect, useState } from 'react'; +import { useState } from 'react'; -import { - formatBalance, - getBlockTimestamp, - parseHNString, -} from '@/utils/functions'; +import useBalance from '@/hooks/balance'; +import useSalePhase from '@/hooks/salePhase'; +import useSalePrice from '@/hooks/salePrice'; +import { formatBalance } from '@/utils/functions'; -import { Progress, SaleInfoGrid, Section } from '@/components'; +import { Progress, SaleInfoGrid } from '@/components'; import { useCoretimeApi } from '@/contexts/apis'; import { ApiState } from '@/contexts/apis/types'; import { useRegions } from '@/contexts/regions'; import { useSaleInfo } from '@/contexts/sales'; import { useToast } from '@/contexts/toast'; -import { SalePhase } from '@/models'; - -import { - getCurrentPhase, - getCurrentPrice, - getSaleEndInBlocks, - getSaleProgress, - getSaleStartInBlocks, -} from '../utils/sale/utils'; const Purchase = () => { const theme = useTheme(); const [working, setWorking] = useState(false); - const [balance, setBalance] = useState(0); - const [currentPhase, setCurrentPhase] = useState(null); - const [currentPrice, setCurrentPrice] = useState(0); - const [saleEnd, setSaleEnd] = useState(null); - const [currentBlockNumber, setCurrentBlockNumber] = useState( - null - ); - const [progress, setProgress] = useState(0); - const [saleSections, setSaleSections] = useState([]); - TimeAgo.addLocale(en); // Create formatter (English). const timeAgo = new TimeAgo('en-US'); const { activeSigner, activeAccount } = useInkathon(); - const { toastError, toastSuccess, toastInfo, toastWarning } = useToast(); + const { toastError, toastSuccess, toastInfo } = useToast(); - const [saleEndTimestamp, setSaleEndTimestamp] = useState(0); - const { saleInfo, config, loading } = useSaleInfo(); + const { saleInfo, loading } = useSaleInfo(); const { state: { api, apiState, symbol }, } = useCoretimeApi(); const { fetchRegions } = useRegions(); - const fetchBalance = useCallback( - async (api: ApiPromise, activeAccount: InjectedAccount) => { - const account = ( - await api.query.system.account(activeAccount.address) - ).toHuman() as any; - - const balance = parseHNString(account.data.free.toString()); - setBalance(balance); - - if (balance == 0) { - toastWarning( - `The selected account does not have any ${symbol} tokens on the Coretime chain.` - ); - } - }, - [toastWarning] - ); - - const fetchCurrentPhase = useCallback( - async (api: ApiPromise) => { - const blockNumber = (await api.query.system.number()).toJSON() as number; - const lastCommittedTimeslice = parseHNString( - ( - (await api.query.broker.status()).toHuman() as any - ).lastCommittedTimeslice.toString() - ); - - const _saleStart = getSaleStartInBlocks(saleInfo, config); - const _saleEnd = getSaleEndInBlocks( - saleInfo, - blockNumber, - lastCommittedTimeslice - ); - - setCurrentBlockNumber(blockNumber); - setSaleEnd(_saleEnd); - getBlockTimestamp(api, _saleEnd).then((value) => - setSaleEndTimestamp(value) - ); - - const progress = getSaleProgress( - saleInfo, - config, - blockNumber, - lastCommittedTimeslice - ); - setProgress(progress); - - setCurrentPhase(getCurrentPhase(saleInfo, blockNumber)); - - const saleDuration = _saleEnd - _saleStart; - - setSaleSections([ - { name: 'Interlude', value: 0 }, - { - name: 'Leadin phase', - value: (config.interludeLength / saleDuration) * 100, - }, - { - name: 'Fixed price phase', - value: - ((config.interludeLength + config.leadinLength) / saleDuration) * - 100, - }, - ]); - }, - [saleInfo, config] - ); - - const fetchCurreentPrice = useCallback( - async (api: ApiPromise) => { - const blockNumber = (await api.query.system.number()).toJSON() as number; - - const price = getCurrentPrice(saleInfo, blockNumber); - setCurrentPrice(price); - }, - [saleInfo] - ); + const balance = useBalance(); + const currentPrice = useSalePrice(); + const { + currentPhase, + progress, + saleStartTimestamp, + saleEndTimestamp, + saleSections, + } = useSalePhase(); const purchase = async () => { if (!api || apiState !== ApiState.READY || !activeAccount || !activeSigner) @@ -172,19 +80,6 @@ const Purchase = () => { } }; - useEffect(() => { - if (!api || apiState !== ApiState.READY) return; - - fetchCurrentPhase(api); - fetchCurreentPrice(api); - }, [api, apiState, fetchCurreentPrice, fetchCurrentPhase]); - - useEffect(() => { - if (!api || apiState !== ApiState.READY || !activeAccount) return; - - fetchBalance(api, activeAccount); - }, [api, apiState, activeAccount, fetchBalance]); - return ( { {loading || - !currentPhase || - !saleEnd || - !currentBlockNumber || - !progress || - !saleEndTimestamp ? ( + !currentPhase || + !progress || + !saleStartTimestamp || + !saleEndTimestamp ? ( <> Connect your wallet @@ -234,7 +128,8 @@ const Purchase = () => { currentPhase={currentPhase} currentPrice={currentPrice} saleInfo={saleInfo} - saleEnd={saleEnd} + saleStartTimestamp={saleStartTimestamp} + saleEndTimestamp={saleEndTimestamp} /> Date: Tue, 23 Apr 2024 09:08:33 +0200 Subject: [PATCH 5/6] Network selection (#72) * Network selection * progress * format * .. * working * fix style * lint fixes * width * fix * linting errors * working but a mess * cleanup * more cleanup * .. * small fixes * merge fix * fix issue --- .env.example | 6 ++- Dockerfile | 4 +- next.config.js | 6 ++- src/components/Elements/FeatureCard/index.tsx | 4 +- .../Elements/NetworkSelect/index.tsx | 35 +++++++++++++++++ src/components/Header/index.tsx | 12 +----- src/components/Sidebar/index.module.scss | 7 +++- src/components/Sidebar/index.tsx | 8 +++- src/contexts/apis/CoretimeApi/index.tsx | 33 +++++++++++----- src/contexts/apis/RelayApi/index.tsx | 33 ++++++++++++---- src/contexts/apis/common.ts | 27 ++++++++----- src/contexts/apis/consts.ts | 8 +++- src/contexts/sales/index.tsx | 9 ++++- src/contexts/tasks/index.tsx | 14 ++++++- src/hooks/salePhase.tsx | 15 ++++++-- src/pages/_app.tsx | 24 +++++++++++- src/pages/purchase.tsx | 8 ++-- src/utils/functions.ts | 38 ++++++++++--------- src/utils/sale/utils.test.ts | 17 ++++++--- src/utils/sale/utils.ts | 29 ++++++++------ 20 files changed, 239 insertions(+), 98 deletions(-) create mode 100644 src/components/Elements/NetworkSelect/index.tsx diff --git a/.env.example b/.env.example index 5c2e725f..30aa77da 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,4 @@ -WS_CORETIME_CHAIN="WSS endpoint of the coretime chain" -WS_RELAY_CHAIN="WSS endpoint of the coretime relay chain" +WS_ROCOCO_CORETIME_CHAIN="WSS endpoint of the coretime chain" +WS_KUSAMA_CORETIME_CHAIN="WSS endpoint of the coretime chain" +WS_ROCOCO_RELAY_CHAIN="WSS endpoint of the coretime relay chain" +WS_KUSAMA_RELAY_CHAIN="WSS endpoint of the coretime relay chain" diff --git a/Dockerfile b/Dockerfile index ec8f1dfc..6c7364b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,8 @@ WORKDIR /corehub COPY . . # Set the necessary environment variables -ENV WS_CORETIME_CHAIN="ws://127.0.0.1:9910" -ENV WS_RELAY_CHAIN="ws://127.0.0.1:9900" +ENV WS_ROCOCO_CORETIME_CHAIN="ws://127.0.0.1:9910" +ENV WS_ROCOCO_RELAY_CHAIN="ws://127.0.0.1:9900" RUN apk add --no-cache libc6-compat diff --git a/next.config.js b/next.config.js index 7bee534b..5ab342eb 100644 --- a/next.config.js +++ b/next.config.js @@ -5,8 +5,10 @@ const nextConfig = { domains: ['github.com'], }, env: { - WS_CORETIME_CHAIN: process.env.WS_CORETIME_CHAIN || '', - WS_RELAY_CHAIN: process.env.WS_RELAY_CHAIN, + WS_ROCOCO_CORETIME_CHAIN: process.env.WS_ROCOCO_CORETIME_CHAIN || '', + WS_KUSAMA_CORETIME_CHAIN: process.env.WS_KUSAMA_CORETIME_CHAIN || '', + WS_ROCOCO_RELAY_CHAIN: process.env.WS_ROCOCO_RELAY_CHAIN, + WS_KUSAMA_RELAY_CHAIN: process.env.WS_KUSAMA_RELAY_CHAIN, }, }; diff --git a/src/components/Elements/FeatureCard/index.tsx b/src/components/Elements/FeatureCard/index.tsx index bd54f7cc..c9c5d9bb 100644 --- a/src/components/Elements/FeatureCard/index.tsx +++ b/src/components/Elements/FeatureCard/index.tsx @@ -27,7 +27,7 @@ export const FeatureCard = ({ enabled, href, }: FeatureCardProps) => { - const { push } = useRouter(); + const { push, query } = useRouter(); const theme = useTheme(); return ( @@ -40,7 +40,7 @@ export const FeatureCard = ({ + ); +}; diff --git a/src/components/Elements/Buttons/ProgressButton/index.module.scss b/src/components/Elements/Buttons/ProgressButton/index.module.scss new file mode 100644 index 00000000..41e71bf8 --- /dev/null +++ b/src/components/Elements/Buttons/ProgressButton/index.module.scss @@ -0,0 +1,8 @@ +.buttonContainer { + background:linear-gradient(180deg, #E84D68 0%, #AD2B49 100%); + border-radius: 100px; + font-weight: 500; + text-transform: none; + padding: 0.5rem 1.25rem; + font-size: 0.8rem; +} \ No newline at end of file diff --git a/src/components/Elements/Buttons/ProgressButton/index.tsx b/src/components/Elements/Buttons/ProgressButton/index.tsx new file mode 100644 index 00000000..29175669 --- /dev/null +++ b/src/components/Elements/Buttons/ProgressButton/index.tsx @@ -0,0 +1,25 @@ +import { LoadingButton } from '@mui/lab'; + +import styles from './index.module.scss'; + +interface ProgressButtonProps { + label: string; + onClick: () => void; + loading: boolean; +} +export const ProgressButton = ({ + label, + onClick, + loading, +}: ProgressButtonProps) => { + return ( + + {label} + + ); +}; diff --git a/src/components/Elements/Buttons/index.tsx b/src/components/Elements/Buttons/index.tsx new file mode 100644 index 00000000..1a65d096 --- /dev/null +++ b/src/components/Elements/Buttons/index.tsx @@ -0,0 +1,2 @@ +export * from './ActionButton'; +export * from './ProgressButton'; diff --git a/src/components/Elements/CoreDetailsPanel/index.module.scss b/src/components/Elements/CoreDetailsPanel/index.module.scss new file mode 100644 index 00000000..9fe0fd9e --- /dev/null +++ b/src/components/Elements/CoreDetailsPanel/index.module.scss @@ -0,0 +1,39 @@ +.container { + display: flex; + flex-direction: column; + gap: 2rem; + padding: 1.5rem; + flex-grow: 1; + box-shadow: 2px 2px 55px rgba(0, 0, 0, 0.08); +} + +.titleWrapper { + display: flex; + align-items: center; +} + +.iconWrapper { + width: 1.5rem; + height: 1.5rem; + margin: 0.5rem; +} + +.infoWrapper { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.detailWrapper { + display: flex; + justify-content: space-between; + padding: 1.5rem; +} + +.valueWrapper { + background: #ecf1f9; + padding: 0.5rem 0.75rem; + border-radius: 0.5rem; + display: flex; + align-items: center; +} diff --git a/src/components/Elements/CoreDetailsPanel/index.tsx b/src/components/Elements/CoreDetailsPanel/index.tsx new file mode 100644 index 00000000..0969d133 --- /dev/null +++ b/src/components/Elements/CoreDetailsPanel/index.tsx @@ -0,0 +1,94 @@ +import { Box, Paper, Typography, useTheme } from '@mui/material'; +import Image from 'next/image'; + +import GraphIcon from '@/assets/graph.png'; +import { SaleInfo } from '@/models'; + +import styles from './index.module.scss'; + +interface DetailItemProps { + label: string; + description: string; + value: number; +} + +const DetailItem = ({ label, description, value }: DetailItemProps) => { + const theme = useTheme(); + return ( + + + + {label} + + + {description} + + + + + {value} + + + + ); +}; + +interface CoreDetailsPanelProps { + saleInfo: SaleInfo; +} + +export const CoreDetailsPanel = ({ saleInfo }: CoreDetailsPanelProps) => { + const theme = useTheme(); + return ( + + + graph + + Core Details + + + + + + + + + ); +}; diff --git a/src/components/Elements/SaleInfo/index.tsx b/src/components/Elements/SaleInfo/index.tsx deleted file mode 100644 index 338e29a3..00000000 --- a/src/components/Elements/SaleInfo/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Box, Typography } from '@mui/material'; -import TimeAgo from 'javascript-time-ago'; -import en from 'javascript-time-ago/locale/en.json'; - -import { formatBalance } from '@/utils/functions'; - -import { useCoretimeApi } from '@/contexts/apis'; -import { SaleInfo, SalePhase } from '@/models'; - -import styles from './index.module.scss'; - -interface SaleInfoGridProps { - saleInfo: SaleInfo; - currentPhase: SalePhase; - currentPrice: number; - saleEndTimestamp: number; - saleStartTimestamp: number; -} - -export const SaleInfoGrid = ({ - saleInfo, - currentPhase, - currentPrice, - saleEndTimestamp, - saleStartTimestamp, -}: SaleInfoGridProps) => { - TimeAgo.addLocale(en); - const timeAgo = new TimeAgo('en-US'); - - const { - state: { symbol }, - } = useCoretimeApi(); - - const nextPhase = (): SalePhase => { - const phases = Object.values(SalePhase); - const currentIndex = phases.indexOf(currentPhase); - - // Calculate the index of the next phase - const nextIndex = (currentIndex + 1) % phases.length; - return phases[nextIndex]; - }; - - return ( - - - - {`Sale start: ${timeAgo.format(saleStartTimestamp)}`} - - - {`Sale ends ${timeAgo.format(saleEndTimestamp)}`} - - - - {`Current phase: ${currentPhase}`} - {`Upcoming phase: ${nextPhase()}`} - - - - {`Current price: ${formatBalance(currentPrice.toString(), false)} ${symbol}`} - - - {`Floor price: ${formatBalance(saleInfo.price.toString(), false)} ${symbol}`} - - - - - - {`Cores offered: ${saleInfo.coresOffered}`} - - Number of cores which are offered for sale. - - - - - - {`Cores sold: ${saleInfo.coresSold}`} - - Number of cores which have been sold - - - - - - {`Ideal cores sold: ${saleInfo.idealCoresSold}`} - - - Number of cores sold to not affect the price for next sale - - - - - ); -}; diff --git a/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss b/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss new file mode 100644 index 00000000..4292c791 --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/DetailCard/index.module.scss @@ -0,0 +1,31 @@ +.container { + display: flex; + flex-direction: column; + padding: 1rem 2rem; + border-radius: .5rem; + gap: 1.5rem; +} + +.titleWrapper { + display: flex; + align-items: center; +} + +.iconWrapper { + margin: 0.5rem; + margin-left: 0; + width: 2rem; + height: 2rem; +} + +.infoSection { + display: flex; + align-items: center; + justify-content: space-between; +} + +.infoItem { + display: flex; + flex-direction: column; + gap: 0.5rem; +} \ No newline at end of file diff --git a/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx b/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx new file mode 100644 index 00000000..6da14b9e --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/DetailCard/index.tsx @@ -0,0 +1,49 @@ +import { Box, Paper, Typography, useTheme } from '@mui/material'; +import Image from 'next/image'; + +import styles from './index.module.scss'; + +interface ItemDetail { + label: string; + value: string; +} + +interface DetailCardProps { + icon: any; + title: string; + left: ItemDetail; + right: ItemDetail; +} + +const ItemContainer = ({ label, value }: ItemDetail) => { + const theme = useTheme(); + return ( + + {label} + + {value} + + + ); +}; + +export const DetailCard = ({ icon, title, left, right }: DetailCardProps) => { + const theme = useTheme(); + return ( + + + icon + + {title} + + + + + + + + ); +}; diff --git a/src/components/Elements/SaleInfo/index.module.scss b/src/components/Elements/SaleInfoPanel/index.module.scss similarity index 100% rename from src/components/Elements/SaleInfo/index.module.scss rename to src/components/Elements/SaleInfoPanel/index.module.scss diff --git a/src/components/Elements/SaleInfoPanel/index.tsx b/src/components/Elements/SaleInfoPanel/index.tsx new file mode 100644 index 00000000..305579cf --- /dev/null +++ b/src/components/Elements/SaleInfoPanel/index.tsx @@ -0,0 +1,86 @@ +import { Box } from '@mui/material'; +import TimeAgo from 'javascript-time-ago'; +import en from 'javascript-time-ago/locale/en.json'; +import moment from 'moment'; + +import { formatBalance } from '@/utils/functions'; + +import DollarIcon from '@/assets/dollar.png'; +import ListIcon from '@/assets/list.png'; +import ShoppingIcon from '@/assets/shopping.png'; +import { useCoretimeApi } from '@/contexts/apis'; +import { SaleInfo, SalePhase } from '@/models'; + +import { DetailCard } from './DetailCard'; + +interface SaleInfoGridProps { + saleInfo: SaleInfo; + currentPhase: SalePhase; + currentPrice: number; + saleEndTimestamp: number; + saleStartTimestamp: number; +} + +export const SaleInfoPanel = ({ + saleInfo, + currentPhase, + currentPrice, + saleEndTimestamp, + saleStartTimestamp, +}: SaleInfoGridProps) => { + TimeAgo.addLocale(en); + const { + state: { symbol }, + } = useCoretimeApi(); + + const nextPhase = (): SalePhase => { + const phases = Object.values(SalePhase); + const currentIndex = phases.indexOf(currentPhase); + + // Calculate the index of the next phase + const nextIndex = (currentIndex + 1) % phases.length; + return phases[nextIndex]; + }; + + return ( + + + + + + ); +}; diff --git a/src/components/Elements/index.ts b/src/components/Elements/index.ts index 6b96619d..0456f2fd 100644 --- a/src/components/Elements/index.ts +++ b/src/components/Elements/index.ts @@ -1,10 +1,13 @@ export * from './AmountInput'; export * from './Banner'; +export * from './Buttons'; +export * from './CoreDetailsPanel'; export * from './FeatureCard'; export * from './Label'; export * from './ListingCard'; export * from './MarketFilters'; export * from './Progress'; export * from './RegionCard'; -export * from './SaleInfo'; +export * from './SaleInfoPanel'; +export * from './Selectors'; export * from './StatusIndicator'; diff --git a/src/components/Header/index.module.scss b/src/components/Header/index.module.scss index 2e43aa2b..620a6f8c 100644 --- a/src/components/Header/index.module.scss +++ b/src/components/Header/index.module.scss @@ -21,8 +21,10 @@ } .listWrapper { - border-radius: 100px; - width: 240px; + display: flex; + flex-direction: column; + width: 15rem; + gap: 0; } .accountsWrapper { @@ -36,6 +38,7 @@ .accountsList { max-height: 300px; overflow-y: auto; + padding-bottom: 0; } .accountsList::-webkit-scrollbar { diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index f0dc27e2..7f033806 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,7 +1,6 @@ import { ExpandMore } from '@mui/icons-material'; import { Box, - Button, Collapse, Divider, List, @@ -12,6 +11,7 @@ import { useInkathon } from '@scio-labs/use-inkathon'; import React, { useState } from 'react'; import styles from './index.module.scss'; +import { ActionButton } from '../Elements'; import { WalletModal } from '../Modals/WalletConnect'; export const Header = () => { @@ -37,20 +37,32 @@ export const Header = () => { borderBottom: `1px solid ${theme.palette.divider}`, }} > -

+ {activeAccount ? ( {!accountsOpen && ( openAccounts(true)} - sx={{ justifyContent: 'space-between' }} + sx={{ + justifyContent: 'space-between', + background: theme.palette.background.default, + borderRadius: 4, + }} > {activeAccount.name} )} - + {accounts?.map( (account, index) => @@ -61,28 +73,35 @@ export const Header = () => { setActiveAccount && setActiveAccount(account); openAccounts(false); }} + sx={{ + borderRadius: '0.5rem', + background: theme.palette.grey['100'], + }} > {account.name} ) )} - - + + Disconnect ) : ( - + label='Connect Wallet' + /> )} -
+ {
- -
{children}
-
+
{children}
); diff --git a/src/components/index.ts b/src/components/index.ts index ea987eed..93333dfa 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,4 @@ export * from './Elements'; -export * from './Elements/Selectors'; export * from './Header'; export * from './Layout'; export * from './Modals'; diff --git a/src/pages/purchase.tsx b/src/pages/purchase.tsx index b91cca66..1fafe01d 100644 --- a/src/pages/purchase.tsx +++ b/src/pages/purchase.tsx @@ -1,4 +1,3 @@ -import { LoadingButton } from '@mui/lab'; import { Box, Button, Typography, useTheme } from '@mui/material'; import { useInkathon } from '@scio-labs/use-inkathon'; import TimeAgo from 'javascript-time-ago'; @@ -11,7 +10,7 @@ import useSalePhase from '@/hooks/salePhase'; import useSalePrice from '@/hooks/salePrice'; import { formatBalance } from '@/utils/functions'; -import { Progress, SaleInfoGrid } from '@/components'; +import { CoreDetailsPanel, ProgressButton, SaleInfoPanel } from '@/components'; import { useCoretimeApi } from '@/contexts/apis'; import { ApiState } from '@/contexts/apis/types'; @@ -25,7 +24,6 @@ const Purchase = () => { const [working, setWorking] = useState(false); TimeAgo.addLocale(en); // Create formatter (English). - const timeAgo = new TimeAgo('en-US'); const { activeSigner, activeAccount } = useInkathon(); const { toastError, toastSuccess, toastInfo } = useToast(); @@ -39,13 +37,8 @@ const Purchase = () => { const balance = useBalance(); const currentPrice = useSalePrice(); - const { - currentPhase, - progress, - saleStartTimestamp, - saleEndTimestamp, - saleSections, - } = useSalePhase(); + const { currentPhase, progress, saleStartTimestamp, saleEndTimestamp } = + useSalePhase(); const purchase = async () => { if (!api || apiState !== ApiState.READY || !activeAccount || !activeSigner) @@ -86,6 +79,7 @@ const Purchase = () => { sx={{ display: 'flex', justifyContent: 'space-between', + alignItems: 'center', }} > @@ -99,11 +93,14 @@ const Purchase = () => { variant='subtitle2' sx={{ color: theme.palette.text.primary }} > - Purchase a core directly from the Coretime chain + Buy a core straight from the Coretime chain - {`Your balance: ${formatBalance(balance.toString(), false)} ${symbol}`} + {`Your balance: ${formatBalance( + balance.toString(), + false + )} ${symbol}`} @@ -114,40 +111,24 @@ const Purchase = () => { !saleEndTimestamp ? ( <> - Connect your wallet + Check your network conection and connect your wallet ) : ( - <> - - - - - - Current Bulk Sale: - Ends {timeAgo.format(saleEndTimestamp)} - - - - + + + + + { - - Purchase - + label='Purchase Core' + /> - + )} diff --git a/src/pages/regions.tsx b/src/pages/regions.tsx index cfdfa542..5446d679 100644 --- a/src/pages/regions.tsx +++ b/src/pages/regions.tsx @@ -5,6 +5,7 @@ import { Box, Button, CircularProgress, + Paper, Typography, useTheme, } from '@mui/material'; @@ -176,11 +177,10 @@ const Dashboard = () => { )} - { ))} - + {regionSelected && ( <>