Merge branch 'hn.validator-onboarding' of https://github.com/nimbus-gui/nimbus-gui into hn.validator-onboarding
This commit is contained in:
commit
0d3310d67c
|
@ -0,0 +1,14 @@
|
|||
import { YStack } from 'tamagui'
|
||||
import KeyGenerationTitle from './KeyGenerationTitle'
|
||||
import { Text } from '@status-im/components'
|
||||
|
||||
const ConfirmRecoveryPhrase = () => {
|
||||
return (
|
||||
<YStack space={'$4'} style={{ width: '100%', marginTop: '20px' }}>
|
||||
<KeyGenerationTitle />
|
||||
<Text size={27}>Confirm Recovery Phrase</Text>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConfirmRecoveryPhrase
|
|
@ -1,10 +1,8 @@
|
|||
import { XStack, YStack } from 'tamagui'
|
||||
import { Stack, XStack, YStack } from 'tamagui'
|
||||
import { Button, InformationBox, Input, Text } from '@status-im/components'
|
||||
import { ClearIcon, CloseCircleIcon } from '@status-im/icons'
|
||||
import { useState } from 'react'
|
||||
|
||||
import BorderBox from '../../../components/General/BorderBox'
|
||||
|
||||
const KeyFiles = () => {
|
||||
const [encryptedPassword, setEncryptedPassword] = useState('')
|
||||
const [confirmEncryptedPassword, setConfirmEncryptedPassword] = useState('')
|
||||
|
@ -28,10 +26,10 @@ const KeyFiles = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$2'}>
|
||||
<XStack space={'$2'} style={{ justifyContent: 'space-between' }}>
|
||||
<YStack space={'$1'}>
|
||||
<YStack space={'$2'}>
|
||||
<YStack space={'$4'}>
|
||||
<XStack space={'$2'} style={{ justifyContent: 'space-between', width: '100%' }}>
|
||||
<YStack space={'$4'} style={{ width: '66%' }}>
|
||||
<YStack space={'$4'}>
|
||||
<Text size={15} color={'#647084'}>
|
||||
Encryption Password
|
||||
</Text>
|
||||
|
@ -68,13 +66,23 @@ const KeyFiles = () => {
|
|||
/>
|
||||
</YStack>
|
||||
</YStack>
|
||||
<BorderBox>
|
||||
<YStack
|
||||
style={{
|
||||
border: '1px solid #DCE0E5',
|
||||
borderRadius: '16px',
|
||||
padding: '12px 16px',
|
||||
width: '32%',
|
||||
marginTop: '3.4%',
|
||||
}}
|
||||
>
|
||||
<Text size={15} weight={'semibold'}>
|
||||
Download Key Files
|
||||
</Text>
|
||||
</BorderBox>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<Button onPress={generateKeyFilesHandler}>Generate Key files</Button>
|
||||
<Stack style={{ width: 'fit-content' }}>
|
||||
<Button onPress={generateKeyFilesHandler}>Generate Key files</Button>
|
||||
</Stack>
|
||||
<InformationBox
|
||||
message="You should see that you have one keystore per validator. This keystore contains your signing key, encrypted with your password. Warning: Do not store keys on multiple (backup) validator clients at once"
|
||||
variant="error"
|
||||
|
|
|
@ -1,36 +1,49 @@
|
|||
import { YStack } from 'tamagui'
|
||||
import { Stack, YStack } from 'tamagui'
|
||||
import { Text } from '@status-im/components'
|
||||
import { useState } from 'react'
|
||||
|
||||
import KeyGenerationHeader from './KeyGenerationHeader'
|
||||
import RecoveryMechanism from './RecoveryMechanism'
|
||||
import { Text } from '@status-im/components'
|
||||
import KeyFiles from './KeyFiles'
|
||||
import { useState } from 'react'
|
||||
import RecoveryPhrase from './RecoveryPhrase'
|
||||
import { BOTH_KEY_AND_RECOVERY, KEY_FILES, RECOVERY_PHRASE } from '../../../constants'
|
||||
import ConfirmRecoveryPhrase from './ConfirmRecoveryPhrase'
|
||||
|
||||
const KeyGeneration = () => {
|
||||
type KeyGenerationProps = {
|
||||
isConfirmPhraseStage: boolean
|
||||
}
|
||||
|
||||
const KeyGeneration = ({ isConfirmPhraseStage }: KeyGenerationProps) => {
|
||||
const [recoveryMechanism, setRecoveryMechanism] = useState(KEY_FILES)
|
||||
|
||||
const handleRecMechanismChange = (value: string) => {
|
||||
setRecoveryMechanism(value)
|
||||
}
|
||||
|
||||
const isKeyFiles = recoveryMechanism === KEY_FILES || recoveryMechanism === BOTH_KEY_AND_RECOVERY
|
||||
|
||||
const isRecoveryPhrase =
|
||||
recoveryMechanism === RECOVERY_PHRASE || recoveryMechanism === BOTH_KEY_AND_RECOVERY
|
||||
|
||||
const handleRecMechanismChange = (value: string) => {
|
||||
setRecoveryMechanism(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$2'} style={{ width: '100%', padding: '16px 32px', alignItems: 'start' }}>
|
||||
<KeyGenerationHeader />
|
||||
<RecoveryMechanism
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
<Text size={27} weight={'semibold'}>
|
||||
4 Validators
|
||||
</Text>
|
||||
{isKeyFiles && <KeyFiles />}
|
||||
{isRecoveryPhrase && <RecoveryPhrase />}
|
||||
{isConfirmPhraseStage && <ConfirmRecoveryPhrase />}
|
||||
{isConfirmPhraseStage === false && (
|
||||
<>
|
||||
<KeyGenerationHeader />
|
||||
<RecoveryMechanism
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
<Stack style={{ margin: '30px 0' }}>
|
||||
<Text size={27} weight={'semibold'}>
|
||||
4 Validators
|
||||
</Text>
|
||||
</Stack>
|
||||
{isKeyFiles && <KeyFiles />}
|
||||
{isRecoveryPhrase && <RecoveryPhrase isKeyFiles={isKeyFiles} />}
|
||||
</>
|
||||
)}
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Text } from '@status-im/components'
|
||||
import { XStack, YStack } from 'tamagui'
|
||||
|
||||
import RecoveryMechanismCard from './RecoveryMechanismCard'
|
||||
import { BOTH_KEY_AND_RECOVERY, KEY_FILES, RECOVERY_PHRASE } from '../../../constants'
|
||||
|
||||
|
@ -8,6 +9,8 @@ type RecoveryMechanismProps = {
|
|||
handleRecMechanismChange: (value: string) => void
|
||||
}
|
||||
|
||||
const cards = [KEY_FILES, RECOVERY_PHRASE, BOTH_KEY_AND_RECOVERY]
|
||||
|
||||
const RecoveryMechanism = ({
|
||||
recoveryMechanism,
|
||||
handleRecMechanismChange,
|
||||
|
@ -18,21 +21,14 @@ const RecoveryMechanism = ({
|
|||
Select Recovery Mechanism
|
||||
</Text>
|
||||
<XStack space={'$4'} style={{ justifyContent: 'space-between', marginTop: '40px' }}>
|
||||
<RecoveryMechanismCard
|
||||
value={KEY_FILES}
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
<RecoveryMechanismCard
|
||||
value={RECOVERY_PHRASE}
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
<RecoveryMechanismCard
|
||||
value={BOTH_KEY_AND_RECOVERY}
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
{cards.map(value => (
|
||||
<RecoveryMechanismCard
|
||||
key={value}
|
||||
value={value}
|
||||
recoveryMechanism={recoveryMechanism}
|
||||
handleRecMechanismChange={handleRecMechanismChange}
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
</YStack>
|
||||
)
|
||||
|
|
|
@ -1,11 +1,39 @@
|
|||
import { YStack } from 'tamagui'
|
||||
import { Button, InformationBox } from '@status-im/components'
|
||||
import { Stack, YStack } from 'tamagui'
|
||||
import { Button, InformationBox, Text } from '@status-im/components'
|
||||
import { CloseCircleIcon } from '@status-im/icons'
|
||||
import { useState } from 'react'
|
||||
|
||||
type RecoveryPhraseProps = {
|
||||
isKeyFiles: boolean
|
||||
}
|
||||
|
||||
const RecoveryPhrase = ({ isKeyFiles }: RecoveryPhraseProps) => {
|
||||
const [isReveal, setIsReveal] = useState(false)
|
||||
|
||||
const revealHandler = () => {
|
||||
setIsReveal(state => !state)
|
||||
}
|
||||
|
||||
const RecoveryPhrase = () => {
|
||||
return (
|
||||
<YStack space={'$2'}>
|
||||
<Button>Reveal Recovery Phrase</Button>
|
||||
<YStack space={'$4'} style={{ width: '100%', marginTop: isKeyFiles ? '20px' : '0px' }}>
|
||||
<Stack
|
||||
style={{
|
||||
border: `1px solid #2A4AF566`,
|
||||
borderRadius: '16px',
|
||||
padding: '12px 16px',
|
||||
backgroundColor: '#f4f6fe',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Stack style={{ filter: `blur(${isReveal ? '0px' : '4px'})` }}>
|
||||
<Text size={15} weight={'semibold'}>
|
||||
asdf
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack style={{ width: 'fit-content', marginBottom: '12px' }}>
|
||||
<Button onPress={revealHandler}>Reveal Recovery Phrase</Button>
|
||||
</Stack>
|
||||
<InformationBox
|
||||
message="Write down and keep your Secret Recovery Phrase in a secure place. Make sure no one is looking at your screen."
|
||||
variant="error"
|
||||
|
|
|
@ -14,6 +14,7 @@ import ValidatorSetupInstall from './ValidatorSetup/ValidatorInstall'
|
|||
|
||||
const ValidatorOnboarding = () => {
|
||||
const [activeStep, setActiveStep] = useState(0)
|
||||
const [isConfirmPhraseStage, setIsConfirmPhraseStage] = useState(false)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const changeActiveStep = (step: number) => {
|
||||
|
@ -21,7 +22,9 @@ const ValidatorOnboarding = () => {
|
|||
}
|
||||
|
||||
const continueHandler = () => {
|
||||
if (activeStep < 4) {
|
||||
if (activeStep === 3 && isConfirmPhraseStage === false) {
|
||||
setIsConfirmPhraseStage(true)
|
||||
} else if (activeStep < 4) {
|
||||
setActiveStep(activeStep + 1)
|
||||
} else {
|
||||
navigate('/')
|
||||
|
@ -49,7 +52,7 @@ const ValidatorOnboarding = () => {
|
|||
{activeStep === 0 && <Overview />}
|
||||
{activeStep === 1 && <Advicsories />}
|
||||
{activeStep === 2 && <ValidatorSetupInstall />}
|
||||
{activeStep === 3 && <KeyGeneration />}
|
||||
{activeStep === 3 && <KeyGeneration isConfirmPhraseStage={isConfirmPhraseStage} />}
|
||||
{activeStep === 4 && <Activation />}
|
||||
</ValidatorBoxWrapper>
|
||||
<Stack style={{ alignItems: 'end', width: '100%', marginTop: '16px', zIndex: 999 }}>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ValidatorSetup from './ValidatorSetup'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'ValidatorOnboarding/ValidatorSetup',
|
||||
|
@ -10,6 +11,7 @@ const meta = {
|
|||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
decorators: [withRouter()],
|
||||
} satisfies Meta<typeof ValidatorSetup>
|
||||
|
||||
export default meta
|
||||
|
|
|
@ -4,31 +4,32 @@ import { Text } from '@status-im/components'
|
|||
import ExecClientCard from './ExecClientCard'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const execClientCardsContent = [
|
||||
{
|
||||
name: 'Nethermind',
|
||||
icon: '/icons/nethermind-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Besu',
|
||||
icon: '/icons/hyperledger-besu-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Geth',
|
||||
icon: '/icons/gethereum-mascot-circle.png',
|
||||
isSelected: true,
|
||||
},
|
||||
{
|
||||
name: 'Erigon',
|
||||
icon: '/icons/erigon-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Nimbus',
|
||||
icon: '/icons/NimbusDisabled.svg',
|
||||
isComingSoon: true,
|
||||
},
|
||||
]
|
||||
|
||||
const ValidatorSetup = () => {
|
||||
const execClientCardsContent = [
|
||||
{
|
||||
name: 'Nethermind',
|
||||
icon: '/icons/nethermind-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Besu',
|
||||
icon: '/icons/hyperledger-besu-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Geth',
|
||||
icon: '/icons/gethereum-mascot-circle.png',
|
||||
isSelected: true,
|
||||
},
|
||||
{
|
||||
name: 'Erigon',
|
||||
icon: '/icons/erigon-circle.png',
|
||||
},
|
||||
{
|
||||
name: 'Nimbus',
|
||||
icon: '/icons/NimbusDisabled.svg',
|
||||
isComingSoon: true,
|
||||
},
|
||||
]
|
||||
return (
|
||||
<YStack style={{ width: '100%', padding: '16px 32px' }}>
|
||||
<XStack justifyContent={'space-between'}>
|
||||
|
|
Loading…
Reference in New Issue