mirror of
https://github.com/status-im/nimbus-gui.git
synced 2025-02-03 23:24:20 +00:00
Merge pull request #35 from nimbus-gui/rd.fix-connect-screens-flow
Fix connect screens flow
This commit is contained in:
commit
836521aee4
@ -1,8 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="20/connection">
|
||||
<g id="body">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.99978 1.8999C8.21669 1.8999 6.48343 2.48826 5.06881 3.57374C3.6542 4.65921 2.63728 6.18114 2.17578 7.90347L3.33489 8.21405C3.72802 6.74688 4.59428 5.45043 5.79933 4.52576C7.00437 3.6011 8.48086 3.0999 9.99978 3.0999C11.5187 3.0999 12.9952 3.6011 14.2002 4.52577C15.4053 5.45043 16.2715 6.74688 16.6647 8.21405L17.8238 7.90347C17.3623 6.18114 16.3454 4.65922 14.9307 3.57374C13.5161 2.48827 11.7829 1.8999 9.99978 1.8999ZM9.99988 4.9C8.87719 4.9 7.78588 5.27045 6.8952 5.9539C6.00451 6.63734 5.36423 7.59559 5.07366 8.68002L6.23277 8.9906C6.45497 8.16133 6.9446 7.42856 7.62571 6.90592C8.30682 6.38329 9.14136 6.1 9.99988 6.1C10.8584 6.1 11.6929 6.38329 12.374 6.90592C13.0552 7.42856 13.5448 8.16134 13.767 8.99061L14.9261 8.68002C14.6355 7.59559 13.9952 6.63735 13.1046 5.9539C12.2139 5.27045 11.1226 4.9 9.99988 4.9ZM9.99988 10.1C8.95054 10.1 8.09988 10.9507 8.09988 12C8.09988 13.0493 8.95054 13.9 9.99988 13.9C11.0492 13.9 11.8999 13.0493 11.8999 12C11.8999 10.9507 11.0492 10.1 9.99988 10.1ZM6.89988 12C6.89988 10.2879 8.2878 8.9 9.99988 8.9C11.712 8.9 13.0999 10.2879 13.0999 12C13.0999 13.5068 12.0248 14.7625 10.5999 15.042V17.5H9.39988V15.042C7.97494 14.7625 6.89988 13.5068 6.89988 12Z" fill="#2F80ED"/>
|
||||
<path d="M5.06881 3.57374L4.76443 3.17706L5.06881 3.57374ZM2.17578 7.90347L1.69282 7.77406L1.56341 8.25702L2.04637 8.38643L2.17578 7.90347ZM3.33489 8.21405L3.20548 8.69701L3.68845 8.82642L3.81786 8.34346L3.33489 8.21405ZM5.79933 4.52576L6.10371 4.92244L5.79933 4.52576ZM9.99978 3.0999V2.5999V3.0999ZM16.6647 8.21405L16.1817 8.34346L16.3111 8.82642L16.7941 8.69702L16.6647 8.21405ZM17.8238 7.90347L17.9532 8.38643L18.4362 8.25702L18.3067 7.77406L17.8238 7.90347ZM14.9307 3.57374L15.2351 3.17707V3.17706L14.9307 3.57374ZM6.8952 5.9539L6.59082 5.55722H6.59081L6.8952 5.9539ZM9.99988 4.9V5.4V4.9ZM5.07366 8.68002L4.59069 8.55061L4.46128 9.03357L4.94425 9.16298L5.07366 8.68002ZM6.23277 8.9906L6.10336 9.47357L6.58632 9.60298L6.71573 9.12001L6.23277 8.9906ZM9.99988 6.1L9.99988 5.6H9.99988V6.1ZM12.374 6.90592L12.6784 6.50925H12.6784L12.374 6.90592ZM13.767 8.99061L13.284 9.12002L13.4134 9.60298L13.8964 9.47357L13.767 8.99061ZM14.9261 8.68002L15.0555 9.16299L15.5385 9.03358L15.4091 8.55062L14.9261 8.68002ZM13.1046 5.9539L13.4089 5.55722H13.4089L13.1046 5.9539ZM10.5999 15.042L10.5037 14.5513L10.0999 14.6305V15.042H10.5999ZM10.5999 17.5V18H11.0999V17.5H10.5999ZM9.39988 17.5H8.89988V18H9.39988V17.5ZM9.39988 15.042H9.89988V14.6305L9.4961 14.5513L9.39988 15.042ZM5.37319 3.97042C6.70049 2.95195 8.32676 2.3999 9.99978 2.3999V1.3999C8.10663 1.3999 6.26637 2.02458 4.76443 3.17706L5.37319 3.97042ZM2.65874 8.03288C3.09175 6.41686 4.0459 4.98889 5.37319 3.97042L4.76443 3.17706C3.26249 4.32954 2.1828 5.94541 1.69282 7.77406L2.65874 8.03288ZM3.4643 7.73109L2.30519 7.4205L2.04637 8.38643L3.20548 8.69701L3.4643 7.73109ZM5.49495 4.12909C4.20258 5.12075 3.27354 6.51115 2.85193 8.08464L3.81786 8.34346C4.18249 6.98261 4.98598 5.7801 6.10371 4.92244L5.49495 4.12909ZM9.99978 2.5999C8.37079 2.5999 6.78731 3.13742 5.49495 4.12909L6.10371 4.92244C7.22143 4.06478 8.59092 3.5999 9.99978 3.5999V2.5999ZM14.5046 4.12909C13.2122 3.13742 11.6288 2.5999 9.99978 2.5999V3.5999C11.4086 3.5999 12.7781 4.06478 13.8959 4.92244L14.5046 4.12909ZM17.1476 8.08464C16.726 6.51116 15.797 5.12076 14.5046 4.12909L13.8959 4.92244C15.0136 5.7801 15.8171 6.98261 16.1817 8.34346L17.1476 8.08464ZM17.6944 7.42051L16.5353 7.73109L16.7941 8.69702L17.9532 8.38643L17.6944 7.42051ZM14.6264 3.97042C15.9537 4.98889 16.9078 6.41687 17.3408 8.03288L18.3067 7.77406C17.8168 5.94541 16.7371 4.32954 15.2351 3.17707L14.6264 3.97042ZM9.99978 2.3999C11.6728 2.3999 13.2991 2.95195 14.6264 3.97042L15.2351 3.17706C13.7332 2.02459 11.8929 1.3999 9.99978 1.3999V2.3999ZM7.19958 6.35057C8.00294 5.73413 8.98726 5.4 9.99988 5.4V4.4C8.76713 4.4 7.56882 4.80677 6.59082 5.55722L7.19958 6.35057ZM5.55662 8.80943C5.8187 7.83132 6.39621 6.96702 7.19958 6.35057L6.59081 5.55722C5.61281 6.30767 4.90975 7.35987 4.59069 8.55061L5.55662 8.80943ZM6.36218 8.50764L5.20307 8.19706L4.94425 9.16298L6.10336 9.47357L6.36218 8.50764ZM7.32133 6.50924C6.55289 7.09889 6.00049 7.92561 5.7498 8.86119L6.71573 9.12001C6.90945 8.39706 7.3363 7.75823 7.93009 7.3026L7.32133 6.50924ZM9.99988 5.6C9.03129 5.6 8.08976 5.9196 7.32133 6.50924L7.93009 7.3026C8.52388 6.84697 9.25142 6.6 9.99988 6.6V5.6ZM12.6784 6.50925C11.91 5.91961 10.9685 5.6 9.99988 5.6L9.99988 6.6C10.7483 6.6 11.4759 6.84697 12.0697 7.3026L12.6784 6.50925ZM14.25 8.8612C13.9993 7.92561 13.4469 7.09889 12.6784 6.50925L12.0697 7.3026C12.6635 7.75823 13.0903 8.39706 13.284 9.12002L14.25 8.8612ZM14.7967 8.19706L13.6376 8.50764L13.8964 9.47357L15.0555 9.16299L14.7967 8.19706ZM12.8002 6.35057C13.6035 6.96702 14.1811 7.83132 14.4431 8.80943L15.4091 8.55062C15.09 7.35987 14.3869 6.30767 13.4089 5.55722L12.8002 6.35057ZM9.99988 5.4C11.0125 5.4 11.9968 5.73413 12.8002 6.35057L13.4089 5.55722C12.4309 4.80677 11.2326 4.4 9.99988 4.4V5.4ZM8.59988 12C8.59988 11.2268 9.22668 10.6 9.99988 10.6V9.6C8.67439 9.6 7.59988 10.6745 7.59988 12H8.59988ZM9.99988 13.4C9.22668 13.4 8.59988 12.7732 8.59988 12H7.59988C7.59988 13.3255 8.67439 14.4 9.99988 14.4V13.4ZM11.3999 12C11.3999 12.7732 10.7731 13.4 9.99988 13.4V14.4C11.3254 14.4 12.3999 13.3255 12.3999 12H11.3999ZM9.99988 10.6C10.7731 10.6 11.3999 11.2268 11.3999 12H12.3999C12.3999 10.6745 11.3254 9.6 9.99988 9.6V10.6ZM9.99988 8.4C8.01165 8.4 6.39988 10.0118 6.39988 12H7.39988C7.39988 10.5641 8.56394 9.4 9.99988 9.4V8.4ZM13.5999 12C13.5999 10.0118 11.9881 8.4 9.99988 8.4V9.4C11.4358 9.4 12.5999 10.5641 12.5999 12H13.5999ZM10.6961 15.5326C12.3511 15.2081 13.5999 13.7504 13.5999 12H12.5999C12.5999 13.2632 11.6985 14.317 10.5037 14.5513L10.6961 15.5326ZM10.0999 15.042V17.5H11.0999V15.042H10.0999ZM10.5999 17H9.39988V18H10.5999V17ZM9.89988 17.5V15.042H8.89988V17.5H9.89988ZM6.39988 12C6.39988 13.7504 7.64864 15.2081 9.30366 15.5326L9.4961 14.5513C8.30124 14.317 7.39988 13.2632 7.39988 12H6.39988Z" fill="#2A4CF4"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 6.0 KiB |
14
src/App.tsx
14
src/App.tsx
@ -9,15 +9,13 @@ import { useSelector } from 'react-redux'
|
||||
import config from '../tamagui.config'
|
||||
import LandingPage from './pages/LandingPage/LandingPage'
|
||||
import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck'
|
||||
import ConnectDevicePage from './pages/ConnectDevicePage/ConnectDevicePage'
|
||||
import { RootState } from './redux/store'
|
||||
import DeviceSyncStatus from './pages/DeviceSyncStatus/DeviceSyncStatus'
|
||||
import PairDevice from './pages/PairDevice/PairDevice'
|
||||
import PinnedNotification from './components/General/PinnedNottification'
|
||||
import CreateLocalNodePage from './pages/CreateLocalNodePage/CreateLocalNodePage'
|
||||
import CreateLocalNode from './pages/CreateLocalNode/CreateLocalNode'
|
||||
import ValidatorOnboarding from './pages/ValidatorOnboarding/ValidatorOnboarding'
|
||||
import Dashboard from './pages/Dashboard/Dashboard'
|
||||
import ConnectExistingInstance from './pages/ConnectExistingInstance/ConnectExistingInstance'
|
||||
import ValidatorManagement from './pages/ValidatorManagement/ValidatorManagement'
|
||||
import { ethereumRopsten, wcV2InitOptions, apiKey } from './constants'
|
||||
import './App.css'
|
||||
@ -47,10 +45,6 @@ const router = createBrowserRouter([
|
||||
path: '/device-health-check',
|
||||
element: <DeviceHealthCheck />,
|
||||
},
|
||||
{
|
||||
path: '/connect-device',
|
||||
element: <ConnectDevicePage />,
|
||||
},
|
||||
{
|
||||
path: '/device-sync-status',
|
||||
element: <DeviceSyncStatus />,
|
||||
@ -59,11 +53,7 @@ const router = createBrowserRouter([
|
||||
path: '/pair-device',
|
||||
element: <PairDevice />,
|
||||
},
|
||||
{
|
||||
path: '/pair-existing-instance',
|
||||
element: <ConnectExistingInstance />,
|
||||
},
|
||||
{ path: '/create-local-node', element: <CreateLocalNodePage /> },
|
||||
{ path: '/create-local-node', element: <CreateLocalNode /> },
|
||||
{ path: '/validator-onboarding', element: <ValidatorOnboarding /> },
|
||||
{ path: '/dashboard', element: <Dashboard /> },
|
||||
{ path: '/validator-management', element: <ValidatorManagement /> },
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import Header from './Header'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'General/Header',
|
||||
@ -8,6 +9,7 @@ const meta = {
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
decorators: [withRouter],
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof Header>
|
||||
|
||||
@ -16,18 +18,12 @@ type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
selectedTag: 'pair',
|
||||
selectedTag: 'Pair',
|
||||
},
|
||||
}
|
||||
|
||||
export const CreateTag: Story = {
|
||||
args: {
|
||||
selectedTag: 'create',
|
||||
},
|
||||
}
|
||||
|
||||
export const ConnectTag: Story = {
|
||||
args: {
|
||||
selectedTag: 'connect',
|
||||
selectedTag: 'Create',
|
||||
},
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import NimbusLogo from '../Logos/NimbusLogo'
|
||||
import TagContainer from './TagContainer'
|
||||
import TagContainer, { SelectedTag } from './TagContainer'
|
||||
|
||||
type HeaderProps = {
|
||||
selectedTag: 'pair' | 'create' | 'connect'
|
||||
selectedTag: SelectedTag
|
||||
}
|
||||
|
||||
const Header = ({ selectedTag }: HeaderProps) => {
|
||||
|
@ -2,5 +2,4 @@
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
margin-top: 8px;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Input as StatusInput, Text } from '@status-im/components'
|
||||
import { Label } from 'tamagui'
|
||||
|
||||
import './LabelInputField.css'
|
||||
|
||||
type LabelInputProps = {
|
||||
|
@ -1,3 +0,0 @@
|
||||
/* .tag-container div:nth-child(1) {
|
||||
background:transparent;
|
||||
} */
|
@ -1,21 +1,29 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ConnectDevicePage from './ConnectDevicePage'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
import TagContainer from './TagContainer'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/ConnectDevicePage',
|
||||
component: ConnectDevicePage,
|
||||
title: 'General/TagContainer',
|
||||
component: TagContainer,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof ConnectDevicePage>
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof TagContainer>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {},
|
||||
export const Pair: Story = {
|
||||
args: {
|
||||
selectedTag: 'Pair',
|
||||
},
|
||||
}
|
||||
|
||||
export const Create: Story = {
|
||||
args: {
|
||||
selectedTag: 'Create',
|
||||
},
|
||||
}
|
@ -1,53 +1,46 @@
|
||||
import { Tag } from '@status-im/components'
|
||||
import { XStack } from 'tamagui'
|
||||
import './TagContainer.css'
|
||||
import { ConnectionIcon, AddSmallIcon, SwapIcon } from '@status-im/icons'
|
||||
import { AddSmallIcon, SwapIcon } from '@status-im/icons'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
export type SelectedTag = 'Pair' | 'Create'
|
||||
|
||||
type TagContainerProps = {
|
||||
selectedTag: 'pair' | 'create' | 'connect'
|
||||
selectedTag: SelectedTag
|
||||
}
|
||||
|
||||
const TAGS = [
|
||||
{
|
||||
label: 'Pair',
|
||||
icon: SwapIcon,
|
||||
path: '/pair-device',
|
||||
},
|
||||
{
|
||||
label: 'Create',
|
||||
icon: AddSmallIcon,
|
||||
path: '/create-local-node',
|
||||
},
|
||||
]
|
||||
|
||||
const TagContainer = ({ selectedTag }: TagContainerProps) => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const onPressConnect = () => {
|
||||
navigate('/connect-device')
|
||||
}
|
||||
|
||||
const onPressPair = () => {
|
||||
navigate('/pair-device')
|
||||
}
|
||||
|
||||
const onPressCreate = () => {
|
||||
navigate('/create-local-node')
|
||||
const onPressTag = (path: string) => {
|
||||
navigate(path)
|
||||
}
|
||||
|
||||
return (
|
||||
<XStack space={'$2'} alignItems="center" className="tag-container">
|
||||
{selectedTag === 'connect' ? (
|
||||
{TAGS.map(tag => (
|
||||
<Tag
|
||||
selected={selectedTag === 'connect'}
|
||||
icon={ConnectionIcon}
|
||||
label="Connect"
|
||||
key={tag.label}
|
||||
selected={selectedTag === tag.label}
|
||||
icon={tag.icon}
|
||||
label={tag.label}
|
||||
size={32}
|
||||
onPress={onPressConnect}
|
||||
onPress={() => onPressTag(tag.path)}
|
||||
/>
|
||||
) : null}
|
||||
<Tag
|
||||
selected={selectedTag === 'pair'}
|
||||
icon={SwapIcon}
|
||||
label="Pair"
|
||||
size={32}
|
||||
onPress={onPressPair}
|
||||
/>
|
||||
<Tag
|
||||
selected={selectedTag === 'create'}
|
||||
icon={AddSmallIcon}
|
||||
label="Create"
|
||||
size={32}
|
||||
onPress={onPressCreate}
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
)
|
||||
}
|
||||
|
@ -113,3 +113,12 @@ export const VALIDATORS_DATA = [
|
||||
status: 'Active',
|
||||
},
|
||||
]
|
||||
|
||||
// Pair Device
|
||||
export const VC = 'VC'
|
||||
export const VALIDATOR_CLIENT = 'Validator Client'
|
||||
export const BEACON = 'Beacon'
|
||||
export const NODE = 'Node'
|
||||
export const VC_PORT = '9000'
|
||||
export const BEACON_PORT = '5052'
|
||||
export const DEFAULT_ADDRESS = 'http://124.0.0.1'
|
||||
|
@ -1,130 +0,0 @@
|
||||
import { NodeIcon } from '@status-im/icons'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Button as StatusButton, Text, Checkbox } from '@status-im/components'
|
||||
import { Article, Label, Separator, Stack, XStack, YStack } from 'tamagui'
|
||||
|
||||
import BreadcrumbBar from '../../components/General/BreadcrumbBar/BreadcrumbBar'
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import Titles from '../../components/General/Titles'
|
||||
import LabelInputField from '../../components/General/LabelInputField'
|
||||
import Header from '../../components/General/Header'
|
||||
import CreateAvatar from '../../components/General/CreateAvatar/CreateAvatar'
|
||||
|
||||
const ConnectDevicePage = () => {
|
||||
const [autoConnectChecked, setAutoConnectChecked] = useState(false)
|
||||
const [portChecked, setPortChecked] = useState(false)
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth)
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth)
|
||||
}
|
||||
window.addEventListener('resize', handleResize)
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}, [])
|
||||
|
||||
const breakpoint = 268
|
||||
|
||||
const responsiveXStackStyle = {
|
||||
space: '$4',
|
||||
alignItems: 'center',
|
||||
flexDirection: windowWidth <= breakpoint ? 'column' : 'row',
|
||||
width: '55%',
|
||||
}
|
||||
const checkboxStackStyle = {
|
||||
marginTop: '20px',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}
|
||||
const responsiveInputStyle = {
|
||||
marginBottom: windowWidth <= breakpoint ? '0.5rem' : '0',
|
||||
width: '100%',
|
||||
}
|
||||
|
||||
return (
|
||||
<PageWrapperShadow
|
||||
breadcrumbBar={<BreadcrumbBar breadcrumbList={['Nodes', 'Nimbus', 'Connect Device']} />}
|
||||
rightImageSrc="./background-images/day-night-bg.png"
|
||||
rightImageLogo={true}
|
||||
>
|
||||
<YStack space={'$3'}>
|
||||
<Header selectedTag="connect" />
|
||||
|
||||
<Article className="content">
|
||||
<Titles
|
||||
title="Connect Device"
|
||||
subtitle="Configure your device to connect to the Nimbus Node Manager"
|
||||
/>
|
||||
<YStack my={16} width={'50%'}>
|
||||
<XStack style={responsiveXStackStyle} space={'$3'}>
|
||||
<Stack style={responsiveInputStyle}>
|
||||
<LabelInputField
|
||||
labelText="Beacon Address"
|
||||
placeholderText="something"
|
||||
width="100%"
|
||||
/>
|
||||
</Stack>
|
||||
<Stack style={responsiveInputStyle}>
|
||||
<LabelInputField labelText="Beacon Node Port" placeholderText="5052" width="100%" />
|
||||
</Stack>
|
||||
<Stack style={responsiveInputStyle}>
|
||||
<LabelInputField
|
||||
labelText="Client Validator Port"
|
||||
placeholderText="5052"
|
||||
width="100%"
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<YStack width={20} style={checkboxStackStyle}>
|
||||
<Checkbox
|
||||
id="port-checkbox"
|
||||
variant="outline"
|
||||
selected={portChecked}
|
||||
onCheckedChange={v => setPortChecked(v)}
|
||||
/>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack alignItems="center" width="100%">
|
||||
<LabelInputField
|
||||
labelText="API Token"
|
||||
placeholderText="****_*****_*****"
|
||||
width="180%"
|
||||
/>
|
||||
</XStack>
|
||||
</YStack>
|
||||
<YStack my={16}>
|
||||
<CreateAvatar></CreateAvatar>
|
||||
</YStack>
|
||||
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} />
|
||||
<YStack my={16}>
|
||||
<YStack>
|
||||
<Text size={19} weight="semibold">
|
||||
Settings
|
||||
</Text>
|
||||
</YStack>
|
||||
<XStack my={8} space={'$2'}>
|
||||
<Checkbox
|
||||
id="auto-connect"
|
||||
selected={autoConnectChecked}
|
||||
onCheckedChange={v => setAutoConnectChecked(v)}
|
||||
variant="outline"
|
||||
/>
|
||||
<Label htmlFor="auto-connect">
|
||||
<Text size={15} weight="regular">
|
||||
Auto Connect Device
|
||||
</Text>
|
||||
</Label>
|
||||
</XStack>
|
||||
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} />
|
||||
</YStack>
|
||||
<div>
|
||||
<StatusButton icon={<NodeIcon size={20} />}>Connect Device</StatusButton>
|
||||
</div>
|
||||
</Article>
|
||||
</YStack>
|
||||
</PageWrapperShadow>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConnectDevicePage
|
@ -1,88 +0,0 @@
|
||||
import { Checkbox, Input, Text } from '@status-im/components'
|
||||
import { useState } from 'react'
|
||||
import { Stack, Switch, XStack, YStack } from 'tamagui'
|
||||
|
||||
const BeaconAddress = () => {
|
||||
const [isBeaconSwitchOn, setIsBeaconSwitchOn] = useState(false)
|
||||
const [inputAdress, setInputAdress] = useState('')
|
||||
const [vcPort, setVcPort] = useState('')
|
||||
const [isClientAddressChecked, setIsClientAddressChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<YStack>
|
||||
<XStack justifyContent={'space-between'}>
|
||||
<YStack space={'$2'}>
|
||||
<YStack>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
{' '}
|
||||
Protocol{' '}
|
||||
</Text>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
{' '}
|
||||
(HTTP/HTTPS)
|
||||
</Text>
|
||||
</YStack>
|
||||
|
||||
<Switch
|
||||
size="$1"
|
||||
style={isBeaconSwitchOn ? { backgroundColor: '#2A4AF5' } : { backgroundColor: 'grey' }}
|
||||
checked={isBeaconSwitchOn}
|
||||
onCheckedChange={() => setIsBeaconSwitchOn(prev => !prev)}
|
||||
>
|
||||
<Switch.Thumb
|
||||
style={{
|
||||
right: 7,
|
||||
bottom: 3,
|
||||
backgroundColor: '#fff',
|
||||
height: '16px',
|
||||
width: '16px',
|
||||
}}
|
||||
/>
|
||||
</Switch>
|
||||
</YStack>
|
||||
<YStack space={'$2'}>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
Beacon Address
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={''}
|
||||
value={inputAdress}
|
||||
onChangeText={e => {
|
||||
setInputAdress(e)
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
|
||||
<YStack space={'$2'}>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
VC Port
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={''}
|
||||
value={vcPort}
|
||||
onChangeText={e => {
|
||||
setVcPort(e)
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
<Stack
|
||||
style={{ alignItems: 'center', justifyContent: 'center' }}
|
||||
height={'100%'}
|
||||
marginTop={'10px'}
|
||||
width={'fit-content'}
|
||||
>
|
||||
<Checkbox
|
||||
id="checkforaddress"
|
||||
variant="outline"
|
||||
selected={isClientAddressChecked}
|
||||
onCheckedChange={() => setIsClientAddressChecked(prev => !prev)}
|
||||
size={20}
|
||||
/>
|
||||
</Stack>
|
||||
</XStack>
|
||||
<XStack></XStack>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default BeaconAddress
|
@ -1,87 +0,0 @@
|
||||
import { Checkbox, Input, Text } from '@status-im/components'
|
||||
import { useState } from 'react'
|
||||
import { Stack, Switch, XStack, YStack } from 'tamagui'
|
||||
|
||||
const ClientAddressRow = () => {
|
||||
const [isBeaconSwitchOn, setIsBeaconSwitchOn] = useState(false)
|
||||
const [inputAdress, setInputAdress] = useState('')
|
||||
const [vcPort, setVcPort] = useState('')
|
||||
const [isClientAddressChecked, setIsClientAddressChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<YStack>
|
||||
<XStack justifyContent={'space-between'}>
|
||||
<YStack space={'$2'}>
|
||||
<YStack>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
{' '}
|
||||
Protocol{' '}
|
||||
</Text>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
{' '}
|
||||
(HTTP/HTTPS)
|
||||
</Text>
|
||||
</YStack>
|
||||
<Switch
|
||||
size="$1"
|
||||
style={isBeaconSwitchOn ? { backgroundColor: '#2A4AF5' } : { backgroundColor: 'grey' }}
|
||||
checked={isBeaconSwitchOn}
|
||||
onCheckedChange={() => setIsBeaconSwitchOn(prev => !prev)}
|
||||
>
|
||||
<Switch.Thumb
|
||||
style={{
|
||||
right: 7,
|
||||
bottom: 3,
|
||||
backgroundColor: '#fff',
|
||||
height: '16px',
|
||||
width: '16px',
|
||||
}}
|
||||
/>
|
||||
</Switch>
|
||||
</YStack>
|
||||
<YStack space={'$2'}>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
Validator Client Address
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={''}
|
||||
value={inputAdress}
|
||||
onChangeText={e => {
|
||||
setInputAdress(e)
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
|
||||
<YStack space={'$2'}>
|
||||
<Text size={11} color={'#647084'} weight={'regular'}>
|
||||
VC Port
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={''}
|
||||
value={vcPort}
|
||||
onChangeText={e => {
|
||||
setVcPort(e)
|
||||
}}
|
||||
/>
|
||||
</YStack>
|
||||
<Stack
|
||||
style={{ alignItems: 'center', justifyContent: 'center' }}
|
||||
height={'100%'}
|
||||
marginTop={'10px'}
|
||||
width={'fit-content'}
|
||||
>
|
||||
<Checkbox
|
||||
id="checkforaddress"
|
||||
variant="outline"
|
||||
selected={isClientAddressChecked}
|
||||
onCheckedChange={() => setIsClientAddressChecked(prev => !prev)}
|
||||
size={20}
|
||||
/>
|
||||
</Stack>
|
||||
</XStack>
|
||||
<XStack></XStack>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default ClientAddressRow
|
@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ConnectExistingInstance from './ConnectExistingInstance'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/ConnectExistingInstance',
|
||||
component: ConnectExistingInstance,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof ConnectExistingInstance>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {},
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
import { Separator, XStack, YStack } from 'tamagui'
|
||||
import { useState } from 'react'
|
||||
import { Button, Input, Text } from '@status-im/components'
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
|
||||
import Titles from '../../components/General/Titles'
|
||||
|
||||
import { NodeIcon, SettingsIcon, CompleteIdIcon, ClearIcon } from '@status-im/icons'
|
||||
import Header from '../../components/General/Header'
|
||||
|
||||
import ClientAddressRow from './ClientAddressRow'
|
||||
import BeaconAddress from './BeaconAddress'
|
||||
|
||||
const ConnectExistingInstance = () => {
|
||||
const [encryptedPassword, setEncryptedPassword] = useState('')
|
||||
|
||||
const changeEncryptedPasswordHandler = (value: string) => {
|
||||
setEncryptedPassword(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="./background-images/day-night-bg.png" rightImageLogo={true}>
|
||||
<YStack
|
||||
space={'$3'}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
>
|
||||
<Header selectedTag="pair" />
|
||||
<Titles
|
||||
title="Connect to existing Nimbus Instance"
|
||||
subtitle="Pair your existing device to the Nimbus Node Manager "
|
||||
/>
|
||||
<XStack style={{ justifyContent: 'space-between' }}>
|
||||
<Text size={19} weight={'semibold'} color="#09101C">
|
||||
Connect via IP
|
||||
</Text>
|
||||
<Button variant="grey" size={24} icon={<SettingsIcon size={20} />}>
|
||||
Advanced
|
||||
</Button>
|
||||
</XStack>
|
||||
<ClientAddressRow />
|
||||
<BeaconAddress />
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<YStack space={'$2'}>
|
||||
<Text size={11} color={'#647084'}>
|
||||
API Token
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={'*****_*******_******'}
|
||||
icon={
|
||||
<ClearIcon
|
||||
size={16}
|
||||
color="#A1ABBD"
|
||||
onClick={() => setEncryptedPassword('')}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
}
|
||||
value={encryptedPassword}
|
||||
onChangeText={changeEncryptedPasswordHandler}
|
||||
/>
|
||||
</YStack>
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<Text size={19} weight={'semibold'} color="#09101C">
|
||||
Advanced Settings
|
||||
</Text>
|
||||
<XStack space={'$4'}>
|
||||
<Button icon={<CompleteIdIcon size={20} color="#2A4AF5" />} variant="outline">
|
||||
Pair with ID
|
||||
</Button>
|
||||
</XStack>
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<XStack>
|
||||
<Button icon={<NodeIcon size={20} />} variant="blue">
|
||||
Continue
|
||||
</Button>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</PageWrapperShadow>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConnectExistingInstance
|
@ -1,17 +1,17 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import BeaconAddress from './BeaconAddress'
|
||||
import CreateLocalNode from './CreateLocalNode'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/BeaconAddress',
|
||||
component: BeaconAddress,
|
||||
title: 'Pages/CreateLocalNode',
|
||||
component: CreateLocalNode,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof BeaconAddress>
|
||||
} satisfies Meta<typeof CreateLocalNode>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
@ -2,26 +2,25 @@ import { useState } from 'react'
|
||||
import { Button as StatusButton, Text, Checkbox } from '@status-im/components'
|
||||
import { NodeIcon } from '@status-im/icons'
|
||||
import { Label, Separator, XStack, YStack } from 'tamagui'
|
||||
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import Header from '../../components/General/Header'
|
||||
import Titles from '../../components/General/Titles'
|
||||
import CreateAvatar from '../../components/General/CreateAvatar/CreateAvatar'
|
||||
|
||||
const CreateLocalNodePage = () => {
|
||||
const CreateLocalNode = () => {
|
||||
const [autoConnectChecked, setAutoConnectChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="./background-images/day-night-bg.png" rightImageLogo={true}>
|
||||
<YStack space={'$3'}>
|
||||
<Header selectedTag="create" />
|
||||
<Header selectedTag="Create" />
|
||||
<article className="content">
|
||||
<Titles
|
||||
title="Create Local Node"
|
||||
subtitle="Configure your device to start Staking on Nimbus"
|
||||
/>
|
||||
|
||||
<CreateAvatar />
|
||||
|
||||
<YStack my={16}>
|
||||
<Text size={19} weight="semibold">
|
||||
Settings
|
||||
@ -48,4 +47,4 @@ const CreateLocalNodePage = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export default CreateLocalNodePage
|
||||
export default CreateLocalNode
|
@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import CreateLocalNodePage from './CreateLocalNodePage'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/CreateLocalNodePage',
|
||||
component: CreateLocalNodePage,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof CreateLocalNodePage>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {},
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ClientAddressRow from './ClientAddressRow'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
import ConnectViaIP from './ConnectViaIP'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/ClientAddressRow',
|
||||
component: ClientAddressRow,
|
||||
title: 'Pair Device/ConnectViaIP',
|
||||
component: ConnectViaIP,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof ClientAddressRow>
|
||||
} satisfies Meta<typeof ConnectViaIP>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
96
src/pages/PairDevice/ConnectViaIP/ConnectViaIP.tsx
Normal file
96
src/pages/PairDevice/ConnectViaIP/ConnectViaIP.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import { Separator, XStack, YStack } from 'tamagui'
|
||||
import { useState } from 'react'
|
||||
import { Button, Input, Text } from '@status-im/components'
|
||||
import { SettingsIcon, ClearIcon } from '@status-im/icons'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import InputsRow from './InputsRow'
|
||||
import { RootState } from '../../../redux/store'
|
||||
import { BEACON, NODE, VALIDATOR_CLIENT, VC } from '../../../constants'
|
||||
|
||||
const ConnectViaIP = () => {
|
||||
const [apiToken, setApiToken] = useState('')
|
||||
const [isAdvanced, setIsAdvanced] = useState(false)
|
||||
const {
|
||||
beaconPort,
|
||||
vcPort,
|
||||
nodeAddress,
|
||||
beaconAddress,
|
||||
vcAddress,
|
||||
isBeaconSwitchOn,
|
||||
isVcSwitchOn,
|
||||
isBeaconChecked,
|
||||
isVcChecked,
|
||||
} = useSelector((state: RootState) => state.pairDevice)
|
||||
|
||||
const changeApiToken = (value: string) => {
|
||||
setApiToken(value)
|
||||
}
|
||||
|
||||
const onAdvancedClickHandler = () => {
|
||||
setIsAdvanced(state => !state)
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$3'} maxWidth={'100%'}>
|
||||
<XStack style={{ justifyContent: 'space-between' }}>
|
||||
<Text size={19} weight={'semibold'} color="#09101C">
|
||||
Connect via IP
|
||||
</Text>
|
||||
<Button
|
||||
variant={isAdvanced ? 'darkGrey' : 'grey'}
|
||||
size={32}
|
||||
icon={<SettingsIcon size={20} />}
|
||||
onPress={onAdvancedClickHandler}
|
||||
>
|
||||
Advanced
|
||||
</Button>
|
||||
</XStack>
|
||||
{isAdvanced ? (
|
||||
<YStack space={'$3'}>
|
||||
<InputsRow
|
||||
addressType={VALIDATOR_CLIENT}
|
||||
portType={VC}
|
||||
address={vcAddress}
|
||||
port={vcPort}
|
||||
isAdvanced={isAdvanced}
|
||||
isSwitchOn={isVcSwitchOn}
|
||||
isChecked={isVcChecked}
|
||||
/>
|
||||
<InputsRow
|
||||
addressType={BEACON}
|
||||
portType={BEACON}
|
||||
address={beaconAddress}
|
||||
port={beaconPort}
|
||||
isAdvanced={isAdvanced}
|
||||
isSwitchOn={isBeaconSwitchOn}
|
||||
isChecked={isBeaconChecked}
|
||||
/>
|
||||
</YStack>
|
||||
) : (
|
||||
<InputsRow addressType={NODE} address={nodeAddress} port={''} portType={''} />
|
||||
)}
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<YStack space={'$2'}>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
API Token
|
||||
</Text>
|
||||
<Input
|
||||
placeholder={'*****_*******_******'}
|
||||
icon={
|
||||
<ClearIcon
|
||||
size={16}
|
||||
color="#A1ABBD"
|
||||
onClick={() => changeApiToken('')}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
}
|
||||
value={apiToken}
|
||||
onChangeText={changeApiToken}
|
||||
/>
|
||||
</YStack>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConnectViaIP
|
59
src/pages/PairDevice/ConnectViaIP/InputsRow.stories.tsx
Normal file
59
src/pages/PairDevice/ConnectViaIP/InputsRow.stories.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
import InputsRow from './InputsRow'
|
||||
import {
|
||||
BEACON,
|
||||
BEACON_PORT,
|
||||
DEFAULT_ADDRESS,
|
||||
NODE,
|
||||
VALIDATOR_CLIENT,
|
||||
VC,
|
||||
VC_PORT,
|
||||
} from '../../../constants'
|
||||
|
||||
const meta = {
|
||||
title: 'Pair Device/InputsRow',
|
||||
component: InputsRow,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof InputsRow>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Node: Story = {
|
||||
args: {
|
||||
addressType: NODE,
|
||||
address: DEFAULT_ADDRESS,
|
||||
port: '',
|
||||
portType: '',
|
||||
},
|
||||
}
|
||||
|
||||
export const ValidatorClient: Story = {
|
||||
args: {
|
||||
addressType: VALIDATOR_CLIENT,
|
||||
portType: VC,
|
||||
address: DEFAULT_ADDRESS,
|
||||
port: VC_PORT,
|
||||
isAdvanced: true,
|
||||
isSwitchOn: true,
|
||||
isChecked: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const Beacon: Story = {
|
||||
args: {
|
||||
addressType: BEACON,
|
||||
portType: BEACON,
|
||||
address: DEFAULT_ADDRESS,
|
||||
port: BEACON_PORT,
|
||||
isAdvanced: true,
|
||||
isSwitchOn: true,
|
||||
isChecked: true,
|
||||
},
|
||||
}
|
106
src/pages/PairDevice/ConnectViaIP/InputsRow.tsx
Normal file
106
src/pages/PairDevice/ConnectViaIP/InputsRow.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import { Checkbox, Input, Text } from '@status-im/components'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { Stack, Switch, XStack, YStack } from 'tamagui'
|
||||
|
||||
import { RootState } from '../../../redux/store'
|
||||
import PortInput from './PortInput'
|
||||
import { BEACON, VC } from '../../../constants'
|
||||
|
||||
type InputsRowProps = {
|
||||
addressType: string
|
||||
portType: string
|
||||
isAdvanced?: boolean
|
||||
address: string
|
||||
port: string
|
||||
isSwitchOn?: boolean
|
||||
isChecked?: boolean
|
||||
}
|
||||
|
||||
const InputsRow = ({
|
||||
isAdvanced,
|
||||
addressType,
|
||||
portType,
|
||||
address,
|
||||
port,
|
||||
isSwitchOn,
|
||||
isChecked,
|
||||
}: InputsRowProps) => {
|
||||
const { beaconPort, vcPort, isNodeChecked, isNodeSwitchOn } = useSelector(
|
||||
(state: RootState) => state.pairDevice,
|
||||
)
|
||||
const dispatch = useDispatch()
|
||||
const isSwitchOnResult = isAdvanced ? isSwitchOn : isNodeSwitchOn
|
||||
const switchStyle = isSwitchOnResult
|
||||
? { backgroundColor: '#2A4AF5' }
|
||||
: { backgroundColor: 'grey' }
|
||||
|
||||
const onSwitchChange = (value: boolean) => {
|
||||
dispatch({ type: 'pairDevice/setIsSwitchOn', payload: { value, switchType: addressType } })
|
||||
}
|
||||
|
||||
const onCheckboxChange = (value: boolean) => {
|
||||
dispatch({ type: 'pairDevice/setIsChecked', payload: { value, checkType: addressType } })
|
||||
}
|
||||
|
||||
const onAddressChange = (value: string) => {
|
||||
dispatch({ type: 'pairDevice/setAddress', payload: { value, addressType } })
|
||||
}
|
||||
|
||||
return (
|
||||
<XStack space={'$3'}>
|
||||
<YStack space={'$2'} flexBasis={0} flexGrow={2}>
|
||||
<YStack>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
Protocol
|
||||
</Text>
|
||||
<Text size={11} color={'#647084'}>
|
||||
(HTTP/HTTPS)
|
||||
</Text>
|
||||
</YStack>
|
||||
<Switch
|
||||
size="$1"
|
||||
style={switchStyle}
|
||||
checked={isSwitchOnResult}
|
||||
onCheckedChange={onSwitchChange}
|
||||
>
|
||||
<Switch.Thumb
|
||||
style={{
|
||||
right: 7.6,
|
||||
bottom: 2.4,
|
||||
backgroundColor: '#fff',
|
||||
height: '16px',
|
||||
width: '16px',
|
||||
}}
|
||||
/>
|
||||
</Switch>
|
||||
</YStack>
|
||||
<YStack space={'$2'} flexBasis={0} flexGrow={isAdvanced ? 5 : 4}>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
{addressType} Address
|
||||
</Text>
|
||||
<Input value={address} onChangeText={onAddressChange} />
|
||||
</YStack>
|
||||
{isAdvanced ? (
|
||||
<PortInput port={port} portType={portType} />
|
||||
) : (
|
||||
<XStack space={'$3'} flexGrow={4} flexBasis={0}>
|
||||
<PortInput port={vcPort} portType={VC} />
|
||||
<PortInput port={beaconPort} portType={BEACON} />
|
||||
</XStack>
|
||||
)}
|
||||
<div style={{ display: 'flex', alignItems: 'end', height: '100%' }}>
|
||||
<Stack height={'46%'} flexBasis={0} flexGrow={0.5}>
|
||||
<Checkbox
|
||||
id="AddressAndPortInputs"
|
||||
variant="outline"
|
||||
selected={isAdvanced ? isChecked : isNodeChecked}
|
||||
onCheckedChange={onCheckboxChange}
|
||||
size={20}
|
||||
/>
|
||||
</Stack>
|
||||
</div>
|
||||
</XStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default InputsRow
|
32
src/pages/PairDevice/ConnectViaIP/PortInput.stories.tsx
Normal file
32
src/pages/PairDevice/ConnectViaIP/PortInput.stories.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
import PortInput from './PortInput'
|
||||
import { BEACON, BEACON_PORT, VC, VC_PORT } from '../../../constants'
|
||||
|
||||
const meta = {
|
||||
title: 'Pair Device/PortInput',
|
||||
component: PortInput,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof PortInput>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const ValidatorClient: Story = {
|
||||
args: {
|
||||
port: VC_PORT,
|
||||
portType: VC,
|
||||
},
|
||||
}
|
||||
|
||||
export const Beacon: Story = {
|
||||
args: {
|
||||
port: BEACON_PORT,
|
||||
portType: BEACON,
|
||||
},
|
||||
}
|
31
src/pages/PairDevice/ConnectViaIP/PortInput.tsx
Normal file
31
src/pages/PairDevice/ConnectViaIP/PortInput.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Input, Text } from '@status-im/components'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { YStack } from 'tamagui'
|
||||
|
||||
type PortInputProps = {
|
||||
portType: string
|
||||
port: string
|
||||
}
|
||||
|
||||
const PortInput = ({ portType, port }: PortInputProps) => {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const onPortChange = (value: string) => {
|
||||
if (isNaN(Number(value))) {
|
||||
return
|
||||
}
|
||||
|
||||
dispatch({ type: 'pairDevice/setPort', payload: { value, portType } })
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$2'} flexBasis={0} flexGrow={3}>
|
||||
<Text size={13} color={'#647084'} weight={'semibold'}>
|
||||
{portType} Port
|
||||
</Text>
|
||||
<Input value={port} onChangeText={onPortChange} />
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default PortInput
|
@ -4,7 +4,7 @@ import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
import PairDevice from './PairDevice'
|
||||
|
||||
const meta = {
|
||||
title: 'Connect-Device/PairDevice',
|
||||
title: 'Pages/PairDevice',
|
||||
component: PairDevice,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { NodeIcon } from '@status-im/icons'
|
||||
import { Separator, XStack, YStack } from 'tamagui'
|
||||
import { NodeIcon, CompleteIdIcon, ConnectionIcon } from '@status-im/icons'
|
||||
import { Label, Separator, XStack, YStack } from 'tamagui'
|
||||
import { useState } from 'react'
|
||||
import { Button, Text } from '@status-im/components'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Button, Checkbox, Text } from '@status-im/components'
|
||||
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import SyncStatus from './SyncStatus'
|
||||
@ -11,11 +10,12 @@ import PairedSuccessfully from './PairedSuccessfully'
|
||||
import CreateAvatar from '../../components/General/CreateAvatar/CreateAvatar'
|
||||
import GenerateId from './GenerateId'
|
||||
import Header from '../../components/General/Header'
|
||||
import Icon from '../../components/General/Icon'
|
||||
import ConnectViaIP from './ConnectViaIP/ConnectViaIP'
|
||||
|
||||
const PairDevice = () => {
|
||||
const [isAwaitingPairing, setIsAwaitingPairing] = useState(false)
|
||||
const navigate = useNavigate()
|
||||
const [isConnectingViaIp, setIsConnectingViaIp] = useState(false)
|
||||
const [isAutoConnectChecked, setIsAutoConnectChecked] = useState(false)
|
||||
const isPaired = false
|
||||
const isPairing = false
|
||||
|
||||
@ -23,27 +23,58 @@ const PairDevice = () => {
|
||||
setIsAwaitingPairing(result)
|
||||
}
|
||||
|
||||
const connectViaIpHandler = () => {
|
||||
navigate('/connect-device')
|
||||
const connectAndPairHandler = () => {
|
||||
setIsConnectingViaIp(state => !state)
|
||||
}
|
||||
|
||||
const continueHandler = () => {}
|
||||
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="./background-images/day-night-bg.png" rightImageLogo={true}>
|
||||
<YStack space={'$3'}>
|
||||
<Header selectedTag="pair" />
|
||||
<Header selectedTag="Pair" />
|
||||
<Titles
|
||||
title="Connect to existing Nimbus Instance"
|
||||
subtitle="Pair your existing device to the Nimbus Node Manager"
|
||||
/>
|
||||
{isPaired ? <PairedSuccessfully /> : <GenerateId isAwaitingPairing={isAwaitingPairing} />}
|
||||
{isPaired === false && (
|
||||
<SyncStatus
|
||||
isPairing={isPairing}
|
||||
isAwaitingPairing={isAwaitingPairing}
|
||||
changeSetIsAwaitingPairing={changeSetIsAwaitingPairing}
|
||||
/>
|
||||
{isConnectingViaIp ? (
|
||||
<ConnectViaIP />
|
||||
) : isPaired ? (
|
||||
<PairedSuccessfully />
|
||||
) : (
|
||||
<>
|
||||
<GenerateId isAwaitingPairing={isAwaitingPairing} />
|
||||
<SyncStatus
|
||||
isPairing={isPairing}
|
||||
isAwaitingPairing={isAwaitingPairing}
|
||||
changeSetIsAwaitingPairing={changeSetIsAwaitingPairing}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{isPaired === false && (
|
||||
{isPaired ? (
|
||||
<>
|
||||
<YStack space={'$3'}>
|
||||
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} marginTop={3} />
|
||||
<Text size={19} weight="semibold">
|
||||
General Settings
|
||||
</Text>
|
||||
<XStack space={'$4'} alignItems={'center'}>
|
||||
<Checkbox
|
||||
id="auto-connect"
|
||||
selected={isAutoConnectChecked}
|
||||
onCheckedChange={e => setIsAutoConnectChecked(e)}
|
||||
variant="outline"
|
||||
/>
|
||||
<Label htmlFor="auto-connect">
|
||||
<Text size={15} weight="regular">
|
||||
Auto Connect Paired Device
|
||||
</Text>
|
||||
</Label>
|
||||
</XStack>
|
||||
</YStack>
|
||||
<CreateAvatar />
|
||||
</>
|
||||
) : (
|
||||
<YStack space={'$3'}>
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<YStack space={'$1'}>
|
||||
@ -52,21 +83,26 @@ const PairDevice = () => {
|
||||
</Text>
|
||||
<XStack>
|
||||
<Button
|
||||
icon={<Icon src="/icons/connection-blue.svg" width={20} />}
|
||||
icon={
|
||||
isConnectingViaIp ? <CompleteIdIcon size={20} /> : <ConnectionIcon size={20} />
|
||||
}
|
||||
variant="outline"
|
||||
onPress={connectViaIpHandler}
|
||||
onPress={connectAndPairHandler}
|
||||
>
|
||||
Connect via IP
|
||||
{isConnectingViaIp ? 'Pair with ID' : 'Connect via IP'}
|
||||
</Button>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
)}
|
||||
{isPaired && <CreateAvatar />}
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<div>
|
||||
<Button icon={<NodeIcon size={20} />} disabled={!isPaired}>
|
||||
Continue
|
||||
<Button
|
||||
icon={<NodeIcon size={20} />}
|
||||
disabled={isConnectingViaIp ? false : !isPaired}
|
||||
onPress={continueHandler}
|
||||
>
|
||||
{isConnectingViaIp ? 'Connect Device' : 'Continue'}
|
||||
</Button>
|
||||
</div>
|
||||
</YStack>
|
||||
|
76
src/redux/PairDevice/slice.ts
Normal file
76
src/redux/PairDevice/slice.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { BEACON, BEACON_PORT, DEFAULT_ADDRESS, VALIDATOR_CLIENT, VC_PORT } from '../../constants'
|
||||
|
||||
type PairDeviceStateType = {
|
||||
beaconPort: string
|
||||
vcPort: string
|
||||
nodeAddress: string
|
||||
beaconAddress: string
|
||||
vcAddress: string
|
||||
isNodeSwitchOn: boolean
|
||||
isBeaconSwitchOn: boolean
|
||||
isVcSwitchOn: boolean
|
||||
isNodeChecked: boolean
|
||||
isBeaconChecked: boolean
|
||||
isVcChecked: boolean
|
||||
}
|
||||
|
||||
const initialState: PairDeviceStateType = {
|
||||
beaconPort: BEACON_PORT,
|
||||
vcPort: VC_PORT,
|
||||
nodeAddress: DEFAULT_ADDRESS,
|
||||
beaconAddress: DEFAULT_ADDRESS,
|
||||
vcAddress: DEFAULT_ADDRESS,
|
||||
isNodeSwitchOn: true,
|
||||
isBeaconSwitchOn: true,
|
||||
isVcSwitchOn: true,
|
||||
isNodeChecked: true,
|
||||
isBeaconChecked: true,
|
||||
isVcChecked: true,
|
||||
}
|
||||
|
||||
const pairDeviceSlice = createSlice({
|
||||
name: 'pairDevice',
|
||||
initialState,
|
||||
reducers: {
|
||||
setPort: (state, action) => {
|
||||
if (action.payload.portType === BEACON) {
|
||||
state.beaconPort = action.payload.value
|
||||
} else {
|
||||
state.vcPort = action.payload.value
|
||||
}
|
||||
},
|
||||
setAddress: (state, action) => {
|
||||
if (action.payload.addressType === BEACON) {
|
||||
state.beaconAddress = action.payload.value
|
||||
} else if (action.payload.addressType === VALIDATOR_CLIENT) {
|
||||
state.vcAddress = action.payload.value
|
||||
} else {
|
||||
state.nodeAddress = action.payload.value
|
||||
}
|
||||
},
|
||||
setIsSwitchOn: (state, action) => {
|
||||
if (action.payload.switchType === BEACON) {
|
||||
state.isBeaconSwitchOn = action.payload.value
|
||||
} else if (action.payload.switchType === VALIDATOR_CLIENT) {
|
||||
state.isVcSwitchOn = action.payload.value
|
||||
} else {
|
||||
state.isNodeSwitchOn = action.payload.value
|
||||
}
|
||||
},
|
||||
setIsChecked: (state, action) => {
|
||||
if (action.payload.checkType === BEACON) {
|
||||
state.isBeaconChecked = action.payload.value
|
||||
} else if (action.payload.checkType === VALIDATOR_CLIENT) {
|
||||
state.isVcChecked = action.payload.value
|
||||
} else {
|
||||
state.isNodeChecked = action.payload.value
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const {} = pairDeviceSlice.actions
|
||||
|
||||
export default pairDeviceSlice.reducer
|
@ -11,6 +11,7 @@ import rightSidebarReducer from './RightSidebar/slice'
|
||||
import validatorOnboardingReducer from './ValidatorOnboarding/slice'
|
||||
import advisoriesReducer from './ValidatorOnboarding/Advisories/slice'
|
||||
import validatorSetupReducer from './ValidatorOnboarding/ValidatorSetup/slice'
|
||||
import pairDeviceReducer from './PairDevice/slice'
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
@ -25,6 +26,7 @@ const store = configureStore({
|
||||
validatorOnboarding: validatorOnboardingReducer,
|
||||
advisories: advisoriesReducer,
|
||||
validatorSetup: validatorSetupReducer,
|
||||
pairDevice: pairDeviceReducer,
|
||||
},
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user