Merge branch 'hn.validator-onboarding' of github.com:nimbus-gui/nimbus-gui into ia.responsive-css
This commit is contained in:
commit
4dc83a834a
|
@ -1,12 +1,25 @@
|
|||
import { Stack, XStack, YStack } from 'tamagui'
|
||||
import { Input as StatusInput, Text } from '@status-im/components'
|
||||
import { AddIcon, ChevronDownIcon } from '@status-im/icons'
|
||||
import { useState } from 'react'
|
||||
|
||||
type SetupRowProps = {
|
||||
title: string
|
||||
}
|
||||
|
||||
const SetupRow = ({ title }: SetupRowProps) => {
|
||||
const [validatorCount, setValidatorCount] = useState(0)
|
||||
|
||||
const addValidatorHandler = () => {
|
||||
setValidatorCount((state: number) => state + 1)
|
||||
}
|
||||
|
||||
const changeValidatorCountHandler = (e: any) => {
|
||||
if (!isNaN(e.target.value)) {
|
||||
setValidatorCount(Number(e.target.value))
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$4'}>
|
||||
<Text size={19} weight={'semibold'}>
|
||||
|
@ -17,7 +30,12 @@ const SetupRow = ({ title }: SetupRowProps) => {
|
|||
<Text size={15} weight="regular" color={'#647084'}>
|
||||
How many Validators would you like to run?
|
||||
</Text>
|
||||
<StatusInput icon={<AddIcon size={16} />} />
|
||||
<StatusInput
|
||||
icon={<AddIcon size={16} style={{ cursor: 'pointer' }} onClick={addValidatorHandler} />}
|
||||
value={validatorCount.toString()}
|
||||
onChange={changeValidatorCountHandler}
|
||||
style={{ fontWeight: 'bold' }}
|
||||
/>
|
||||
</Stack>
|
||||
<YStack space={'$2'}>
|
||||
<Text size={15} weight={'semibold'} color="#09101C">
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
import { Stack, YStack } from 'tamagui'
|
||||
import { InformationBox, Input as StatusInput, Text } from '@status-im/components'
|
||||
import { ClearIcon, CloseCircleIcon } from '@status-im/icons'
|
||||
import { useState } from 'react'
|
||||
|
||||
type WithdrawalAddressProps = {
|
||||
title: string
|
||||
}
|
||||
|
||||
const WithdrawalAddress = ({ title }: WithdrawalAddressProps) => {
|
||||
const [withdrawalAddress, setWithdrawalAddress] = useState('')
|
||||
|
||||
const changeWithdrawalAddressHandler = (e: any) => {
|
||||
setWithdrawalAddress(e.target.value)
|
||||
}
|
||||
|
||||
const removeWithdrawalAddressHandler = () => {
|
||||
setWithdrawalAddress('')
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$4'}>
|
||||
<Text size={19} weight={'semibold'}>
|
||||
|
@ -20,7 +31,15 @@ const WithdrawalAddress = ({ title }: WithdrawalAddressProps) => {
|
|||
<StatusInput
|
||||
placeholder={'******************'}
|
||||
width={'100%'}
|
||||
icon={<ClearIcon size={16} />}
|
||||
icon={
|
||||
<ClearIcon
|
||||
size={16}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={removeWithdrawalAddressHandler}
|
||||
/>
|
||||
}
|
||||
value={withdrawalAddress}
|
||||
onChange={changeWithdrawalAddressHandler}
|
||||
/>
|
||||
</Stack>
|
||||
<InformationBox
|
||||
|
|
|
@ -8,13 +8,21 @@ import { RootState } from '../../redux/store'
|
|||
type ContinueButton = {
|
||||
continueHandler: () => void
|
||||
activeStep: number
|
||||
isConfirmPhraseStage: boolean
|
||||
}
|
||||
|
||||
const ContinueButton = ({ continueHandler, activeStep }: ContinueButton) => {
|
||||
const isCopyPastedPhrase = useSelector(
|
||||
(state: RootState) => state.keyGeneration.isCopyPastedPhrase,
|
||||
const ContinueButton = ({ continueHandler, activeStep, isConfirmPhraseStage }: ContinueButton) => {
|
||||
const { isCopyPastedPhrase, isRightPhrase } = useSelector(
|
||||
(state: RootState) => state.keyGeneration,
|
||||
)
|
||||
|
||||
const isDisabled = () => {
|
||||
if (isConfirmPhraseStage && !isRightPhrase) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
<XStack style={{ width: '100%', marginTop: '16px', zIndex: 999, alignItems: 'center' }}>
|
||||
<Stack style={{ width: '100%' }}>
|
||||
|
@ -35,7 +43,7 @@ const ContinueButton = ({ continueHandler, activeStep }: ContinueButton) => {
|
|||
marginTop: isCopyPastedPhrase ? '0px' : '40px',
|
||||
}}
|
||||
>
|
||||
<Button onPress={continueHandler} size={40}>
|
||||
<Button onPress={continueHandler} size={40} disabled={isDisabled()}>
|
||||
{activeStep < 5 ? 'Continue' : 'Continue to Dashboard'}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
|
|
@ -18,6 +18,7 @@ import ContinueButton from './ContinueButton'
|
|||
import { setIsCopyPastedPhrase } from '../../redux/ValidatorOnboarding/KeyGeneration/slice'
|
||||
import { RootState } from '../../redux/store'
|
||||
import './layoutGradient.css'
|
||||
import ActivationValidatorSetup from './ValidatorSetup/ActivationValidatorSetup'
|
||||
|
||||
const ValidatorOnboarding = () => {
|
||||
const [activeStep, setActiveStep] = useState(0)
|
||||
|
@ -37,7 +38,7 @@ const ValidatorOnboarding = () => {
|
|||
const continueHandler = () => {
|
||||
if (activeStep === 4 && isConfirmPhraseStage === false) {
|
||||
setIsConfirmPhraseStage(true)
|
||||
} else if (activeStep === 3 && subStepValidatorSetup < 2) {
|
||||
} else if (activeStep === 3 && subStepValidatorSetup < 3) {
|
||||
setSubStepValidatorSetup(subStepValidatorSetup + 1)
|
||||
} else if (activeStep < 5) {
|
||||
setActiveStep(activeStep + 1)
|
||||
|
@ -81,11 +82,16 @@ const ValidatorOnboarding = () => {
|
|||
{activeStep === 3 && subStepValidatorSetup === 0 && <ValidatorSetup />}
|
||||
{activeStep === 3 && subStepValidatorSetup === 1 && <ValidatorSetupInstall />}
|
||||
{activeStep === 3 && subStepValidatorSetup === 2 && <ConsensusSelection />}
|
||||
{activeStep === 3 && subStepValidatorSetup === 3 && <ActivationValidatorSetup />}
|
||||
|
||||
{activeStep === 4 && <KeyGeneration isConfirmPhraseStage={isConfirmPhraseStage} />}
|
||||
{activeStep === 5 && <Activation />}
|
||||
</ValidatorBoxWrapper>
|
||||
<ContinueButton activeStep={activeStep} continueHandler={continueHandler} />
|
||||
<ContinueButton
|
||||
activeStep={activeStep}
|
||||
continueHandler={continueHandler}
|
||||
isConfirmPhraseStage={isConfirmPhraseStage}
|
||||
/>
|
||||
</YStack>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ActivationValidatorSetup from './ActivationValidatorSetup'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'ValidatorOnboarding/ActivationValidatorSetup',
|
||||
component: ActivationValidatorSetup,
|
||||
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
} satisfies Meta<typeof ActivationValidatorSetup>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { XStack, Stack, YStack } from 'tamagui'
|
||||
import { Text } from '@status-im/components'
|
||||
import Confetti from 'react-confetti'
|
||||
import LinkWithArrow from '../../../components/General/LinkWithArrow'
|
||||
import ActivationCard from '../Activation/ActivationCard'
|
||||
|
||||
const styles = {
|
||||
confettiContainer: {
|
||||
position: 'relative' as const,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'fit-content'
|
||||
},
|
||||
confettiCanvas: {
|
||||
position: 'absolute' as const,
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
zIndex: 0,
|
||||
},
|
||||
}
|
||||
|
||||
const ActivationValidatorSetup = () => {
|
||||
const [showConfetti, setShowConfetti] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setShowConfetti(false)
|
||||
}, 10000)
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Stack style={styles.confettiContainer} width={'100%'} >
|
||||
{showConfetti && <Confetti style={styles.confettiCanvas} />}
|
||||
<YStack style={{ padding: '16px 32px' }}>
|
||||
<YStack space={'$5'}>
|
||||
<Text size={27} weight={'semibold'}>
|
||||
Activation
|
||||
</Text>
|
||||
<Stack >
|
||||
<Text size={27}>
|
||||
Congratulations! You have successfully setup your Execution and Consensus clients and are currently syncing your nodes. You need to be sufficiently synced prior to setting up your validators and making a deposit.
|
||||
</Text>
|
||||
</Stack>
|
||||
<YStack space={'$3'} marginTop={'10px'} width={'33%'} >
|
||||
<XStack width={'151%'} space={'$3'} >
|
||||
|
||||
<ActivationCard
|
||||
text="Execution Sync Status"
|
||||
isGaugeIncluded={true}
|
||||
gaugeColor={'#2a4af5'}
|
||||
gaugeSynced={123.524}
|
||||
gaugeTotal={172.503}
|
||||
/>
|
||||
<ActivationCard
|
||||
text="Execution Sync Status"
|
||||
isGaugeIncluded={true}
|
||||
gaugeColor={'#EB5757'}
|
||||
gaugeSynced={123.524}
|
||||
gaugeTotal={172.503}
|
||||
/>
|
||||
</XStack>
|
||||
<XStack space={'$3'}>
|
||||
<ActivationCard text="Validator Queue" value="92603" />
|
||||
<ActivationCard text="Estimated Activation Time" value="32 Days" />
|
||||
<ActivationCard text="Current APR" value="4.40%" />
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
<LinkWithArrow
|
||||
text="Skip to Dashboard"
|
||||
to="/"
|
||||
arrowLeft={true}
|
||||
style={{ marginTop: '44px', marginBottom: '88px' }}
|
||||
/>
|
||||
</YStack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
export default ActivationValidatorSetup
|
|
@ -0,0 +1,19 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ConsensusClientCard from './ConsensusClientCard'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'ValidatorOnboarding/ConsensusClientCard',
|
||||
component: ConsensusClientCard,
|
||||
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
} satisfies Meta<typeof ConsensusClientCard>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: { name: 'Erigon', icon: '/icons/erigon-circle.png' },
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ConsensusGaugeCard from './ConsensusGaugeCard'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'ValidatorOnboarding/ConsensusGaugeCard',
|
||||
component: ConsensusGaugeCard,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
} satisfies Meta<typeof ConsensusGaugeCard>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
color:'orange', synced:140000, total:200000, title: 'Synced Files'
|
||||
},
|
||||
}
|
|
@ -10,7 +10,7 @@ const meta = {
|
|||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
decorators: [withRouter],
|
||||
}
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
|
|
@ -6,9 +6,8 @@ import { withRouter } from 'storybook-addon-react-router-v6'
|
|||
const meta = {
|
||||
title: 'ValidatorOnboarding/ExecClientCard',
|
||||
component: ExecClientCard,
|
||||
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof ExecClientCard>
|
||||
|
||||
export default meta
|
||||
|
|
|
@ -10,7 +10,7 @@ const meta = {
|
|||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof PairedDeviceCard>
|
||||
|
||||
export default meta
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import SyntaxHighlighter from './SyntaxHighlighter'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'ValidatorOnboarding/SyntaxHighlighter',
|
||||
component: SyntaxHighlighter,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter()],
|
||||
} satisfies Meta<typeof SyntaxHighlighter>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: { rows: ['yarn', 'yarn build', 'yarn dev', 'house'] },
|
||||
}
|
|
@ -3,6 +3,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
|||
type KeyGenerationState = {
|
||||
words: string[]
|
||||
isCopyPastedPhrase: boolean
|
||||
isRightPhrase: boolean
|
||||
}
|
||||
|
||||
type wordProps = {
|
||||
|
@ -13,6 +14,7 @@ type wordProps = {
|
|||
const initialState: KeyGenerationState = {
|
||||
words: Array(24).fill(''),
|
||||
isCopyPastedPhrase: false,
|
||||
isRightPhrase: false,
|
||||
}
|
||||
|
||||
const keyGenerationSlice = createSlice({
|
||||
|
@ -30,13 +32,13 @@ const keyGenerationSlice = createSlice({
|
|||
setIsCopyPastedPhrase: (state, action: PayloadAction<boolean>) => {
|
||||
state.isCopyPastedPhrase = action.payload
|
||||
},
|
||||
setIsRightPhrase: (state, action: PayloadAction<boolean>) => {
|
||||
state.isRightPhrase = action.payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const {
|
||||
setWord,
|
||||
setMnemonic,
|
||||
setIsCopyPastedPhrase,
|
||||
} = keyGenerationSlice.actions
|
||||
export const { setWord, setMnemonic, setIsCopyPastedPhrase, setIsRightPhrase } =
|
||||
keyGenerationSlice.actions
|
||||
|
||||
export default keyGenerationSlice.reducer
|
||||
|
|
Loading…
Reference in New Issue