Merge branch 'hn.validator-onboarding' of https://github.com/nimbus-gui/nimbus-gui into hn.validator-onboarding

This commit is contained in:
Hristo Nedelkov 2023-08-29 11:17:17 +03:00
commit 0d3310d67c
8 changed files with 139 additions and 74 deletions

View File

@ -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

View File

@ -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"

View File

@ -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>
)
}

View File

@ -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>
)

View File

@ -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"

View File

@ -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 }}>

View File

@ -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

View File

@ -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'}>