mirror of
https://github.com/status-im/nimbus-gui.git
synced 2025-02-03 07:03:30 +00:00
Merge pull request #4 from nimbus-gui/rd-hn.create-pair-device-page
feat: create pair device page
This commit is contained in:
commit
3ce69737b2
@ -10,6 +10,7 @@ const config: StorybookConfig = {
|
||||
'@storybook/addon-interactions',
|
||||
'storybook-addon-designs',
|
||||
'storybook-dark-mode',
|
||||
'storybook-addon-react-router-v6',
|
||||
],
|
||||
|
||||
docs: {
|
||||
|
@ -50,6 +50,7 @@
|
||||
"@storybook/test-runner": "^0.12.0",
|
||||
"@storybook/testing-library": "^0.2.0",
|
||||
"@types/react-color": "^3.0.6",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"@vitejs/plugin-react": "^4.0.3",
|
||||
@ -59,6 +60,7 @@
|
||||
"eslint-plugin-storybook": "^0.6.13",
|
||||
"prettier": "^3.0.1",
|
||||
"storybook": "^7.2.0",
|
||||
"storybook-addon-react-router-v6": "^2.0.5",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.9"
|
||||
},
|
||||
|
10
public/icons/block.svg
Normal file
10
public/icons/block.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="16/placeholder" clip-path="url(#clip0_1311_16617)">
|
||||
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M0.900146 7.9999C0.900146 4.07868 4.07892 0.899902 8.00015 0.899902C11.9214 0.899902 15.1001 4.07868 15.1001 7.9999C15.1001 11.9211 11.9214 15.0999 8.00015 15.0999C4.07893 15.0999 0.900146 11.9211 0.900146 7.9999ZM8.00015 2.0999C6.58695 2.0999 5.2898 2.59676 4.27385 3.42531L7.99995 7.15142L11.7262 3.42514C10.7103 2.59669 9.41325 2.0999 8.00015 2.0999ZM12.5748 4.27366L8.84848 7.99995L12.5747 11.7262C13.4033 10.7103 13.9001 9.4131 13.9001 7.9999C13.9001 6.58673 13.4033 5.2896 12.5748 4.27366ZM7.15143 7.99995L3.42534 4.27387C2.59692 5.28978 2.10015 6.58683 2.10015 7.9999C2.10015 9.413 2.59693 10.7101 3.42539 11.726L7.15143 7.99995ZM4.2739 12.5745L7.99995 8.84848L11.7262 12.5747C10.7103 13.4031 9.41322 13.8999 8.00015 13.8999C6.58697 13.8999 5.28984 13.4031 4.2739 12.5745Z" fill="#E95460"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1311_16617">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
8
public/icons/connection.svg
Normal file
8
public/icons/connection.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<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="white" fill-opacity="0.7"/>
|
||||
<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="white"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.0 KiB |
6
public/icons/refresh-black.svg
Normal file
6
public/icons/refresh-black.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="20/refresh">
|
||||
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M12.6404 3.62514C11.2371 3.04387 9.68124 2.94189 8.21407 3.33502C6.7469 3.72814 5.45045 4.59441 4.52578 5.79945C3.60112 7.0045 3.09992 8.48098 3.09992 9.99991C3.09992 11.5188 3.60112 12.9953 4.52578 14.2004C5.45045 15.4054 6.7469 16.2717 8.21407 16.6648C9.68124 17.0579 11.2371 16.9559 12.6404 16.3747C14.0437 15.7934 15.216 14.7653 15.9755 13.4499L17.0147 14.0499C16.1232 15.5941 14.747 16.801 13.0997 17.4833C11.4523 18.1657 9.62582 18.2854 7.90349 17.8239C6.18116 17.3624 4.65923 16.3455 3.57376 14.9309C2.48828 13.5163 1.89992 11.783 1.89992 9.99991C1.89992 8.21682 2.48828 6.48356 3.57376 5.06894C4.65923 3.65432 6.18116 2.6374 7.90349 2.17591C9.62582 1.71441 11.4523 1.83412 13.0997 2.51648C14.166 2.95819 15.1188 3.61967 15.9 4.45017L15.9 2.99978L17.1 2.99979L17.1 6.49979L17.0999 7.09979H16.5L13 7.09979V5.89979L15.5496 5.89979C14.8075 4.89526 13.8033 4.1068 12.6404 3.62514Z" fill="#09101C"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
5
public/icons/refresh.svg
Normal file
5
public/icons/refresh.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="20/refresh">
|
||||
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M12.6404 3.62514C11.2371 3.04387 9.68124 2.94189 8.21407 3.33502C6.7469 3.72814 5.45045 4.59441 4.52578 5.79945C3.60112 7.0045 3.09992 8.48098 3.09992 9.99991C3.09992 11.5188 3.60112 12.9953 4.52578 14.2004C5.45045 15.4054 6.7469 16.2717 8.21407 16.6648C9.68124 17.0579 11.2371 16.9559 12.6404 16.3747C14.0437 15.7934 15.216 14.7653 15.9755 13.4499L17.0147 14.0499C16.1232 15.5941 14.747 16.801 13.0997 17.4833C11.4523 18.1657 9.62582 18.2854 7.90349 17.8239C6.18116 17.3624 4.65923 16.3455 3.57376 14.9309C2.48828 13.5163 1.89992 11.783 1.89992 9.99991C1.89992 8.21682 2.48828 6.48356 3.57376 5.06894C4.65923 3.65432 6.18116 2.6374 7.90349 2.17591C9.62582 1.71441 11.4523 1.83412 13.0997 2.51648C14.166 2.95819 15.1188 3.61967 15.9 4.45017L15.9 2.99978L17.1 2.99979L17.1 6.49979L17.0999 7.09979H16.5L13 7.09979V5.89979L15.5496 5.89979C14.8075 4.89526 13.8033 4.1068 12.6404 3.62514Z" fill="#A1ABBD"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -7,6 +7,7 @@ import LandingPage from './pages/LandingPage/LandingPage'
|
||||
import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck'
|
||||
import ConnectDevicePage from './pages/ConnectDevicePage/ConnectDevicePage'
|
||||
import DeviceSyncStatus from './pages/DeviceSyncStatus/DeviceSyncStatus'
|
||||
import PairDevice from './pages/PairDevice/PairDevice'
|
||||
import { Provider as ReduxProvider } from 'react-redux'
|
||||
import PinnedNotification from './components/General/PinnedNottification'
|
||||
import store from './redux/store'
|
||||
@ -30,9 +31,10 @@ const router = createBrowserRouter([
|
||||
element: <DeviceSyncStatus />,
|
||||
},
|
||||
{
|
||||
path: '/create-local-node',
|
||||
element: <CreateLocalNodePage />,
|
||||
path: '/pair-device',
|
||||
element: <PairDevice />,
|
||||
},
|
||||
{ path: '/create-local-node', element: <CreateLocalNodePage /> },
|
||||
])
|
||||
function App() {
|
||||
return (
|
||||
|
@ -24,32 +24,27 @@ const DeviceSyncStatus = () => {
|
||||
}, [dispatch])
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="/background-images/sync-status-background.png">
|
||||
|
||||
<div className="container-inner landing-page">
|
||||
<YStack
|
||||
space={'$4'}
|
||||
style={{
|
||||
justifyContent: 'end',
|
||||
alignItems: 'start',
|
||||
marginBottom: '2rem',
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
>
|
||||
<NimbusLogo />
|
||||
<Titles
|
||||
title="Device Health Check"
|
||||
subtitle="Configure your device to start Staking on Nimbus"
|
||||
isAdvancedSettings={true}
|
||||
/>
|
||||
<YStack>
|
||||
<SyncStatusCardExecution synced={132432} total={200000} />
|
||||
<SyncStatusCardConsensus synced={149500} total={160000} />
|
||||
</YStack>
|
||||
<Stack style={{ marginTop: '1rem' }}>
|
||||
<Button>Continue</Button>
|
||||
</Stack>
|
||||
<YStack
|
||||
space={'$4'}
|
||||
style={{
|
||||
justifyContent: 'end',
|
||||
alignItems: 'start',
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
>
|
||||
<NimbusLogo />
|
||||
<Titles
|
||||
title="Sync Status"
|
||||
subtitle="Monitor your Validator Client and Beacon Node syncing progression."
|
||||
/>
|
||||
<YStack style={{ width: '100%' }}>
|
||||
<SyncStatusCardExecution synced={132432} total={200000} />
|
||||
<SyncStatusCardConsensus synced={149500} total={160000} />
|
||||
</YStack>
|
||||
</div>
|
||||
<Stack style={{ marginTop: '1rem' }}>
|
||||
<Button>Continue</Button>
|
||||
</Stack>
|
||||
</YStack>
|
||||
</PageWrapperShadow>
|
||||
)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ const SyncStatusCardConsensus: React.FC<DeviceStorageHealthProps> = ({ synced, t
|
||||
<Shadow
|
||||
variant="$2"
|
||||
style={{
|
||||
width: '632px',
|
||||
width: '100%',
|
||||
borderRadius: '16px',
|
||||
borderTopLeftRadius: '0px',
|
||||
borderTopRightRadius: '0px',
|
||||
|
@ -34,7 +34,7 @@ const SyncStatusCardExecution: React.FC<DeviceStorageHealthProps> = ({ synced, t
|
||||
<Shadow
|
||||
variant="$2"
|
||||
style={{
|
||||
width: '632px',
|
||||
width: '100%',
|
||||
borderRadius: '16px',
|
||||
borderBottomRightRadius: '0px',
|
||||
borderBottomLeftRadius: '0px',
|
||||
|
33
src/pages/PairDevice/CreateAvatar.tsx
Normal file
33
src/pages/PairDevice/CreateAvatar.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { XStack, YStack } from 'tamagui'
|
||||
import LabelInputField from '../../components/General/LabelInputField'
|
||||
import { Avatar, Text } from '@status-im/components'
|
||||
import ColorPicker from '../../components/General/ColorPicker'
|
||||
|
||||
import ReactionIcon from '../../components/Icons/ReactionIcon'
|
||||
// create func component
|
||||
export const CreateAvatar = () => {
|
||||
return (
|
||||
<YStack my={16}>
|
||||
<XStack space>
|
||||
<LabelInputField labelText="Device Name" placeholderText="Stake and chips" />
|
||||
</XStack>
|
||||
<XStack my={10} justifyContent={'space-between'}>
|
||||
<YStack mr={30}>
|
||||
<Text size={13} weight="regular" color={'#647084'}>
|
||||
Device Avatar
|
||||
</Text>
|
||||
<XStack my={10}>
|
||||
<Avatar type="account" size={80} name="Device Avatar" />
|
||||
<Avatar type="icon" size={32} icon={<ReactionIcon />} backgroundColor={'white'} />
|
||||
</XStack>
|
||||
</YStack>
|
||||
<YStack>
|
||||
<Text size={13} weight="regular" color={'#647084'}>
|
||||
Highlight Color
|
||||
</Text>
|
||||
<ColorPicker />
|
||||
</YStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
)
|
||||
}
|
30
src/pages/PairDevice/GenerateId.stories.tsx
Normal file
30
src/pages/PairDevice/GenerateId.stories.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import GenerateId from './GenerateId'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
const meta = {
|
||||
title: 'Pair Device/GenerateId',
|
||||
component: GenerateId,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof GenerateId>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const GenerateIdNotAwaiting: Story = {
|
||||
args: {
|
||||
isAwaitingPairing: false,
|
||||
},
|
||||
}
|
||||
|
||||
export const GenerateIdAwaiting: Story = {
|
||||
args: {
|
||||
isAwaitingPairing: true,
|
||||
},
|
||||
}
|
66
src/pages/PairDevice/GenerateId.tsx
Normal file
66
src/pages/PairDevice/GenerateId.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import { Button, Input, Text as StatusText } from '@status-im/components'
|
||||
import { CompleteIdIcon, CopyIcon } from '@status-im/icons'
|
||||
import { Text } from '@tamagui/web'
|
||||
import { useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Separator, XStack, YStack } from 'tamagui'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
type GenerateIdProps = {
|
||||
isAwaitingPairing: boolean
|
||||
}
|
||||
|
||||
const GenerateId = ({ isAwaitingPairing }: GenerateIdProps) => {
|
||||
const [generatedId, setGeneratedId] = useState('')
|
||||
|
||||
const generateIdHandler = () => {
|
||||
setGeneratedId(uuidv4())
|
||||
}
|
||||
|
||||
const copyGeneratedIdHandler = () => {
|
||||
navigator.clipboard.writeText(generatedId)
|
||||
}
|
||||
|
||||
return (
|
||||
<YStack space={'$2'}>
|
||||
<XStack style={{ justifyContent: 'space-between' }}>
|
||||
<StatusText size={19} weight={'semibold'}>
|
||||
Pair with Command line
|
||||
</StatusText>
|
||||
<Button
|
||||
variant="outline"
|
||||
size={24}
|
||||
icon={<CompleteIdIcon size={20} />}
|
||||
onPress={generateIdHandler}
|
||||
>
|
||||
Generate ID
|
||||
</Button>
|
||||
</XStack>
|
||||
<YStack space={'$2'}>
|
||||
<StatusText size={15} color={'#647084'}>
|
||||
Generated Pairing ID Input
|
||||
</StatusText>
|
||||
<Input
|
||||
placeholder={'nimbus pair <random-pairing-id>'}
|
||||
icon={
|
||||
<CopyIcon size={20} onClick={copyGeneratedIdHandler} style={{ cursor: 'pointer' }} />
|
||||
}
|
||||
value={generatedId}
|
||||
error={isAwaitingPairing}
|
||||
/>
|
||||
</YStack>
|
||||
<StatusText size={13} weight={'medium'} color={'#647084'}>
|
||||
Please execute the following command with your randomly generated pairing id on the machine
|
||||
where the Nimbus Service is running.{' '}
|
||||
<Text style={{ fontStyle: 'italic', fontWeight: 'normal' }}>Learn how with our </Text>
|
||||
<Link style={{ textDecoration: 'underline', color: 'inherit' }} to="/">
|
||||
Documentation
|
||||
</Link>
|
||||
.
|
||||
</StatusText>
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default GenerateId
|
22
src/pages/PairDevice/PairDevice.stories.ts
Normal file
22
src/pages/PairDevice/PairDevice.stories.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import { withRouter } from 'storybook-addon-react-router-v6'
|
||||
|
||||
import PairDevice from './PairDevice'
|
||||
|
||||
const meta = {
|
||||
title: 'Pages/PairDevice',
|
||||
component: PairDevice,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
decorators: [withRouter],
|
||||
} satisfies Meta<typeof PairDevice>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {},
|
||||
}
|
78
src/pages/PairDevice/PairDevice.tsx
Normal file
78
src/pages/PairDevice/PairDevice.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import { Separator, XStack, YStack } from 'tamagui'
|
||||
import { useState } from 'react'
|
||||
import { Button, Checkbox, Tag, Text } from '@status-im/components'
|
||||
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import SyncStatus from './SyncStatus'
|
||||
import NimbusLogo from '../../components/Logos/NimbusLogo'
|
||||
import PairIcon from '../../components/Icons/PairIcon'
|
||||
import CreateIcon from '../../components/Icons/CreateIcon'
|
||||
import NodeIcon from '../../components/Icons/NodeIcon'
|
||||
import Titles from '../../components/General/Titles'
|
||||
import PairedSuccessfully from './PairedSuccessfully'
|
||||
import { CreateAvatar } from './CreateAvatar'
|
||||
import GenerateId from './GenerateId'
|
||||
|
||||
const PairDevice = () => {
|
||||
const [autoChecked, setAutoChecked] = useState(false)
|
||||
const [isAwaitingPairing, setIsAwaitingPairing] = useState(false)
|
||||
const isPaired = false
|
||||
const isPairing = true
|
||||
|
||||
const changeSetIsAwaitingPairing = (result: boolean) => {
|
||||
setIsAwaitingPairing(result)
|
||||
}
|
||||
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="/background-images/day-night-bg.png">
|
||||
<YStack
|
||||
space={'$3'}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
>
|
||||
<XStack style={{ justifyContent: 'space-between' }}>
|
||||
<NimbusLogo />
|
||||
<XStack space={'$2'} style={{ alignItems: 'center' }}>
|
||||
<Tag icon={PairIcon} label="Pair" size={32} selected />
|
||||
<Tag icon={CreateIcon} label="Create" size={32} />
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Titles title="Pair Device" subtitle="Pair your device to the Nimbus Node Manager" />
|
||||
{isPaired ? <PairedSuccessfully /> : <GenerateId isAwaitingPairing={isAwaitingPairing} />}
|
||||
{!isPaired && (
|
||||
<SyncStatus
|
||||
isPairing={isPairing}
|
||||
isAwaitingPairing={isAwaitingPairing}
|
||||
changeSetIsAwaitingPairing={changeSetIsAwaitingPairing}
|
||||
/>
|
||||
)}
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<Text size={19} weight={'semibold'} color="#09101C">
|
||||
Settings
|
||||
</Text>
|
||||
<XStack space={'$4'}>
|
||||
<Checkbox
|
||||
id="port-checkbox"
|
||||
variant="outline"
|
||||
selected={autoChecked}
|
||||
onCheckedChange={v => {
|
||||
setAutoChecked(v)
|
||||
}}
|
||||
size={20}
|
||||
/>
|
||||
<Text size={15}>Auto Connect Paired Device</Text>
|
||||
</XStack>
|
||||
{isPaired && <CreateAvatar></CreateAvatar>}
|
||||
<Separator borderColor={'#e3e3e3'} />
|
||||
<XStack>
|
||||
<Button icon={<NodeIcon />} disabled={!isPaired}>
|
||||
Continue
|
||||
</Button>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</PageWrapperShadow>
|
||||
)
|
||||
}
|
||||
|
||||
export default PairDevice
|
20
src/pages/PairDevice/PairedSuccessfully.stories.tsx
Normal file
20
src/pages/PairDevice/PairedSuccessfully.stories.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import PairedSuccessfully from './PairedSuccessfully'
|
||||
|
||||
const meta = {
|
||||
title: 'Pair Device/PairedSuccessfully',
|
||||
component: PairedSuccessfully,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof PairedSuccessfully>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const PairedSuccessfullyExample: Story = {
|
||||
args: {},
|
||||
}
|
20
src/pages/PairDevice/PairedSuccessfully.tsx
Normal file
20
src/pages/PairDevice/PairedSuccessfully.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { Text } from '@status-im/components'
|
||||
import { YStack } from 'tamagui'
|
||||
|
||||
const PairedSuccessfully = () => {
|
||||
return (
|
||||
<YStack space={'$2'}>
|
||||
<Text size={19} weight={'semibold'}>
|
||||
Pair with Command line
|
||||
</Text>
|
||||
<Text size={11} weight={'semibold'} color="#647084">
|
||||
Device Sync Status
|
||||
</Text>
|
||||
<Text size={15} weight={'semibold'} color="#2A4AF5">
|
||||
Paired Successfully! 🥳
|
||||
</Text>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default PairedSuccessfully
|
22
src/pages/PairDevice/SyncStatus.stories.tsx
Normal file
22
src/pages/PairDevice/SyncStatus.stories.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import SyncStatus from './SyncStatus'
|
||||
|
||||
const meta = {
|
||||
title: 'Pair Device/SyncStatus',
|
||||
component: SyncStatus,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof SyncStatus>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {
|
||||
isPairing: true,
|
||||
},
|
||||
}
|
96
src/pages/PairDevice/SyncStatus.tsx
Normal file
96
src/pages/PairDevice/SyncStatus.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { XStack, YStack } from 'tamagui'
|
||||
import { Button, IconButton, InformationBox, Text } from '@status-im/components'
|
||||
|
||||
import Icon from '../../components/General/Icon'
|
||||
import RefreshBlackIcon from '/icons/refresh-black.svg'
|
||||
import RefreshIcon from '/icons/refresh.svg'
|
||||
import BlockIcon from '/icons/block.svg'
|
||||
import ConnectionIcon from '/icons/connection.svg'
|
||||
import { convertSecondsToTimerFormat } from '../../utilities'
|
||||
|
||||
type SyncStatusProps = {
|
||||
isPairing: boolean
|
||||
isAwaitingPairing?: boolean
|
||||
changeSetIsAwaitingPairing: (isAwaitingPairing: boolean) => void
|
||||
}
|
||||
|
||||
const SyncStatus = ({
|
||||
isPairing,
|
||||
isAwaitingPairing,
|
||||
changeSetIsAwaitingPairing,
|
||||
}: SyncStatusProps) => {
|
||||
const [elapsedTime, setElapsedTime] = useState(0)
|
||||
|
||||
const resetTimer = () => {
|
||||
setElapsedTime(0)
|
||||
changeSetIsAwaitingPairing(false)
|
||||
}
|
||||
useEffect(() => {
|
||||
let timer: ReturnType<typeof setTimeout>
|
||||
|
||||
if (isPairing) {
|
||||
timer = setInterval(() => {
|
||||
setElapsedTime(prevTime => prevTime + 65)
|
||||
if (elapsedTime >= 180) {
|
||||
changeSetIsAwaitingPairing(true)
|
||||
}
|
||||
}, 1000)
|
||||
} else {
|
||||
changeSetIsAwaitingPairing(false)
|
||||
}
|
||||
|
||||
return () => clearInterval(timer)
|
||||
}, [isPairing, elapsedTime])
|
||||
|
||||
const timer = convertSecondsToTimerFormat(elapsedTime) // Assuming you've imported the convertSecondsToTimerFormat function
|
||||
|
||||
return (
|
||||
<YStack space={'$2'}>
|
||||
<XStack style={{ justifyContent: 'space-between' }}>
|
||||
<Text size={11} color="#647084" weight="medium">
|
||||
Device Sync Status
|
||||
</Text>
|
||||
{isPairing && (
|
||||
<Text
|
||||
size={isAwaitingPairing ? 15 : 11}
|
||||
color={isAwaitingPairing ? '#EB5757' : '#647084'}
|
||||
weight={isAwaitingPairing && 'semibold'}
|
||||
>
|
||||
{timer}
|
||||
</Text>
|
||||
)}
|
||||
<IconButton
|
||||
icon={<Icon src={isPairing ? RefreshBlackIcon : RefreshIcon} />}
|
||||
onPress={resetTimer}
|
||||
variant="ghost"
|
||||
/>
|
||||
</XStack>
|
||||
{isPairing ? (
|
||||
<Text size={15} color={isAwaitingPairing ? '#EB5757' : '#09101C'} weight={'semibold'}>
|
||||
Awaiting pairing connection...
|
||||
</Text>
|
||||
) : (
|
||||
<Text size={13} color="#A1ABBD">
|
||||
No pairing input provided.
|
||||
</Text>
|
||||
)}
|
||||
{isAwaitingPairing && (
|
||||
<InformationBox
|
||||
message="No connection has been created to a Nimbus service for over 3 minutes. Please ensure that the generated pairing ID was input into the CLI. If you are unable to pair device, consider connect via IP. "
|
||||
variant="error"
|
||||
icon={<Icon src={BlockIcon} />}
|
||||
/>
|
||||
)}
|
||||
{isAwaitingPairing && (
|
||||
<XStack>
|
||||
<Button icon={<Icon src={ConnectionIcon} />} size={40}>
|
||||
Connect via IP
|
||||
</Button>
|
||||
</XStack>
|
||||
)}
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default SyncStatus
|
@ -16,3 +16,9 @@
|
||||
export function assertUnreachable(value: never): never {
|
||||
throw new Error(`Unreachable case: ${value}`);
|
||||
}
|
||||
|
||||
export const convertSecondsToTimerFormat = (seconds: number) => {
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const remainingSeconds = seconds % 60
|
||||
return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`
|
||||
}
|
45
yarn.lock
45
yarn.lock
@ -7192,6 +7192,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/uuid@npm:^9.0.2":
|
||||
version: 9.0.2
|
||||
resolution: "@types/uuid@npm:9.0.2"
|
||||
checksum: 1754bcf3444e1e3aeadd6e774fc328eb53bc956665e2e8fb6ec127aa8e1f43d9a224c3d22a9a6233dca8dd81a12dc7fed4d84b8876dd5ec82d40f574f7ff8b68
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/wait-on@npm:^5.2.0":
|
||||
version: 5.3.1
|
||||
resolution: "@types/wait-on@npm:5.3.1"
|
||||
@ -8722,6 +8729,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"compare-versions@npm:^6.0.0":
|
||||
version: 6.1.0
|
||||
resolution: "compare-versions@npm:6.1.0"
|
||||
checksum: d4e2a45706a023d8d0b6680338b66b79e20bd02d1947f0ac6531dab634cbed89fa373b3f03d503c5e489761194258d6e1bae67a07f88b1efc61648454f2d47e7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"compressible@npm:~2.0.16":
|
||||
version: 2.0.18
|
||||
resolution: "compressible@npm:2.0.18"
|
||||
@ -13824,6 +13838,7 @@ __metadata:
|
||||
"@types/react": 18
|
||||
"@types/react-color": ^3.0.6
|
||||
"@types/react-dom": 18
|
||||
"@types/uuid": ^9.0.2
|
||||
"@typescript-eslint/eslint-plugin": ^6.0.0
|
||||
"@typescript-eslint/parser": ^6.0.0
|
||||
"@vitejs/plugin-react": ^4.0.3
|
||||
@ -13841,6 +13856,7 @@ __metadata:
|
||||
react-redux: ^8.1.2
|
||||
react-router-dom: ^6.14.2
|
||||
storybook: ^7.2.0
|
||||
storybook-addon-react-router-v6: ^2.0.5
|
||||
tamagui: 1.36.4
|
||||
typescript: ^5.0.2
|
||||
vite: ^4.4.9
|
||||
@ -14950,7 +14966,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-inspector@npm:^6.0.0":
|
||||
"react-inspector@npm:6.0.2, react-inspector@npm:^6.0.0":
|
||||
version: 6.0.2
|
||||
resolution: "react-inspector@npm:6.0.2"
|
||||
peerDependencies:
|
||||
@ -16170,6 +16186,33 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"storybook-addon-react-router-v6@npm:^2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "storybook-addon-react-router-v6@npm:2.0.5"
|
||||
dependencies:
|
||||
compare-versions: ^6.0.0
|
||||
react-inspector: 6.0.2
|
||||
peerDependencies:
|
||||
"@storybook/blocks": ^7.0.0
|
||||
"@storybook/channels": ^7.0.0
|
||||
"@storybook/components": ^7.0.0
|
||||
"@storybook/core-events": ^7.0.0
|
||||
"@storybook/manager-api": ^7.0.0
|
||||
"@storybook/preview-api": ^7.0.0
|
||||
"@storybook/theming": ^7.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react-router: ^6.4.0
|
||||
react-router-dom: ^6.4.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
checksum: 19cca302dae97f50f6ec6b91358ca16f9c9b1e6a5ff91c51b762016c1be66390a10438fb7de7eed7130add5e873845f884605a8e3b8188f40153811dc665935d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"storybook@npm:^7.2.0":
|
||||
version: 7.2.1
|
||||
resolution: "storybook@npm:7.2.1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user