From 638e8f967b3f314ff5db51a7b0a18cd0a72024ec Mon Sep 17 00:00:00 2001 From: Sergej Date: Fri, 30 Aug 2024 15:16:40 +0200 Subject: [PATCH 1/8] renewal refactor --- README.md | 2 +- src/components/Layout/Sidebar/index.tsx | 2 +- src/hooks/renewableParas.ts | 2 +- src/pages/paras/index.tsx | 2 +- src/pages/paras/renewal.tsx | 295 ---------------------- src/pages/renew/action.tsx | 60 +++++ src/pages/renew/hooks/useRenewHandlers.ts | 10 + src/pages/renew/index.tsx | 70 +++++ src/pages/renew/info.tsx | 163 ++++++++++++ src/pages/renew/select.tsx | 43 ++++ 10 files changed, 350 insertions(+), 299 deletions(-) delete mode 100644 src/pages/paras/renewal.tsx create mode 100644 src/pages/renew/action.tsx create mode 100644 src/pages/renew/hooks/useRenewHandlers.ts create mode 100644 src/pages/renew/index.tsx create mode 100644 src/pages/renew/info.tsx create mode 100644 src/pages/renew/select.tsx diff --git a/README.md b/README.md index 15965466..23008ce6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The UI currently supports: - Parachain Id reservation - Parachain code registration -### `/paras/renewal` +### `/renew` - Core renewal ### `/marketplace` diff --git a/src/components/Layout/Sidebar/index.tsx b/src/components/Layout/Sidebar/index.tsx index 2f43bbc8..ba07db82 100644 --- a/src/components/Layout/Sidebar/index.tsx +++ b/src/components/Layout/Sidebar/index.tsx @@ -110,7 +110,7 @@ export const Sidebar = () => { parachains: [ { label: 'Renew', - route: '/paras/renewal', + route: '/renew', enabled: true, icon: , }, diff --git a/src/hooks/renewableParas.ts b/src/hooks/renewableParas.ts index b4ae5b87..c23340b0 100644 --- a/src/hooks/renewableParas.ts +++ b/src/hooks/renewableParas.ts @@ -7,7 +7,7 @@ import { ApiState } from '@/contexts/apis/types'; import { useNetwork } from '@/contexts/network'; import { ContextStatus, NetworkType } from '@/models'; -type RenewableParachain = { +export type RenewableParachain = { core: number; paraId: number; price: number; diff --git a/src/pages/paras/index.tsx b/src/pages/paras/index.tsx index 6c3e8252..22310ca6 100644 --- a/src/pages/paras/index.tsx +++ b/src/pages/paras/index.tsx @@ -69,7 +69,7 @@ const ParachainManagement = () => { // Renew coretime with the given para id const onRenew = (paraId: number) => { router.push({ - pathname: 'paras/renewal', + pathname: 'renew', query: { network, paraId }, }); }; diff --git a/src/pages/paras/renewal.tsx b/src/pages/paras/renewal.tsx deleted file mode 100644 index fa4e48a0..00000000 --- a/src/pages/paras/renewal.tsx +++ /dev/null @@ -1,295 +0,0 @@ -import { - Backdrop, - Box, - CircularProgress, - FormControl, - InputLabel, - MenuItem, - Paper, - Select, - Stack, - Tooltip, - Typography, - useTheme, -} from '@mui/material'; -import { humanizer } from 'humanize-duration'; -import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; - -import { useRenewableParachains } from '@/hooks/renewableParas'; -import { useSubmitExtrinsic } from '@/hooks/submitExtrinsic'; -import { getBalanceString, timesliceToTimestamp } from '@/utils/functions'; - -import { Balance, Banner, ParaDisplay, ProgressButton } from '@/components'; - -import { useAccounts } from '@/contexts/account'; -import { useCoretimeApi, useRelayApi } from '@/contexts/apis'; -import { useNetwork } from '@/contexts/network'; -import { useSaleInfo } from '@/contexts/sales'; -import { useToast } from '@/contexts/toast'; -import { ContextStatus } from '@/models'; - -const Renewal = () => { - const router = useRouter(); - const theme = useTheme(); - - const { - state: { activeAccount, activeSigner }, - } = useAccounts(); - const { status, parachains } = useRenewableParachains(); - const { saleInfo, saleStatus, status: saleInfoStatus, phase } = useSaleInfo(); - - const { - state: { api: relayApi, isApiReady: isRelayReady }, - } = useRelayApi(); - const { - state: { api: coretimeApi, isApiReady: isCoretimeReady, decimals, symbol }, - timeslicePeriod, - } = useCoretimeApi(); - - const { toastError, toastInfo, toastSuccess } = useToast(); - const { network } = useNetwork(); - const { submitExtrinsicWithFeeInfo } = useSubmitExtrinsic(); - - const [loading, setLoading] = useState(false); - const [activeIdx, setActiveIdx] = useState(0); - const [working, setWorking] = useState(false); - const [expiryTimestamp, setExpiryTimestamp] = useState(0); - - const formatDuration = humanizer({ units: ['w', 'd', 'h'], round: true }); - - const handleRenew = () => { - if (!activeAccount || !coretimeApi || !isCoretimeReady || !activeSigner) return; - - const { core } = parachains[activeIdx]; - - const txRenewal = coretimeApi.tx.broker.renew(core); - submitExtrinsicWithFeeInfo(symbol, decimals, txRenewal, activeAccount.address, activeSigner, { - ready: () => { - setWorking(true); - toastInfo('Transaction was initiated'); - }, - inBlock: () => toastInfo('In Block'), - finalized: () => setWorking(false), - success: () => { - toastSuccess('Successfully renewed the selected parachain'); - }, - fail: () => { - toastError(`Failed to renew the selected parachain`); - }, - error: (e) => { - toastError(`Failed to renew the selected parachain ${e}`); - setWorking(false); - }, - }); - }; - - useEffect(() => { - const getExpiry = async () => { - setLoading(true); - if ( - !coretimeApi || - !isCoretimeReady || - !relayApi || - !isRelayReady || - !parachains[activeIdx] || - saleInfoStatus !== ContextStatus.LOADED - ) - return; - - const now = await timesliceToTimestamp( - relayApi, - saleStatus.lastCommittedTimeslice, - timeslicePeriod - ); - const expiry = await timesliceToTimestamp( - relayApi, - parachains[activeIdx].when, - timeslicePeriod - ); - - if (expiry - now < 0) { - setExpiryTimestamp(phase.endpoints.fixed.end - now); - } else { - setExpiryTimestamp(expiry - now); - } - - setLoading(false); - }; - - getExpiry(); - }, [ - coretimeApi, - isCoretimeReady, - relayApi, - isRelayReady, - activeIdx, - parachains, - timeslicePeriod, - saleInfoStatus, - saleStatus, - phase, - ]); - - useEffect(() => { - if (!router.isReady || status !== ContextStatus.LOADED || parachains.length === 0) return; - const { query } = router; - if (query['paraId'] === undefined) return; - const paraId = parseInt(query['paraId'] as string); - const index = parachains.findIndex((para) => para.paraId == paraId); - if (index === -1) { - toastError(`No renewable parachain found with ID = ${paraId}`); - return; - } - setActiveIdx(index); - }, [router, parachains, status, parachains.length, toastError]); - - return status !== ContextStatus.LOADED ? ( - - - - ) : parachains.length === 0 ? ( - There are no renewable parachains. - ) : ( - <> - - - - Renew a parachain - - - Renew a parachain - - - - - - - - - - Select a parachain to renew - - - Parachain - - - - - - - - - {saleInfo.coresSold === saleInfo.coresOffered && ( - - - - )} - {/* If not all cores are sold inform the user: */} - {saleInfo.coresSold < saleInfo.coresOffered && ( - - - - )} - - - - - - - ); -}; - -interface PropertyProps { - property: string; - value: any; - tooltip?: string; -} - -export const Property = ({ property, value, tooltip }: PropertyProps) => { - return ( - - - {property} - - - {tooltip && ( - - - ⓘ - - - )} - - {value} - - - - ); -}; - -export default Renewal; diff --git a/src/pages/renew/action.tsx b/src/pages/renew/action.tsx new file mode 100644 index 00000000..570a6746 --- /dev/null +++ b/src/pages/renew/action.tsx @@ -0,0 +1,60 @@ +import { ProgressButton } from "@/components" +import { useCoretimeApi, useRelayApi } from "@/contexts/apis"; +import { Stack } from "@mui/material" +import { useState } from "react"; +import { useToast } from '@/contexts/toast'; +import { useAccounts } from "@/contexts/account"; +import { RenewableParachain } from "@/hooks"; +import { useSubmitExtrinsic } from "@/hooks/submitExtrinsic"; + +interface RenewActionProps { + parachain: RenewableParachain, +} + +export const RenewAction = ({ parachain }: RenewActionProps) => { + const [working, setWorking] = useState(false); + + const { + state: { activeAccount, activeSigner }, + } = useAccounts(); + const { + state: { api: coretimeApi, isApiReady: isCoretimeReady, decimals, symbol }, + } = useCoretimeApi(); + + const { toastError, toastInfo, toastSuccess } = useToast(); + const { submitExtrinsicWithFeeInfo } = useSubmitExtrinsic(); + + const handleRenew = () => { + if (!activeAccount || !coretimeApi || !isCoretimeReady || !activeSigner) return; + + const { core } = parachain; + + const txRenewal = coretimeApi.tx.broker.renew(core); + submitExtrinsicWithFeeInfo(symbol, decimals, txRenewal, activeAccount.address, activeSigner, { + ready: () => { + setWorking(true); + toastInfo('Transaction was initiated'); + }, + inBlock: () => toastInfo('In Block'), + finalized: () => setWorking(false), + success: () => { + toastSuccess('Successfully renewed the selected parachain'); + }, + fail: () => { + toastError(`Failed to renew the selected parachain`); + }, + error: (e) => { + toastError(`Failed to renew the selected parachain ${e}`); + setWorking(false); + }, + }); + }; + + return ( + <> + + + + + ) +} diff --git a/src/pages/renew/hooks/useRenewHandlers.ts b/src/pages/renew/hooks/useRenewHandlers.ts new file mode 100644 index 00000000..b48e4123 --- /dev/null +++ b/src/pages/renew/hooks/useRenewHandlers.ts @@ -0,0 +1,10 @@ +import { useState } from "react"; + +export const useRenewHandlers = () => { + const [activeIdx, setActiveIdx] = useState(0); + + return { + activeIdx, + setActiveIdx, + } +} diff --git a/src/pages/renew/index.tsx b/src/pages/renew/index.tsx new file mode 100644 index 00000000..9bbd0517 --- /dev/null +++ b/src/pages/renew/index.tsx @@ -0,0 +1,70 @@ +import { + Backdrop, + Box, + CircularProgress, + Paper, + Typography, + useTheme, +} from '@mui/material'; +import { useState } from 'react'; + +import { useRenewableParachains } from '@/hooks/renewableParas'; + +import { Balance } from '@/components'; + +import { ContextStatus } from '@/models'; +import { SelectParachain } from './select'; +import { RenewableParaInfo } from './info'; +import { RenewAction } from './action'; + +const Renewal = () => { + const theme = useTheme(); + + const [activeIdx, setActiveIdx] = useState(0); + const { status, parachains } = useRenewableParachains(); + + return status !== ContextStatus.LOADED ? ( + + + + ) : parachains.length === 0 ? ( + There are no renewable parachains. + ) : ( + <> + + + + Renew a parachain + + + Renew a parachain + + + + + + + + + + + + + + ); +}; + +export default Renewal; diff --git a/src/pages/renew/info.tsx b/src/pages/renew/info.tsx new file mode 100644 index 00000000..cd75355f --- /dev/null +++ b/src/pages/renew/info.tsx @@ -0,0 +1,163 @@ +import theme from "@/utils/muiTheme"; +import { Box, Stack, Tooltip, Typography } from "@mui/material"; +import { RenewableParachain } from "@/hooks"; +import { getBalanceString, timesliceToTimestamp } from "@/utils/functions"; +import { useEffect, useState } from "react"; +import { useCoretimeApi, useRelayApi } from "@/contexts/apis"; +import { useSaleInfo } from "@/contexts/sales"; +import { ContextStatus } from "@/models"; +import { Banner } from "@/components"; +import { humanizer } from "humanize-duration"; + +interface RenewableParaInfoProps { + parachain: RenewableParachain, +} + +export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { + const [expiryTimestamp, setExpiryTimestamp] = useState(0); + + const { saleInfo, saleStatus, status: saleInfoStatus, phase } = useSaleInfo(); + + const { + state: { api: relayApi, isApiReady: isRelayReady }, + } = useRelayApi(); + const { + state: { api: coretimeApi, isApiReady: isCoretimeReady, decimals, symbol }, + timeslicePeriod, + } = useCoretimeApi(); + + const [loading, setLoading] = useState(false); + + const formatDuration = humanizer({ units: ['w', 'd', 'h'], round: true }); + + useEffect(() => { + const getExpiry = async () => { + setLoading(true); + if ( + !coretimeApi || + !isCoretimeReady || + !relayApi || + !isRelayReady || + !parachain || + saleInfoStatus !== ContextStatus.LOADED + ) + return; + + const now = await timesliceToTimestamp( + relayApi, + saleStatus.lastCommittedTimeslice, + timeslicePeriod + ); + const expiry = await timesliceToTimestamp( + relayApi, + parachain.when, + timeslicePeriod + ); + + if (expiry - now < 0) { + setExpiryTimestamp(phase.endpoints.fixed.end - now); + } else { + setExpiryTimestamp(expiry - now); + } + + setLoading(false); + }; + + getExpiry(); + }, [ + coretimeApi, + isCoretimeReady, + relayApi, + isRelayReady, + timeslicePeriod, + saleInfoStatus, + saleStatus, + phase, + ]); + + return ( + <> + + + + + + + + {saleInfo.coresSold === saleInfo.coresOffered && ( + + + + )} + {/* If not all cores are sold inform the user: */} + {saleInfo.coresSold < saleInfo.coresOffered && ( + + + + )} + + ) +} + +interface PropertyProps { + property: string; + value: any; + tooltip?: string; +} + +const Property = ({ property, value, tooltip }: PropertyProps) => { + return ( + + + {property} + + + {tooltip && ( + + + ⓘ + + + )} + + {value} + + + + ); +}; diff --git a/src/pages/renew/select.tsx b/src/pages/renew/select.tsx new file mode 100644 index 00000000..e339298d --- /dev/null +++ b/src/pages/renew/select.tsx @@ -0,0 +1,43 @@ +import { ParaDisplay } from "@/components" +import { useNetwork } from "@/contexts/network" +import { RenewableParachain } from "@/hooks" +import theme from "@/utils/muiTheme" +import { FormControl, InputLabel, MenuItem, Select, Stack, Typography } from "@mui/material" + +interface SelectParachainProps { + parachains: RenewableParachain[], + activeIdx: number, + setActiveIdx: (_: number) => void, +} + +export const SelectParachain = ({ parachains, activeIdx, setActiveIdx }: SelectParachainProps) => { + const { network } = useNetwork(); + + return ( + + + Select a parachain to renew + + + Parachain + + + + ) +} From c0a24c08e5a874e631f21a928a23caf5f7890187 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 15:54:22 +0200 Subject: [PATCH 2/8] lint & format --- src/pages/renew/action.tsx | 23 ++++++++------- src/pages/renew/hooks/useRenewHandlers.ts | 6 ++-- src/pages/renew/index.tsx | 20 ++++++------- src/pages/renew/info.tsx | 35 +++++++++++------------ src/pages/renew/select.tsx | 25 +++++++++------- 5 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/pages/renew/action.tsx b/src/pages/renew/action.tsx index 570a6746..de5ab824 100644 --- a/src/pages/renew/action.tsx +++ b/src/pages/renew/action.tsx @@ -1,14 +1,17 @@ -import { ProgressButton } from "@/components" -import { useCoretimeApi, useRelayApi } from "@/contexts/apis"; -import { Stack } from "@mui/material" -import { useState } from "react"; +import { Stack } from '@mui/material'; +import { useState } from 'react'; + +import { RenewableParachain } from '@/hooks'; +import { useSubmitExtrinsic } from '@/hooks/submitExtrinsic'; + +import { ProgressButton } from '@/components'; + +import { useAccounts } from '@/contexts/account'; +import { useCoretimeApi } from '@/contexts/apis'; import { useToast } from '@/contexts/toast'; -import { useAccounts } from "@/contexts/account"; -import { RenewableParachain } from "@/hooks"; -import { useSubmitExtrinsic } from "@/hooks/submitExtrinsic"; interface RenewActionProps { - parachain: RenewableParachain, + parachain: RenewableParachain; } export const RenewAction = ({ parachain }: RenewActionProps) => { @@ -56,5 +59,5 @@ export const RenewAction = ({ parachain }: RenewActionProps) => { - ) -} + ); +}; diff --git a/src/pages/renew/hooks/useRenewHandlers.ts b/src/pages/renew/hooks/useRenewHandlers.ts index b48e4123..75811349 100644 --- a/src/pages/renew/hooks/useRenewHandlers.ts +++ b/src/pages/renew/hooks/useRenewHandlers.ts @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState } from 'react'; export const useRenewHandlers = () => { const [activeIdx, setActiveIdx] = useState(0); @@ -6,5 +6,5 @@ export const useRenewHandlers = () => { return { activeIdx, setActiveIdx, - } -} + }; +}; diff --git a/src/pages/renew/index.tsx b/src/pages/renew/index.tsx index 9bbd0517..a8be6687 100644 --- a/src/pages/renew/index.tsx +++ b/src/pages/renew/index.tsx @@ -1,11 +1,4 @@ -import { - Backdrop, - Box, - CircularProgress, - Paper, - Typography, - useTheme, -} from '@mui/material'; +import { Backdrop, Box, CircularProgress, Paper, Typography, useTheme } from '@mui/material'; import { useState } from 'react'; import { useRenewableParachains } from '@/hooks/renewableParas'; @@ -13,9 +6,10 @@ import { useRenewableParachains } from '@/hooks/renewableParas'; import { Balance } from '@/components'; import { ContextStatus } from '@/models'; -import { SelectParachain } from './select'; -import { RenewableParaInfo } from './info'; + import { RenewAction } from './action'; +import { RenewableParaInfo } from './info'; +import { SelectParachain } from './select'; const Renewal = () => { const theme = useTheme(); @@ -58,7 +52,11 @@ const Renewal = () => { boxShadow: 'none', }} > - + diff --git a/src/pages/renew/info.tsx b/src/pages/renew/info.tsx index cd75355f..04915f09 100644 --- a/src/pages/renew/info.tsx +++ b/src/pages/renew/info.tsx @@ -1,16 +1,19 @@ -import theme from "@/utils/muiTheme"; -import { Box, Stack, Tooltip, Typography } from "@mui/material"; -import { RenewableParachain } from "@/hooks"; -import { getBalanceString, timesliceToTimestamp } from "@/utils/functions"; -import { useEffect, useState } from "react"; -import { useCoretimeApi, useRelayApi } from "@/contexts/apis"; -import { useSaleInfo } from "@/contexts/sales"; -import { ContextStatus } from "@/models"; -import { Banner } from "@/components"; -import { humanizer } from "humanize-duration"; +import { Box, Stack, Tooltip, Typography } from '@mui/material'; +import { humanizer } from 'humanize-duration'; +import { useEffect, useState } from 'react'; + +import { RenewableParachain } from '@/hooks'; +import { getBalanceString, timesliceToTimestamp } from '@/utils/functions'; +import theme from '@/utils/muiTheme'; + +import { Banner } from '@/components'; + +import { useCoretimeApi, useRelayApi } from '@/contexts/apis'; +import { useSaleInfo } from '@/contexts/sales'; +import { ContextStatus } from '@/models'; interface RenewableParaInfoProps { - parachain: RenewableParachain, + parachain: RenewableParachain; } export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { @@ -48,11 +51,7 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { saleStatus.lastCommittedTimeslice, timeslicePeriod ); - const expiry = await timesliceToTimestamp( - relayApi, - parachain.when, - timeslicePeriod - ); + const expiry = await timesliceToTimestamp(relayApi, parachain.when, timeslicePeriod); if (expiry - now < 0) { setExpiryTimestamp(phase.endpoints.fixed.end - now); @@ -131,8 +130,8 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { )} - ) -} + ); +}; interface PropertyProps { property: string; diff --git a/src/pages/renew/select.tsx b/src/pages/renew/select.tsx index e339298d..db43f850 100644 --- a/src/pages/renew/select.tsx +++ b/src/pages/renew/select.tsx @@ -1,13 +1,16 @@ -import { ParaDisplay } from "@/components" -import { useNetwork } from "@/contexts/network" -import { RenewableParachain } from "@/hooks" -import theme from "@/utils/muiTheme" -import { FormControl, InputLabel, MenuItem, Select, Stack, Typography } from "@mui/material" +import { FormControl, InputLabel, MenuItem, Select, Stack, Typography } from '@mui/material'; + +import { RenewableParachain } from '@/hooks'; +import theme from '@/utils/muiTheme'; + +import { ParaDisplay } from '@/components'; + +import { useNetwork } from '@/contexts/network'; interface SelectParachainProps { - parachains: RenewableParachain[], - activeIdx: number, - setActiveIdx: (_: number) => void, + parachains: RenewableParachain[]; + activeIdx: number; + setActiveIdx: (_: number) => void; } export const SelectParachain = ({ parachains, activeIdx, setActiveIdx }: SelectParachainProps) => { @@ -38,6 +41,6 @@ export const SelectParachain = ({ parachains, activeIdx, setActiveIdx }: SelectP ))} - - ) -} + + ); +}; From 87b8dbe925b8c22097baed7bbe6eee5877808e1a Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 19:27:01 +0200 Subject: [PATCH 3/8] info cleanup --- src/pages/renew/info.tsx | 83 ++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/pages/renew/info.tsx b/src/pages/renew/info.tsx index 04915f09..45b6a38b 100644 --- a/src/pages/renew/info.tsx +++ b/src/pages/renew/info.tsx @@ -31,8 +31,6 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { const [loading, setLoading] = useState(false); - const formatDuration = humanizer({ units: ['w', 'd', 'h'], round: true }); - useEffect(() => { const getExpiry = async () => { setLoading(true); @@ -76,30 +74,10 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { return ( <> - - - - - - - - {saleInfo.coresSold === saleInfo.coresOffered && ( - + + + {/* If all cores are sold warn the user: */} + {saleInfo.coresSold === saleInfo.coresOffered && ( { }} severity='warning' /> - - )} - {/* If not all cores are sold inform the user: */} - {saleInfo.coresSold < saleInfo.coresOffered && ( - + )} + {/* If not all cores are sold inform the user to renew: */} + {saleInfo.coresSold < saleInfo.coresOffered && ( { }} severity='info' /> - - )} + )} + + + ); +}; + +interface ParachainInfoProps { + parachain: RenewableParachain; + expiryTimestamp: number; + expiryLoading: boolean; +} + +const ParachainInfo = ({ parachain, expiryTimestamp, expiryLoading }: ParachainInfoProps) => { + const { + state: { decimals, symbol }, + } = useCoretimeApi(); + + const formatDuration = humanizer({ units: ['w', 'd', 'h'], round: true }); + + return ( + <> + + + + + ); }; interface PropertyProps { property: string; - value: any; + value: string; tooltip?: string; } From 3b092f1e880eea88e202a6ea19db91f6485183d7 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 19:31:35 +0200 Subject: [PATCH 4/8] format & improvements --- src/pages/renew/info.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pages/renew/info.tsx b/src/pages/renew/info.tsx index 45b6a38b..9cd21e84 100644 --- a/src/pages/renew/info.tsx +++ b/src/pages/renew/info.tsx @@ -25,13 +25,16 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { state: { api: relayApi, isApiReady: isRelayReady }, } = useRelayApi(); const { - state: { api: coretimeApi, isApiReady: isCoretimeReady, decimals, symbol }, + state: { api: coretimeApi, isApiReady: isCoretimeReady }, timeslicePeriod, } = useCoretimeApi(); const [loading, setLoading] = useState(false); useEffect(() => { + // No need to keep refreshing + if (expiryTimestamp) return; + const getExpiry = async () => { setLoading(true); if ( @@ -75,7 +78,11 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { return ( <> - + {/* If all cores are sold warn the user: */} {saleInfo.coresSold === saleInfo.coresOffered && ( Date: Sat, 31 Aug 2024 20:53:44 +0200 Subject: [PATCH 5/8] improvements & cleanup --- src/hooks/renewableParas.ts | 1 + src/pages/renew/action.tsx | 11 +++- src/pages/renew/hooks/useRenewHandlers.ts | 10 ---- src/pages/renew/index.tsx | 8 ++- src/pages/renew/info.tsx | 70 +++++++++++++---------- 5 files changed, 55 insertions(+), 45 deletions(-) delete mode 100644 src/pages/renew/hooks/useRenewHandlers.ts diff --git a/src/hooks/renewableParas.ts b/src/hooks/renewableParas.ts index c23340b0..71f3958d 100644 --- a/src/hooks/renewableParas.ts +++ b/src/hooks/renewableParas.ts @@ -12,6 +12,7 @@ export type RenewableParachain = { paraId: number; price: number; mask: string; + // The point in time that the renewable workload on `core` ends and a fresh renewal may begin. when: number; }; diff --git a/src/pages/renew/action.tsx b/src/pages/renew/action.tsx index de5ab824..ad472abe 100644 --- a/src/pages/renew/action.tsx +++ b/src/pages/renew/action.tsx @@ -12,9 +12,10 @@ import { useToast } from '@/contexts/toast'; interface RenewActionProps { parachain: RenewableParachain; + enabled: boolean; } -export const RenewAction = ({ parachain }: RenewActionProps) => { +export const RenewAction = ({ parachain, enabled }: RenewActionProps) => { const [working, setWorking] = useState(false); const { @@ -56,7 +57,13 @@ export const RenewAction = ({ parachain }: RenewActionProps) => { return ( <> - + ); diff --git a/src/pages/renew/hooks/useRenewHandlers.ts b/src/pages/renew/hooks/useRenewHandlers.ts deleted file mode 100644 index 75811349..00000000 --- a/src/pages/renew/hooks/useRenewHandlers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useState } from 'react'; - -export const useRenewHandlers = () => { - const [activeIdx, setActiveIdx] = useState(0); - - return { - activeIdx, - setActiveIdx, - }; -}; diff --git a/src/pages/renew/index.tsx b/src/pages/renew/index.tsx index a8be6687..d5023b1f 100644 --- a/src/pages/renew/index.tsx +++ b/src/pages/renew/index.tsx @@ -15,6 +15,7 @@ const Renewal = () => { const theme = useTheme(); const [activeIdx, setActiveIdx] = useState(0); + const [renewalEnabled, setRenewalEnabled] = useState(true); const { status, parachains } = useRenewableParachains(); return status !== ContextStatus.LOADED ? ( @@ -57,8 +58,11 @@ const Renewal = () => { parachains={parachains} setActiveIdx={setActiveIdx} /> - - + + diff --git a/src/pages/renew/info.tsx b/src/pages/renew/info.tsx index 9cd21e84..e2e669c6 100644 --- a/src/pages/renew/info.tsx +++ b/src/pages/renew/info.tsx @@ -1,6 +1,6 @@ import { Box, Stack, Tooltip, Typography } from '@mui/material'; import { humanizer } from 'humanize-duration'; -import { useEffect, useState } from 'react'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { RenewableParachain } from '@/hooks'; import { getBalanceString, timesliceToTimestamp } from '@/utils/functions'; @@ -14,9 +14,10 @@ import { ContextStatus } from '@/models'; interface RenewableParaInfoProps { parachain: RenewableParachain; + setRenewalEnabled: Dispatch>; } -export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { +export const RenewableParaInfo = ({ parachain, setRenewalEnabled }: RenewableParaInfoProps) => { const [expiryTimestamp, setExpiryTimestamp] = useState(0); const { saleInfo, saleStatus, status: saleInfoStatus, phase } = useSaleInfo(); @@ -32,9 +33,6 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { const [loading, setLoading] = useState(false); useEffect(() => { - // No need to keep refreshing - if (expiryTimestamp) return; - const getExpiry = async () => { setLoading(true); if ( @@ -42,7 +40,6 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { !isCoretimeReady || !relayApi || !isRelayReady || - !parachain || saleInfoStatus !== ContextStatus.LOADED ) return; @@ -75,6 +72,11 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { phase, ]); + useEffect(() => { + // if expiry is before the next region begin it should be possible to renew. + setRenewalEnabled(parachain.when <= saleInfo.regionBegin); + }, [saleInfo.regionBegin, parachain.when]); + return ( <> @@ -83,33 +85,39 @@ export const RenewableParaInfo = ({ parachain }: RenewableParaInfoProps) => { expiryTimestamp={expiryTimestamp} expiryLoading={loading} /> - {/* If all cores are sold warn the user: */} - {saleInfo.coresSold === saleInfo.coresOffered && ( - saleInfo.regionBegin ? ( + + ) : ( + <> + {/* If all cores are sold warn the user: */} + {saleInfo.coresSold === saleInfo.coresOffered && ( + - )} - {/* If not all cores are sold inform the user to renew: */} - {saleInfo.coresSold < saleInfo.coresOffered && ( - + )} + {/* If not all cores are sold inform the user to renew: */} + {saleInfo.coresSold < saleInfo.coresOffered && ( + + } + link={{ + title: 'Renewal FAQ', + href: 'https://docs.regionx.tech/docs/faq/renewal-questions', + }} + severity='info' + /> + )} + )} From 57b94a7e5bf25662d6f799ceda0c37dbc83cf260 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 21:35:11 +0200 Subject: [PATCH 6/8] move to components --- src/{pages/renew => components/Renew}/action.tsx | 0 src/{pages/renew => components/Renew}/info.tsx | 0 src/{pages/renew/index.tsx => components/Renew/renewPage.tsx} | 0 src/{pages/renew => components/Renew}/select.tsx | 0 src/pages/renew.tsx | 2 ++ 5 files changed, 2 insertions(+) rename src/{pages/renew => components/Renew}/action.tsx (100%) rename src/{pages/renew => components/Renew}/info.tsx (100%) rename src/{pages/renew/index.tsx => components/Renew/renewPage.tsx} (100%) rename src/{pages/renew => components/Renew}/select.tsx (100%) create mode 100644 src/pages/renew.tsx diff --git a/src/pages/renew/action.tsx b/src/components/Renew/action.tsx similarity index 100% rename from src/pages/renew/action.tsx rename to src/components/Renew/action.tsx diff --git a/src/pages/renew/info.tsx b/src/components/Renew/info.tsx similarity index 100% rename from src/pages/renew/info.tsx rename to src/components/Renew/info.tsx diff --git a/src/pages/renew/index.tsx b/src/components/Renew/renewPage.tsx similarity index 100% rename from src/pages/renew/index.tsx rename to src/components/Renew/renewPage.tsx diff --git a/src/pages/renew/select.tsx b/src/components/Renew/select.tsx similarity index 100% rename from src/pages/renew/select.tsx rename to src/components/Renew/select.tsx diff --git a/src/pages/renew.tsx b/src/pages/renew.tsx new file mode 100644 index 00000000..82e9bd19 --- /dev/null +++ b/src/pages/renew.tsx @@ -0,0 +1,2 @@ +import RenewPage from '@/components/Renew/renewPage'; +export default RenewPage; From 3e4dc0cbdfbfcc66a09df619e8f0d7e9eb73d4c3 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 21:35:37 +0200 Subject: [PATCH 7/8] fix --- src/components/Renew/info.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Renew/info.tsx b/src/components/Renew/info.tsx index e2e669c6..55545200 100644 --- a/src/components/Renew/info.tsx +++ b/src/components/Renew/info.tsx @@ -62,6 +62,7 @@ export const RenewableParaInfo = ({ parachain, setRenewalEnabled }: RenewablePar getExpiry(); }, [ + parachain, coretimeApi, isCoretimeReady, relayApi, From 7b3e1a14147027d5e99c258a5eb6080b42df96c9 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 31 Aug 2024 21:40:18 +0200 Subject: [PATCH 8/8] format core --- src/components/Paras/ParaDisplay/index.tsx | 6 +++++- src/components/Renew/select.tsx | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/Paras/ParaDisplay/index.tsx b/src/components/Paras/ParaDisplay/index.tsx index 77c0e4d2..ea7db8f0 100644 --- a/src/components/Paras/ParaDisplay/index.tsx +++ b/src/components/Paras/ParaDisplay/index.tsx @@ -9,8 +9,10 @@ import Unknown from '../../../assets/unknown.svg'; interface ParaDisplayProps { paraId: number; network: NetworkType; + core?: number; } -export const ParaDisplay = ({ paraId, network }: ParaDisplayProps) => { + +export const ParaDisplay = ({ paraId, network, core }: ParaDisplayProps) => { const data = chainData[network][paraId]; if (data === undefined) @@ -18,6 +20,7 @@ export const ParaDisplay = ({ paraId, network }: ParaDisplayProps) => { Parachain #{paraId} + {core &&

| Core {core}

}
); @@ -32,6 +35,7 @@ export const ParaDisplay = ({ paraId, network }: ParaDisplayProps) => { )} {name}

#{paraId}

+ {core &&

| Core {core}

}
); }; diff --git a/src/components/Renew/select.tsx b/src/components/Renew/select.tsx index db43f850..d8193527 100644 --- a/src/components/Renew/select.tsx +++ b/src/components/Renew/select.tsx @@ -34,9 +34,9 @@ export const SelectParachain = ({ parachains, activeIdx, setActiveIdx }: SelectP value={activeIdx} onChange={(e) => setActiveIdx(Number(e.target.value))} > - {parachains.map(({ paraId }, index) => ( + {parachains.map(({ paraId, core }, index) => ( - + ))}