diff --git a/packages/suite/src/support/messages.ts b/packages/suite/src/support/messages.ts index c54caf906ee..cfc3f282eaa 100644 --- a/packages/suite/src/support/messages.ts +++ b/packages/suite/src/support/messages.ts @@ -8334,6 +8334,10 @@ export default defineMessages({ id: 'TR_STEP', defaultMessage: 'Step {number}', }, + TR_STEP_OF_TOTAL: { + id: 'TR_STEP_OF_TOTAL', + defaultMessage: 'Step {index} of {total}', + }, TR_COINJOIN_STEP_1_TITLE: { id: 'TR_COINJOIN_STEP_1_TITLE', defaultMessage: 'Add bitcoin', diff --git a/packages/suite/src/views/recovery/index.tsx b/packages/suite/src/views/recovery/index.tsx index a0a01bf29d8..9adab65637a 100644 --- a/packages/suite/src/views/recovery/index.tsx +++ b/packages/suite/src/views/recovery/index.tsx @@ -1,14 +1,14 @@ import { useState } from 'react'; import { useIntl } from 'react-intl'; -import styled from 'styled-components'; import { getCheckBackupUrl, isDeviceAcquired } from '@suite-common/suite-utils'; -import { Button, H2, Paragraph, Image } from '@trezor/components'; +import { H2, H3, Paragraph, Image, NewModal, Card, List } from '@trezor/components'; import { pickByDeviceModel } from '@trezor/device-utils'; import TrezorConnect, { DeviceModelInternal } from '@trezor/connect'; +import { spacings } from '@trezor/theme'; import { SelectWordCount, SelectRecoveryType } from 'src/components/recovery'; -import { Loading, Translation, CheckItem, Modal } from 'src/components/suite'; +import { Loading, Translation, CheckItem } from 'src/components/suite'; import { ReduxModal } from 'src/components/suite/modals/ReduxModal/ReduxModal'; import { checkSeed, @@ -19,57 +19,9 @@ import { import { useDevice, useDispatch, useSelector } from 'src/hooks/suite'; import type { ForegroundAppProps } from 'src/types/suite'; import type { WordCount } from 'src/types/recovery'; -import { InstructionStep } from 'src/components/suite/InstructionStep'; import messages from 'src/support/messages'; import { LearnMoreButton } from 'src/components/suite/LearnMoreButton'; -const StyledModal = styled(Modal)` - min-height: 450px; - - ${Modal.Content} { - justify-content: center; - } -`; - -// eslint-disable-next-line local-rules/no-override-ds-component -const StyledButton = styled(Button)` - width: 224px; -`; - -const StepsContainer = styled.div` - margin: 40px 0; -`; - -// eslint-disable-next-line local-rules/no-override-ds-component -const StyledP = styled(Paragraph)` - color: ${({ theme }) => theme.legacy.TYPE_LIGHT_GREY}; -`; - -// eslint-disable-next-line local-rules/no-override-ds-component -const StyledImage = styled(Image)` - margin-bottom: 24px; - align-self: center; -`; - -const LeftAlignedP = styled(StyledP)` - text-align: left; -`; - -// eslint-disable-next-line local-rules/no-override-ds-component -const StatusImage = styled(Image)` - padding-bottom: 24px; -`; - -// eslint-disable-next-line local-rules/no-override-ds-component -const StatusTitle = styled(H2)` - margin: 0 0 12px; -`; - -const VerticalCenter = styled.div` - margin-top: auto; - margin-bottom: auto; -`; - export const Recovery = ({ onCancel }: ForegroundAppProps) => { const recovery = useSelector(state => state.recovery); const modal = useSelector(state => state.modal); @@ -102,117 +54,101 @@ export const Recovery = ({ onCancel }: ForegroundAppProps) => { 'finished', ] : ['initial', 'in-progress', 'finished']; + const hasFinished = recovery.status === 'finished'; + const hasError = recovery.error !== undefined; if (!isDeviceAcquired(device) || !deviceModelInternal) { return ( - } - isCancelable onCancel={onCancel} data-testid="@recovery/no-device" + size="tiny" > - - + + ); } - const actionButtons = ( - <> - {recovery.status === 'initial' ? ( - - deviceModelInternal === DeviceModelInternal.T1B1 - ? dispatch(setStatus('select-word-count')) - : dispatch(checkSeed()) - } - isDisabled={!understood || isLocked()} - data-testid="@recovery/start-button" - > - - - ) : ( - onCancel()}> - - - )} - - ); - const getStep = () => { const isShamirBackupAvailable = device?.features?.capabilities?.includes('Capability_Shamir'); - // Shamir backup uses 20 and 33 word shares - const seedBackupLengthMessage = isShamirBackupAvailable - ? 'TR_SEED_BACKUP_LENGTH_INCLUDING_SHAMIR' - : 'TR_SEED_BACKUP_LENGTH'; - switch (recovery.status) { case 'initial': return ( <> - - - - - - + + - } - > - - - - } - > - - - - - } - description={} - isChecked={understood} - link={learnMoreUrl && } - onClick={() => setUnderstood(!understood)} - /> + + + + + + + + + + + + + + + + } + description={} + isChecked={understood} + link={learnMoreUrl && } + onClick={() => setUnderstood(!understood)} + /> + ); case 'select-word-count': return ( <> - +

- +

); case 'select-recovery-type': return ( <> - +

- +

); @@ -221,9 +157,9 @@ export const Recovery = ({ onCancel }: ForegroundAppProps) => { return modal.context !== '@modal/context-none' ? ( <> {device.features.capabilities.includes('Capability_PassphraseEntry') && ( - + - + )} @@ -231,41 +167,74 @@ export const Recovery = ({ onCancel }: ForegroundAppProps) => { ); case 'finished': - return !recovery.error ? ( - - + return !hasError ? ( + <>

- + - -
+ + ) : ( - - + <>

- + - -
+ + ); - // no default } }; return ( - } - totalProgressBarSteps={statesInProgressBar.length} - currentProgressBarStep={statesInProgressBar.findIndex(s => s === recovery.status) + 1} - bottomBarComponents={actionButtons} - isCancelable + description={ + + } + bottomContent={ + <> + {recovery.status === 'initial' && ( + + deviceModelInternal === DeviceModelInternal.T1B1 + ? dispatch(setStatus('select-word-count')) + : dispatch(checkSeed()) + } + isDisabled={!understood || isLocked()} + data-testid="@recovery/start-button" + > + + + )} + onCancel()} + > + + + + } onCancel={() => { if (['in-progress', 'waiting-for-confirmation'].includes(recovery.status)) { TrezorConnect.cancel(intl.formatMessage(messages.TR_CANCELLED)); @@ -273,8 +242,11 @@ export const Recovery = ({ onCancel }: ForegroundAppProps) => { onCancel(); } }} + variant={hasFinished && hasError ? 'warning' : 'primary'} + // eslint-disable-next-line no-nested-ternary + iconName={hasFinished ? (hasError ? 'warning' : 'check') : undefined} > {getStep()} - + ); };