committed by
GitHub
27 changed files with 786 additions and 209 deletions
@ -1,62 +0,0 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
import { translate } from 'react-i18next' |
|||
import logger from 'logger' |
|||
import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' |
|||
|
|||
import type { Device, T } from 'types/common' |
|||
|
|||
import installFinalFirmware from 'commands/installFinalFirmware' |
|||
|
|||
import Box, { Card } from 'components/base/Box' |
|||
// import Button from 'components/base/Button'
|
|||
|
|||
type Props = { |
|||
t: T, |
|||
device: Device, |
|||
deviceInfo: DeviceInfo, |
|||
} |
|||
|
|||
type State = {} |
|||
|
|||
class FirmwareFinalUpdate extends PureComponent<Props, State> { |
|||
componentDidMount() {} |
|||
|
|||
componentWillUnmount() { |
|||
this._unmounting = true |
|||
} |
|||
|
|||
_unmounting = false |
|||
|
|||
installFinalFirmware = async () => { |
|||
try { |
|||
const { device, deviceInfo } = this.props |
|||
const { success } = await installFinalFirmware |
|||
.send({ devicePath: device.path, deviceInfo }) |
|||
.toPromise() |
|||
if (success) { |
|||
this.setState() |
|||
} |
|||
} catch (err) { |
|||
logger.log(err) |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
const { t, ...props } = this.props |
|||
|
|||
return ( |
|||
<Box flow={4} {...props}> |
|||
<Box color="dark" ff="Museo Sans" fontSize={6}> |
|||
{t('app:manager.firmware.update')} |
|||
</Box> |
|||
<Card flow={2} {...props}> |
|||
<Box horizontal align="center" flow={2} /> |
|||
</Card> |
|||
</Box> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default translate()(FirmwareFinalUpdate) |
@ -1,50 +0,0 @@ |
|||
// @flow
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import type { Device } from 'types/common' |
|||
import installMcu from 'commands/installMcu' |
|||
|
|||
import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' |
|||
|
|||
type Props = { |
|||
device: Device, |
|||
deviceInfo: DeviceInfo, |
|||
} |
|||
|
|||
type State = { |
|||
flashing: boolean, |
|||
} |
|||
|
|||
class FlashMcu extends PureComponent<Props, State> { |
|||
state = { |
|||
flashing: false, |
|||
} |
|||
|
|||
flashMCU = async () => { |
|||
const { device, deviceInfo } = this.props |
|||
const { flashing } = this.state |
|||
|
|||
if (!flashing) { |
|||
this.setState({ flashing: true }) |
|||
await installMcu |
|||
.send({ |
|||
devicePath: device.path, |
|||
targetId: deviceInfo.targetId, |
|||
version: deviceInfo.seVersion, |
|||
}) |
|||
.toPromise() |
|||
this.setState({ flashing: false }) |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
return ( |
|||
<div> |
|||
<h1>{'Flashing MCU'}</h1> |
|||
<button onClick={this.flashMCU}>{'flash'}</button> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default FlashMcu |
@ -0,0 +1,82 @@ |
|||
// @flow
|
|||
/* eslint react/jsx-no-literals: 0 */ |
|||
|
|||
import React, { PureComponent, Fragment } from 'react' |
|||
import { translate, Trans } from 'react-i18next' |
|||
import ReactMarkdown from 'react-markdown' |
|||
|
|||
import type { T } from 'types/common' |
|||
|
|||
import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal' |
|||
import Text from 'components/base/Text' |
|||
import Button from 'components/base/Button' |
|||
import GrowScroll from 'components/base/GrowScroll' |
|||
import GradientBox from 'components/GradientBox' |
|||
import { Notes } from 'components/modals/ReleaseNotes' |
|||
|
|||
import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate' |
|||
|
|||
import { getCleanVersion } from 'components/ManagerPage/FirmwareUpdate' |
|||
|
|||
type FirmwareInfos = { |
|||
name: string, |
|||
notes: string, |
|||
} |
|||
|
|||
type Props = { |
|||
t: T, |
|||
status: ModalStatus, |
|||
firmware: FirmwareInfos, |
|||
goToNextStep: () => void, |
|||
onClose: () => void, |
|||
} |
|||
|
|||
type State = * |
|||
|
|||
class DisclaimerModal extends PureComponent<Props, State> { |
|||
render(): React$Node { |
|||
const { status, firmware, onClose, t, goToNextStep } = this.props |
|||
return ( |
|||
<Modal |
|||
isOpened={status === 'disclaimer'} |
|||
onClose={onClose} |
|||
render={({ onClose }) => ( |
|||
<ModalBody onClose={onClose} grow align="center" justify="center" mt={3}> |
|||
<Fragment> |
|||
<ModalTitle>{t('app:manager.firmware.update')}</ModalTitle> |
|||
<ModalContent> |
|||
<Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center"> |
|||
<Trans i18nKey="app:manager.firmware.disclaimerTitle"> |
|||
You are about to install the latest |
|||
<Text ff="Open Sans|SemiBold" color="dark"> |
|||
{`firmware ${firmware ? getCleanVersion(firmware.name) : ''}`} |
|||
</Text> |
|||
</Trans> |
|||
</Text> |
|||
<Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center"> |
|||
{t('app:manager.firmware.disclaimerAppDelete')} |
|||
{t('app:manager.firmware.disclaimerAppReinstall')} |
|||
</Text> |
|||
</ModalContent> |
|||
<ModalContent style={{ height: 250, width: '100%' }}> |
|||
<GrowScroll> |
|||
<Notes> |
|||
<ReactMarkdown>{firmware.notes}</ReactMarkdown> |
|||
</Notes> |
|||
</GrowScroll> |
|||
<GradientBox /> |
|||
</ModalContent> |
|||
<ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}> |
|||
<Button primary padded onClick={goToNextStep}> |
|||
{t('app:manager.firmware.continue')} |
|||
</Button> |
|||
</ModalFooter> |
|||
</Fragment> |
|||
</ModalBody> |
|||
)} |
|||
/> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default translate()(DisclaimerModal) |
@ -0,0 +1,155 @@ |
|||
// @flow
|
|||
import React, { PureComponent, Fragment } from 'react' |
|||
import { translate } from 'react-i18next' |
|||
|
|||
import type { T } from 'types/common' |
|||
|
|||
import Modal from 'components/base/Modal' |
|||
import Stepper from 'components/base/Stepper' |
|||
import Button from 'components/base/Button' |
|||
import SyncSkipUnderPriority from 'components/SyncSkipUnderPriority' |
|||
|
|||
import type { StepProps as DefaultStepProps, Step } from 'components/base/Stepper' |
|||
import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate' |
|||
import type { LedgerScriptParams } from 'helpers/common' |
|||
|
|||
import StepOSUInstaller from './steps/01-step-osu-installer' |
|||
import StepFullFirmwareInstall from './steps/01-step-install-full-firmware' |
|||
import StepFlashMcu from './steps/02-step-flash-mcu' |
|||
import StepConfirmation, { StepConfirmFooter } from './steps/03-step-confirmation' |
|||
|
|||
export type StepProps = DefaultStepProps & { |
|||
firmware: ?LedgerScriptParams, |
|||
onCloseModal: () => void, |
|||
installOsuFirmware: () => void, |
|||
installFinalFirmware: () => void, |
|||
flashMcu: () => void, |
|||
} |
|||
|
|||
type StepId = 'idCheck' | 'updateMCU' | 'finish' |
|||
|
|||
function DebugFooter({ |
|||
transitionTo, |
|||
where, |
|||
}: { |
|||
where: string, |
|||
transitionTo: (where: string) => void, |
|||
}) { |
|||
return <Button onClick={() => transitionTo(where)}>{where}</Button> |
|||
} |
|||
|
|||
const createSteps = ({ |
|||
t, |
|||
firmware, |
|||
}: { |
|||
t: T, |
|||
firmware: LedgerScriptParams & { shouldUpdateMcu: boolean }, |
|||
}): Array<*> => { |
|||
const finalStep = { |
|||
id: 'finish', |
|||
label: t('app:addAccounts.breadcrumb.finish'), |
|||
component: StepConfirmation, |
|||
footer: StepConfirmFooter, |
|||
onBack: null, |
|||
hideFooter: false, |
|||
} |
|||
|
|||
if (firmware.shouldUpdateMcu) { |
|||
return [ |
|||
{ |
|||
id: 'idCheck', |
|||
label: t('app:manager.modal.steps.idCheck'), |
|||
component: StepOSUInstaller, |
|||
footer: ({ firmware, ...props }: StepProps) => ( |
|||
<DebugFooter firmware={firmware} {...props} where="updateMCU" /> |
|||
), |
|||
onBack: null, |
|||
hideFooter: false, |
|||
}, |
|||
{ |
|||
id: 'updateMCU', |
|||
label: t('app:manager.modal.steps.updateMCU'), |
|||
component: StepFlashMcu, |
|||
footer: ({ firmware, ...props }: StepProps) => ( |
|||
<Fragment> |
|||
<DebugFooter firmware={firmware} {...props} where="idCheck" /> |
|||
<DebugFooter firmware={firmware} {...props} where="finish" /> |
|||
</Fragment> |
|||
), |
|||
onBack: null, |
|||
hideFooter: false, |
|||
}, |
|||
finalStep, |
|||
] |
|||
} |
|||
|
|||
return [ |
|||
{ |
|||
id: 'idCheck', |
|||
label: t('app:manager.modal.steps.idCheck'), |
|||
component: StepFullFirmwareInstall, |
|||
footer: ({ firmware, ...props }: StepProps) => ( |
|||
<DebugFooter firmware={firmware} {...props} where="finish" /> |
|||
), |
|||
onBack: null, |
|||
hideFooter: false, |
|||
}, |
|||
finalStep, |
|||
] |
|||
} |
|||
|
|||
type Props = { |
|||
t: T, |
|||
status: ModalStatus, |
|||
onClose: () => void, |
|||
firmware: LedgerScriptParams & { shouldUpdateMcu: boolean }, |
|||
installOsuFirmware: () => void, |
|||
installFinalFirmware: () => void, |
|||
flashMcu: () => void, |
|||
} |
|||
|
|||
type State = { |
|||
stepId: StepId | string, |
|||
} |
|||
|
|||
class UpdateModal extends PureComponent<Props, State> { |
|||
state = { |
|||
stepId: 'idCheck', |
|||
} |
|||
|
|||
STEPS = createSteps({ t: this.props.t, firmware: this.props.firmware }) |
|||
|
|||
handleStepChange = (step: Step) => this.setState({ stepId: step.id }) |
|||
|
|||
render(): React$Node { |
|||
const { status, t, firmware, onClose, ...props } = this.props |
|||
const { stepId } = this.state |
|||
|
|||
const additionalProps = { |
|||
firmware, |
|||
onCloseModal: onClose, |
|||
...props, |
|||
} |
|||
|
|||
return ( |
|||
<Modal |
|||
onClose={onClose} |
|||
isOpened={status === 'install'} |
|||
refocusWhenChange={stepId} |
|||
preventBackdropClick={false} |
|||
render={() => ( |
|||
<Stepper |
|||
title={t('app:manager.firmware.update')} |
|||
initialStepId="idCheck" |
|||
steps={this.STEPS} |
|||
{...additionalProps} |
|||
> |
|||
<SyncSkipUnderPriority priority={100} /> |
|||
</Stepper> |
|||
)} |
|||
/> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default translate()(UpdateModal) |
@ -0,0 +1,108 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent, Fragment } from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Text from 'components/base/Text' |
|||
import Progress from 'components/base/Progress' |
|||
import DeviceConfirm from 'components/DeviceConfirm' |
|||
|
|||
import type { StepProps } from '../' |
|||
|
|||
const Container = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
fontSize: 4, |
|||
color: 'dark', |
|||
px: 7, |
|||
})`` |
|||
|
|||
const Title = styled(Box).attrs({ |
|||
ff: 'Museo Sans|Regular', |
|||
fontSize: 5, |
|||
mb: 3, |
|||
})`` |
|||
|
|||
const Address = styled(Box).attrs({ |
|||
bg: p => (p.notValid ? 'transparent' : p.withQRCode ? 'white' : 'lightGrey'), |
|||
borderRadius: 1, |
|||
color: 'dark', |
|||
ff: 'Open Sans|SemiBold', |
|||
fontSize: 4, |
|||
mt: 2, |
|||
px: p => (p.notValid ? 0 : 4), |
|||
py: p => (p.notValid ? 0 : 3), |
|||
})` |
|||
border: ${p => (p.notValid ? 'none' : `1px dashed ${p.theme.colors.fog}`)}; |
|||
cursor: text; |
|||
user-select: text; |
|||
width: 325px; |
|||
` |
|||
|
|||
const Ellipsis = styled.span` |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
width: 100%; |
|||
` |
|||
|
|||
class StepFullFirmwareInstall extends PureComponent<StepProps, *> { |
|||
componentDidMount() { |
|||
this.install() |
|||
} |
|||
|
|||
install = async () => { |
|||
const { installOsuFirmware, installFinalFirmware, transitionTo } = this.props |
|||
const success = await installOsuFirmware() |
|||
if (success) { |
|||
const finalSuccess = await installFinalFirmware() |
|||
if (finalSuccess) { |
|||
transitionTo('finish') |
|||
} |
|||
} |
|||
} |
|||
|
|||
renderBody = () => { |
|||
const { installing } = this.state |
|||
const { firmware, t } = this.props |
|||
|
|||
if (installing) { |
|||
return ( |
|||
<Box mx={7}> |
|||
<Progress infinite style={{ width: '100%' }} /> |
|||
</Box> |
|||
) |
|||
} |
|||
|
|||
return ( |
|||
<Fragment> |
|||
<Box mx={7} mt={5}> |
|||
<Text ff="Open Sans|SemiBold" align="center" color="smoke"> |
|||
{t('app:manager.modal.identifier')} |
|||
</Text> |
|||
<Address> |
|||
<Ellipsis>{firmware && firmware.hash}</Ellipsis> |
|||
</Address> |
|||
</Box> |
|||
<Box mt={5}> |
|||
<DeviceConfirm /> |
|||
</Box> |
|||
</Fragment> |
|||
) |
|||
} |
|||
|
|||
render() { |
|||
const { t } = this.props |
|||
return ( |
|||
<Container> |
|||
<Title>{t('app:manager.modal.confirmIdentifier')}</Title> |
|||
<Text ff="Open Sans|Regular" align="center" color="smoke"> |
|||
{t('app:manager.modal.confirmIdentifierText')} |
|||
</Text> |
|||
{this.renderBody()} |
|||
</Container> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default StepFullFirmwareInstall |
@ -0,0 +1,85 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Text from 'components/base/Text' |
|||
import DeviceConfirm from 'components/DeviceConfirm' |
|||
|
|||
import type { StepProps } from '../' |
|||
|
|||
const Container = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
fontSize: 4, |
|||
color: 'dark', |
|||
px: 7, |
|||
})`` |
|||
|
|||
const Title = styled(Box).attrs({ |
|||
ff: 'Museo Sans|Regular', |
|||
fontSize: 5, |
|||
mb: 3, |
|||
})`` |
|||
|
|||
const Address = styled(Box).attrs({ |
|||
bg: p => (p.notValid ? 'transparent' : p.withQRCode ? 'white' : 'lightGrey'), |
|||
borderRadius: 1, |
|||
color: 'dark', |
|||
ff: 'Open Sans|SemiBold', |
|||
fontSize: 4, |
|||
mt: 2, |
|||
px: p => (p.notValid ? 0 : 4), |
|||
py: p => (p.notValid ? 0 : 3), |
|||
})` |
|||
border: ${p => (p.notValid ? 'none' : `1px dashed ${p.theme.colors.fog}`)}; |
|||
cursor: text; |
|||
user-select: text; |
|||
width: 325px; |
|||
` |
|||
|
|||
const Ellipsis = styled.span` |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
width: 100%; |
|||
` |
|||
|
|||
class StepOSUInstaller extends PureComponent<StepProps, *> { |
|||
componentDidMount() { |
|||
this.install() |
|||
} |
|||
|
|||
install = async () => { |
|||
const { installOsuFirmware, transitionTo } = this.props |
|||
const success = await installOsuFirmware() |
|||
if (success) { |
|||
transitionTo('updateMCU') |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
const { t, firmware } = this.props |
|||
return ( |
|||
<Container> |
|||
<Title>{t('app:manager.modal.confirmIdentifier')}</Title> |
|||
<Text ff="Open Sans|Regular" align="center" color="smoke"> |
|||
{t('app:manager.modal.confirmIdentifierText')} |
|||
</Text> |
|||
<Box mx={7} mt={5}> |
|||
<Text ff="Open Sans|SemiBold" align="center" color="smoke"> |
|||
{t('app:manager.modal.identifier')} |
|||
</Text> |
|||
<Address> |
|||
<Ellipsis>{firmware && firmware.hash}</Ellipsis> |
|||
</Address> |
|||
</Box> |
|||
<Box mt={5}> |
|||
<DeviceConfirm /> |
|||
</Box> |
|||
</Container> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default StepOSUInstaller |
@ -0,0 +1,155 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent, Fragment } from 'react' |
|||
import styled from 'styled-components' |
|||
import { connect } from 'react-redux' |
|||
import { timeout } from 'rxjs/operators/timeout' |
|||
|
|||
import { DEVICE_INFOS_TIMEOUT } from 'config/constants' |
|||
import { i } from 'helpers/staticPath' |
|||
import { getCurrentDevice } from 'reducers/devices' |
|||
import { createCancelablePolling } from 'helpers/promise' |
|||
import getDeviceInfo from 'commands/getDeviceInfo' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Text from 'components/base/Text' |
|||
import Progress from 'components/base/Progress' |
|||
|
|||
import type { Device } from 'types/common' |
|||
|
|||
import type { StepProps } from '../' |
|||
|
|||
const Container = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
fontSize: 4, |
|||
color: 'dark', |
|||
})`` |
|||
|
|||
const Title = styled(Box).attrs({ |
|||
ff: 'Museo Sans|Regular', |
|||
fontSize: 5, |
|||
mb: 3, |
|||
})`` |
|||
|
|||
const Bullet = styled.span` |
|||
font-weight: 600; |
|||
color: #142533; |
|||
` |
|||
|
|||
const Separator = styled(Box).attrs({ |
|||
color: 'fog', |
|||
})` |
|||
height: 1px; |
|||
width: 100%; |
|||
background-color: currentColor; |
|||
` |
|||
|
|||
const mapStateToProps = state => ({ |
|||
device: getCurrentDevice(state), |
|||
}) |
|||
|
|||
type Props = StepProps & { device?: Device } |
|||
|
|||
type State = { |
|||
installing: boolean, |
|||
} |
|||
|
|||
class StepFlashMcu extends PureComponent<Props, State> { |
|||
state = { |
|||
installing: false, |
|||
} |
|||
|
|||
componentDidMount() { |
|||
this.install() |
|||
} |
|||
|
|||
componentWillUnmount() { |
|||
this._unsubConnect() |
|||
} |
|||
|
|||
waitForDeviceInBootloader = () => { |
|||
const { unsubscribe, promise } = createCancelablePolling(async () => { |
|||
const { device } = this.props |
|||
if (!device) { |
|||
throw new Error('No device') |
|||
} |
|||
const deviceInfo = await getDeviceInfo |
|||
.send({ devicePath: device.path }) |
|||
.pipe(timeout(DEVICE_INFOS_TIMEOUT)) |
|||
.toPromise() |
|||
if (!deviceInfo.isBootloader) { |
|||
throw new Error('Device is not in bootloader') |
|||
} |
|||
return { device, deviceInfo } |
|||
}) |
|||
this._unsubConnect = unsubscribe |
|||
return promise |
|||
} |
|||
|
|||
install = async () => { |
|||
await this.waitForDeviceInBootloader() |
|||
const { flashMcu, installFinalFirmware, transitionTo } = this.props |
|||
this.setState({ installing: true }) |
|||
await flashMcu() |
|||
const finalSuccess = await installFinalFirmware() |
|||
|
|||
if (finalSuccess) { |
|||
transitionTo('finish') |
|||
} |
|||
} |
|||
|
|||
renderBody = () => { |
|||
const { installing } = this.state |
|||
const { t } = this.props |
|||
|
|||
if (installing) { |
|||
return ( |
|||
<Box mx={7}> |
|||
<Progress infinite style={{ width: '100%' }} /> |
|||
</Box> |
|||
) |
|||
} |
|||
|
|||
return ( |
|||
<Fragment> |
|||
<Box mx={7}> |
|||
<Text ff="Open Sans|Regular" align="center" color="smoke"> |
|||
<Bullet>{'1.'}</Bullet> |
|||
{t('app:manager.modal.mcuFirst')} |
|||
</Text> |
|||
<img |
|||
src={i('logos/unplugDevice.png')} |
|||
style={{ width: '100%', maxWidth: 368, marginTop: 30 }} |
|||
alt={t('app:manager.modal.mcuFirst')} |
|||
/> |
|||
</Box> |
|||
<Separator my={6} /> |
|||
<Box mx={7}> |
|||
<Text ff="Open Sans|Regular" align="center" color="smoke"> |
|||
<Bullet>{'2.'}</Bullet> |
|||
{t('app:manager.modal.mcuSecond')} |
|||
</Text> |
|||
<img |
|||
src={i('logos/bootloaderMode.png')} |
|||
style={{ width: '100%', maxWidth: 368, marginTop: 30 }} |
|||
alt={t('app:manager.modal.mcuFirst')} |
|||
/> |
|||
</Box> |
|||
</Fragment> |
|||
) |
|||
} |
|||
|
|||
_unsubConnect: * |
|||
|
|||
render() { |
|||
const { t } = this.props |
|||
return ( |
|||
<Container> |
|||
<Title>{t('app:manager.modal.mcuTitle')}</Title> |
|||
{this.renderBody()} |
|||
</Container> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(StepFlashMcu) |
@ -0,0 +1,52 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Text from 'components/base/Text' |
|||
import Button from 'components/base/Button' |
|||
import CheckCircle from 'icons/CheckCircle' |
|||
|
|||
import type { StepProps } from '../' |
|||
|
|||
const Container = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
fontSize: 4, |
|||
color: 'dark', |
|||
})`` |
|||
|
|||
const Title = styled(Box).attrs({ |
|||
fontFamily: 'Museo Sans', |
|||
fontSize: 6, |
|||
color: 'dark', |
|||
})` |
|||
font-weight: 500; |
|||
` |
|||
|
|||
function StepConfirmation({ t }: StepProps) { |
|||
return ( |
|||
<Container> |
|||
<Box mx={7} color="positiveGreen" my={4}> |
|||
<CheckCircle size={44} /> |
|||
</Box> |
|||
<Title>{t('app:manager.modal.successTitle')}</Title> |
|||
<Box mt={2} mb={8}> |
|||
<Text ff="Open Sans|Regular" fontSize={4} color="graphite"> |
|||
{t('app:manager.modal.successText')} |
|||
</Text> |
|||
</Box> |
|||
<Box mx={7} /> |
|||
</Container> |
|||
) |
|||
} |
|||
|
|||
export function StepConfirmFooter({ t, onCloseModal }: StepProps) { |
|||
return ( |
|||
<Button primary onClick={onCloseModal}> |
|||
{t('app:common.close')} |
|||
</Button> |
|||
) |
|||
} |
|||
|
|||
export default StepConfirmation |
@ -0,0 +1,19 @@ |
|||
// @flow
|
|||
import network from 'api/network' |
|||
|
|||
import { GET_MCUS } from 'helpers/urls' |
|||
|
|||
export default async (): Promise<*> => { |
|||
try { |
|||
const { data } = await network({ |
|||
method: 'GET', |
|||
url: GET_MCUS, |
|||
}) |
|||
|
|||
return data |
|||
} catch (err) { |
|||
const error = Error(err.message) |
|||
error.stack = err.stack |
|||
throw err |
|||
} |
|||
} |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in new issue