mirror of
https://github.com/status-im/nimbus-gui.git
synced 2025-02-03 07:03:30 +00:00
Merge branch 'main' into rd.use-icons-from-status
This commit is contained in:
commit
2317f7ebb4
@ -10,6 +10,7 @@ const config: StorybookConfig = {
|
||||
'@storybook/addon-interactions',
|
||||
'storybook-addon-designs',
|
||||
'storybook-dark-mode',
|
||||
'storybook-addon-react-router-v6',
|
||||
],
|
||||
|
||||
docs: {
|
||||
|
@ -19,6 +19,7 @@
|
||||
"dependencies": {
|
||||
"@nivo/line": "^0.83.0",
|
||||
"@nivo/pie": "^0.83.0",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"@status-im/colors": "*",
|
||||
"@status-im/components": "^0.2.6",
|
||||
"@tamagui/config": "1.36.4",
|
||||
@ -28,9 +29,11 @@
|
||||
"@types/react-dom": "18",
|
||||
"expo-modules-core": "^1.5.9",
|
||||
"react": "18",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "18",
|
||||
"react-native": "^0.72.3",
|
||||
"react-native-svg": "^13.10.0",
|
||||
"react-redux": "^8.1.2",
|
||||
"react-router-dom": "^6.14.2",
|
||||
"tamagui": "1.36.4"
|
||||
},
|
||||
@ -46,6 +49,8 @@
|
||||
"@storybook/react-vite": "^7.2.0",
|
||||
"@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",
|
||||
@ -55,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 |
27
src/App.css
27
src/App.css
@ -1,30 +1,3 @@
|
||||
#root {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
a:nth-of-type(2) .logo {
|
||||
animation: logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
/* span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
} */
|
||||
|
||||
.mb-1 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.mt-1 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.my-1 {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.py-05 {
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
27
src/App.tsx
27
src/App.tsx
@ -7,6 +7,11 @@ 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'
|
||||
import CreateLocalNodePage from './pages/CreateLocalNodePage/CreateLocalNodePage'
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@ -20,21 +25,27 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: '/connect-device',
|
||||
element: <ConnectDevicePage />,
|
||||
|
||||
},
|
||||
{
|
||||
path: '/device-sync-status',
|
||||
element: <DeviceSyncStatus />,
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/pair-device',
|
||||
element: <PairDevice />,
|
||||
},
|
||||
{ path: '/create-local-node', element: <CreateLocalNodePage /> },
|
||||
])
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<TamaguiProvider config={config}>
|
||||
<StatusProvider>
|
||||
<RouterProvider router={router} />
|
||||
</StatusProvider>
|
||||
</TamaguiProvider>
|
||||
<ReduxProvider store={store}>
|
||||
<TamaguiProvider config={config}>
|
||||
<StatusProvider>
|
||||
<PinnedNotification />
|
||||
<RouterProvider router={router} />
|
||||
</StatusProvider>
|
||||
</TamaguiProvider>
|
||||
</ReduxProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthPr
|
||||
justifyContent="space-between"
|
||||
style={{
|
||||
padding: '8px 16px',
|
||||
position: 'relative', // Make XStack a positioning context
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
|
||||
|
@ -4,19 +4,14 @@
|
||||
padding: 1rem 2rem;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
.breadcrumb-bar-ul {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.breadcrumb-bar-li {
|
||||
padding: 0 1em;
|
||||
color: #647084;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
.breadcrumb-bar-li:last-child {
|
||||
color: #09101C;
|
||||
}
|
||||
.breadcrumb-bar-li::after {
|
||||
display: inline-block;
|
||||
content: url("/icons/chevron.svg");
|
||||
@ -26,10 +21,7 @@
|
||||
left: 100%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.breadcrumb-bar-li:last-child {
|
||||
color: #09101C;
|
||||
|
||||
}
|
||||
.breadcrumb-bar-li:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import './breadcrumbbar.css'
|
||||
import './BreadcrumbBar.css'
|
||||
|
||||
type BreadcrumbBarProps = {
|
||||
breadcrumbList: string[]
|
||||
|
19
src/components/General/ColorPicker.stories.tsx
Normal file
19
src/components/General/ColorPicker.stories.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import ColorPicker from './ColorPicker'
|
||||
|
||||
const meta = {
|
||||
title: 'General/ColorPicker',
|
||||
component: ColorPicker,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ColorPicker>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const DefaultColors: Story = {
|
||||
args: {},
|
||||
}
|
33
src/components/General/ColorPicker.tsx
Normal file
33
src/components/General/ColorPicker.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useState } from 'react'
|
||||
import { CirclePicker } from 'react-color'
|
||||
import { XStack } from 'tamagui'
|
||||
|
||||
const ColorPicker = () => {
|
||||
const [chosenColor, setChosenColor] = useState('#FFFFFF')
|
||||
return (
|
||||
<XStack my={10}>
|
||||
<CirclePicker
|
||||
width="80%"
|
||||
circleSize={40}
|
||||
circleSpacing={12}
|
||||
colors={[
|
||||
'#2A4AF5',
|
||||
'#F6B03C',
|
||||
'#7140FD',
|
||||
'#2A799B',
|
||||
'#EC266C',
|
||||
'#1992D7',
|
||||
'#FF7D46',
|
||||
'#216266',
|
||||
'#F66F8F',
|
||||
'#C78F67',
|
||||
'#CB6256',
|
||||
]}
|
||||
color={chosenColor}
|
||||
onChange={color => setChosenColor(color.hex)}
|
||||
/>
|
||||
</XStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default ColorPicker
|
6
src/components/General/LabelInputField.css
Normal file
6
src/components/General/LabelInputField.css
Normal file
@ -0,0 +1,6 @@
|
||||
.input-container {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { Input as StatusInput, Text } from '@status-im/components'
|
||||
import { Label } from 'tamagui'
|
||||
import './LabelInputField.css'
|
||||
|
||||
type LabelInputProps = {
|
||||
labelText: string
|
||||
@ -12,7 +13,9 @@ function LabelInputField({ labelText, placeholderText }: LabelInputProps) {
|
||||
<Text size={13} weight="regular" color={'#647084'}>
|
||||
{labelText}
|
||||
</Text>
|
||||
<StatusInput placeholder={placeholderText} width={'100%'} />
|
||||
<div className="input-container">
|
||||
<StatusInput placeholder={placeholderText} width={'100%'} />
|
||||
</div>
|
||||
</Label>
|
||||
)
|
||||
}
|
||||
|
26
src/components/General/PinnedNottification.tsx
Normal file
26
src/components/General/PinnedNottification.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { PinnedMessage } from '@status-im/components'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from '../../redux/store'
|
||||
|
||||
function PinnedNotification() {
|
||||
const pinnedMessage = useSelector((state: RootState) => state.pinnedMessage.pinnedMessage)
|
||||
console.log(pinnedMessage)
|
||||
return (
|
||||
<>
|
||||
{pinnedMessage && pinnedMessage.pinned && (
|
||||
<PinnedMessage
|
||||
messages={[
|
||||
{
|
||||
id: pinnedMessage.id,
|
||||
reactions: {},
|
||||
pinned: pinnedMessage.pinned,
|
||||
text: pinnedMessage.text,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default PinnedNotification
|
@ -14,22 +14,12 @@
|
||||
}
|
||||
.quick-start-bar > div {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-radius: 24px;
|
||||
background: rgba(100, 112, 132, 0.05);
|
||||
margin-left: 1rem;
|
||||
padding: 1rem 0.5rem;
|
||||
}
|
||||
.quick-start-bar ul {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.quick-start-bar ul li {
|
||||
padding: 0 1rem;
|
||||
color: #0D1625;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ const QuickStartBar = () => {
|
||||
<li>Nodes Community</li>
|
||||
<li>Documentation</li>
|
||||
</ul>
|
||||
<button className="inversed">Quick Start</button>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
|
4
src/components/General/TagContainer.css
Normal file
4
src/components/General/TagContainer.css
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
.tag-container div:nth-child(1) {
|
||||
background:transparent;
|
||||
}
|
16
src/components/General/TagContainer.tsx
Normal file
16
src/components/General/TagContainer.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Tag } from '@status-im/components'
|
||||
import { XStack } from 'tamagui'
|
||||
import PairIcon from '../Icons/PairIcon'
|
||||
import CreateIcon from '../Icons/CreateIcon'
|
||||
import './TagContainer.css'
|
||||
|
||||
const TagContainer = () => {
|
||||
return (
|
||||
<XStack space={'$2'} alignItems="center" className="tag-container">
|
||||
<Tag icon={PairIcon} label="Pair" size={32} />
|
||||
<Tag selected icon={CreateIcon} label="Create" size={32} />
|
||||
</XStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default TagContainer
|
@ -7,7 +7,7 @@ type TitleProps = {
|
||||
|
||||
const Title = ({ color, children }: TitleProps) => {
|
||||
return (
|
||||
<Text size={27} weight={'medium'} color={color}>
|
||||
<Text size={27} weight={'semibold'} color={color}>
|
||||
{children}
|
||||
</Text>
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ type TitlesProps = {
|
||||
|
||||
const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => {
|
||||
return (
|
||||
<YStack style={{ width: '100%' }}>
|
||||
<YStack style={{ width: '100%', margin: '0 0 1em' }}>
|
||||
<XStack style={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Title color={'#09101C'}>{title}</Title>
|
||||
{isAdvancedSettings && (
|
||||
|
16
src/components/Icons/ReactionIcon.tsx
Normal file
16
src/components/Icons/ReactionIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
function ReactionIcon() {
|
||||
return (
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="20/reaction">
|
||||
<path
|
||||
id="body"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M9.2416 3.15729C10.5065 2.96514 11.7973 3.25797 12.9173 4.00409L13.5826 3.0054C12.2242 2.10051 10.6337 1.73206 9.06137 1.9709C7.49044 2.20954 6.04779 3.03734 4.9503 4.30368C3.8539 5.56876 3.15891 7.20428 2.95938 8.95297C2.75985 10.7017 3.06503 12.4813 3.83416 14.0184C4.60352 15.556 5.80023 16.7757 7.25373 17.4704C8.70989 18.1663 10.3311 18.2901 11.8595 17.8176C13.3854 17.3458 14.7159 16.312 15.6563 14.8979C16.5962 13.4846 17.0999 11.763 17.0999 9.99994H15.8999C15.8999 10.2934 15.8839 10.585 15.8524 10.8732C15.8428 10.8931 15.8307 10.9166 15.816 10.943C15.7594 11.0449 15.6664 11.185 15.5256 11.3258C15.2556 11.5958 14.7804 11.9 13.9499 11.9C13.1194 11.9 12.6442 11.5958 12.3742 11.3258C12.2334 11.185 12.1404 11.0449 12.0838 10.943C12.0556 10.8924 12.0372 10.8524 12.0268 10.8281C12.0216 10.8161 12.0185 10.8081 12.0173 10.8048L12.0169 10.8037L12.0177 10.806L12.0183 10.8079L12.0187 10.809L12.0189 10.8096C12.019 10.81 12.0191 10.8103 11.4499 11C10.8807 11.1898 10.8808 11.1901 10.8809 11.1905L10.8812 11.1912L10.8817 11.1927L10.8829 11.1963L10.8859 11.205L10.8947 11.2289C10.9018 11.2477 10.9114 11.2719 10.9238 11.3008C10.9486 11.3586 10.9848 11.4358 11.0348 11.5258C11.1344 11.7052 11.2914 11.94 11.5256 12.1743C12.0056 12.6542 12.7804 13.1 13.9499 13.1C14.514 13.1 14.9863 12.9963 15.3779 12.8351C15.1868 13.3304 14.9453 13.8001 14.6571 14.2334C13.8554 15.4389 12.7433 16.2883 11.505 16.6712C10.2691 17.0533 8.95894 16.9554 7.77119 16.3877C6.58079 15.8187 5.56884 14.8035 4.90732 13.4814C4.24558 12.159 3.97764 10.614 4.15165 9.08901C4.32565 7.56394 4.92997 6.15939 5.85712 5.08959C6.78319 4.02105 7.97527 3.34966 9.2416 3.15729ZM10.4999 8.49994C11.0522 8.49994 11.4999 7.82836 11.4999 6.99994C11.4999 6.17151 11.0522 5.49993 10.4999 5.49993C9.94762 5.49993 9.49991 6.17151 9.49991 6.99994C9.49991 7.82836 9.94762 8.49994 10.4999 8.49994ZM16.9999 6.99994C16.9999 7.82836 16.5522 8.49994 15.9999 8.49994C15.4476 8.49994 14.9999 7.82836 14.9999 6.99994C14.9999 6.17151 15.4476 5.49993 15.9999 5.49993C16.5522 5.49993 16.9999 6.17151 16.9999 6.99994Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
export default ReactionIcon
|
5
src/components/Logos/NimbusLogo.css
Normal file
5
src/components/Logos/NimbusLogo.css
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
.nimbus-logomark{
|
||||
width: auto;
|
||||
height: 30%;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { XStack } from 'tamagui'
|
||||
import BetaTag from './BetaTag'
|
||||
import './NimbusLogo.css'
|
||||
|
||||
const NimbusLogo = () => {
|
||||
return (
|
||||
|
@ -25,8 +25,8 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
padding: 70px 0 0;
|
||||
}
|
||||
.container-inner {
|
||||
max-width: 70%;
|
||||
@ -34,88 +34,42 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
header > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.logo-title {
|
||||
font-size: 27px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
.logo-title .beta{
|
||||
color: #FFF;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
border-radius: 66.667px;
|
||||
background-color: #2A4AF5;
|
||||
padding: 4px 6px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.content .title {
|
||||
font-size: 27px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
.content .subtitle {
|
||||
font-size: 15px;
|
||||
margin: 0.1em;
|
||||
}
|
||||
.content .subtitle span{
|
||||
font-weight: 700;
|
||||
}
|
||||
.content button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.content button span {
|
||||
padding-right: 10px;
|
||||
|
||||
/* LAYOUT RIGHT ELEMENT WITH IMAGE TAKING UP THE WHOLE HIGHT OF THE VIEWPORT */
|
||||
.layout-right {
|
||||
flex: 0 0 45%;
|
||||
max-width: 45%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
|
||||
/* LAYOUT RIGHT ELEMENT WITH IMAGE TAKING UP THE WHOLE HIGHT OF THE VIEWPORT */
|
||||
.layout-right {
|
||||
flex: 0 0 45%;
|
||||
max-width: 45%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.image-container::before {
|
||||
display: block;
|
||||
content: "";
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
.image-container::after {
|
||||
display: block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 1) 20%, rgba(255, 255, 255, 0.0));
|
||||
}
|
||||
.image-container img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
height: 140%;
|
||||
width: auto;
|
||||
}
|
||||
.image-container {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.image-container::before {
|
||||
display: block;
|
||||
content: "";
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
.image-container::after {
|
||||
display: block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 1) 20%, rgba(255, 255, 255, 0.0));
|
||||
}
|
||||
.image-container img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
height: 140%;
|
||||
width: auto;
|
||||
}
|
||||
|
@ -13,69 +13,46 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
#storybook-root {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
line-height: 1.2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
text-decoration: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
button {
|
||||
border-radius: 12px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #2A4AF5;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button.inversed {
|
||||
border-radius: 12px;
|
||||
border: 1px solid #2A4AF5;
|
||||
color: #2A4AF5;
|
||||
padding: 0.75em 1.2em;
|
||||
font-size: 15px;
|
||||
background-color:transparent;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
.nimbus-logomark{
|
||||
width: auto;
|
||||
height: 30%;
|
||||
ul{
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
}
|
||||
ul li {
|
||||
padding: 0 1rem;
|
||||
font-size: 15px;
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
|
20
src/pages/CreateLocalNodePage/CreateLocalNodePage.stories.ts
Normal file
20
src/pages/CreateLocalNodePage/CreateLocalNodePage.stories.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import CreateLocalNodePage from './CreateLocalNodePage'
|
||||
|
||||
const meta = {
|
||||
title: 'Pages/CreateLocalNodePage',
|
||||
component: CreateLocalNodePage,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof CreateLocalNodePage>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
args: {},
|
||||
}
|
76
src/pages/CreateLocalNodePage/CreateLocalNodePage.tsx
Normal file
76
src/pages/CreateLocalNodePage/CreateLocalNodePage.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import { useState } from 'react'
|
||||
import { Button as StatusButton, Text, Avatar, Checkbox } from '@status-im/components'
|
||||
import { Label, Separator, XStack, YStack } from 'tamagui'
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import NimbusLogo from '../../components/Logos/NimbusLogo'
|
||||
import TagContainer from '../../components/General/TagContainer'
|
||||
import Titles from '../../components/General/Titles'
|
||||
import NodeIcon from '../../components/Icons/NodeIcon'
|
||||
import LabelInputField from '../../components/General/LabelInputField'
|
||||
import ReactionIcon from '../../components/Icons/ReactionIcon'
|
||||
import ColorPicker from '../../components/General/ColorPicker'
|
||||
|
||||
const CreateLocalNodePage = () => {
|
||||
const [autoConnectChecked, setAutoConnectChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="/background-images/day-night-bg.png">
|
||||
<div className="connection-page">
|
||||
<XStack justifyContent={'space-between'}>
|
||||
<NimbusLogo />
|
||||
<TagContainer />
|
||||
</XStack>
|
||||
<article className="content">
|
||||
<Titles
|
||||
title="Create Local Node"
|
||||
subtitle="Configure your device to start Staking on Nimbus"
|
||||
/>
|
||||
<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>
|
||||
<YStack my={16}>
|
||||
<Text size={19} weight="semibold">
|
||||
Settings
|
||||
</Text>
|
||||
<XStack my={16} space={'$4'}>
|
||||
<Checkbox
|
||||
id="auto-connect"
|
||||
selected={autoConnectChecked}
|
||||
onCheckedChange={v => setAutoConnectChecked(v)}
|
||||
variant="outline"
|
||||
/>
|
||||
<Label htmlFor="auto-connect">
|
||||
<Text size={15} weight="regular">
|
||||
Auto Connect Paired Device
|
||||
</Text>
|
||||
</Label>
|
||||
</XStack>
|
||||
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} />
|
||||
</YStack>
|
||||
<StatusButton icon={<NodeIcon />}>Continue</StatusButton>
|
||||
</article>
|
||||
</div>
|
||||
</PageWrapperShadow>
|
||||
)
|
||||
}
|
||||
|
||||
export default CreateLocalNodePage
|
@ -1,16 +1,25 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Provider as ReduxProvider } from 'react-redux'
|
||||
import store from '../../redux/store'
|
||||
import DeviceHealthCheck from './DeviceHealthCheck'
|
||||
|
||||
const meta = {
|
||||
const meta: Meta = {
|
||||
title: 'Pages/DeviceHealthCheck',
|
||||
component: DeviceHealthCheck,
|
||||
decorators: [
|
||||
StoryObj => (
|
||||
<ReduxProvider store={store}>
|
||||
<StoryObj />
|
||||
</ReduxProvider>
|
||||
),
|
||||
],
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof DeviceHealthCheck>
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Page: Story = {
|
||||
type DeviceHealthCheckStory = StoryObj<typeof DeviceHealthCheck>
|
||||
|
||||
export const Page: DeviceHealthCheckStory = {
|
||||
args: {},
|
||||
}
|
||||
|
@ -9,8 +9,13 @@ import { Button, InformationBox } from '@status-im/components'
|
||||
import DeviceMemory from '../../components/Charts/DeviceMemoryHealth'
|
||||
import DeviceNetworkHealth from '../../components/Charts/DeviceNetworkHealth'
|
||||
import { CloseCircleIcon } from '@status-im/icons'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from '../../redux/store'
|
||||
|
||||
const DeviceHealthCheck = () => {
|
||||
|
||||
const deviceHealthState = useSelector((state: RootState) => state.deviceHealth)
|
||||
console.log(deviceHealthState)
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="/background-images/eye-background.png">
|
||||
<YStack
|
||||
@ -29,12 +34,21 @@ const DeviceHealthCheck = () => {
|
||||
isAdvancedSettings={true}
|
||||
/>
|
||||
<XStack space={'$4'}>
|
||||
<DeviceStorageHealth storage={44} maxStorage={30} />
|
||||
<DeviceCPULoad load={[12, 123, 4, 90]} />
|
||||
<DeviceStorageHealth
|
||||
storage={deviceHealthState.storage}
|
||||
maxStorage={deviceHealthState.maxMemory}
|
||||
/>
|
||||
<DeviceCPULoad load={deviceHealthState.cpuLoad} />
|
||||
</XStack>
|
||||
<XStack space={'$4'}>
|
||||
<DeviceMemory currentMemory={[25, 31, 5, 14, 20, 81]} maxMemory={38} />
|
||||
<DeviceNetworkHealth uploadRate={[1, 4, 23, 55]} downloadRate={[20, 3, 40, 56]} />
|
||||
<DeviceMemory
|
||||
currentMemory={deviceHealthState.memory}
|
||||
maxMemory={deviceHealthState.maxMemory}
|
||||
/>
|
||||
<DeviceNetworkHealth
|
||||
uploadRate={deviceHealthState.uploadRate}
|
||||
downloadRate={deviceHealthState.downloadRate}
|
||||
/>
|
||||
</XStack>
|
||||
<HealthInfoSection
|
||||
usedStorage={120}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import { Provider as ReduxProvider } from 'react-redux'
|
||||
import store from '../../redux/store'
|
||||
|
||||
import DeviceSyncStatus from './DeviceSyncStatus'
|
||||
|
||||
@ -11,9 +13,11 @@ const meta = {
|
||||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
Story => (
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<Story />
|
||||
</div>
|
||||
<ReduxProvider store={store}>
|
||||
<div style={{ height: '100%', width: '100%' }}>
|
||||
<Story />
|
||||
</div>
|
||||
</ReduxProvider>
|
||||
),
|
||||
],
|
||||
} satisfies Meta<typeof DeviceSyncStatus>
|
||||
|
@ -1,57 +1,50 @@
|
||||
import { Stack, YStack } from 'tamagui'
|
||||
|
||||
import { Button, PinnedMessage } from '@status-im/components'
|
||||
import { Button } from '@status-im/components'
|
||||
|
||||
import Titles from '../../components/General/Titles'
|
||||
import NimbusLogo from '../../components/Logos/NimbusLogo'
|
||||
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
|
||||
import SyncStatusCardConsensus from './SyncStatusCardConsensus'
|
||||
import SyncStatusCardExecution from './SyncStatusCardExecution'
|
||||
import { setPinnedMessage } from '../../redux/PinnedMessage/slice'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
const DeviceSyncStatus = () => {
|
||||
const dispatch = useDispatch()
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
setPinnedMessage({
|
||||
id: '123',
|
||||
text: 'You are currently syncing to the Nimbus Validator Client and Beacon node. This may take a while... Please stay put until you can access the Node Manager.',
|
||||
pinned: true,
|
||||
}),
|
||||
)
|
||||
}, [dispatch])
|
||||
return (
|
||||
<PageWrapperShadow rightImageSrc="/background-images/sync-status-background.png">
|
||||
<Stack>
|
||||
<PinnedMessage
|
||||
messages={[
|
||||
{
|
||||
id: '123',
|
||||
text: 'You are currently syncing to the Nimbus Validator Client and Beacon node. This may take a while... Please stay put until you can access the Node Manager.',
|
||||
reactions: { love: new Set(['userId1', 'userId2']) },
|
||||
},
|
||||
{
|
||||
id: '123',
|
||||
text: 'You are currently syncing to the Nimbus Validator Client and Beacon node. This may take a while... Please stay put until you can access the Node Manager.',
|
||||
reactions: { love: new Set(['userId3', 'userId4w']) },
|
||||
},
|
||||
]}
|
||||
<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."
|
||||
/>
|
||||
</Stack>
|
||||
<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 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>
|
||||
)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ const SyncStatusCardConsensus: React.FC<DeviceStorageHealthProps> = ({ synced, t
|
||||
<Shadow
|
||||
variant="$2"
|
||||
style={{
|
||||
width: '632px',
|
||||
width: '100%',
|
||||
borderRadius: '16px',
|
||||
borderTopLeftRadius: '0px',
|
||||
borderTopRightRadius: '0px',
|
||||
|
@ -35,7 +35,7 @@ const SyncStatusCardExecution: React.FC<DeviceStorageHealthProps> = ({ synced, t
|
||||
<Shadow
|
||||
variant="$2"
|
||||
style={{
|
||||
width: '632px',
|
||||
width: '100%',
|
||||
borderRadius: '16px',
|
||||
borderBottomRightRadius: '0px',
|
||||
borderBottomLeftRadius: '0px',
|
||||
|
@ -1,7 +1,4 @@
|
||||
|
||||
.landing-page header div img {
|
||||
margin-right: 0.5rem;
|
||||
.landing-page {
|
||||
height: 100%;
|
||||
}
|
||||
.landing-page .content .subtitle {
|
||||
margin-bottom: 3em;
|
||||
}
|
File diff suppressed because one or more lines are too long
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
|
34
src/redux/PinnedMessage/slice.tsx
Normal file
34
src/redux/PinnedMessage/slice.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
|
||||
export interface PinnedMessage {
|
||||
id: string
|
||||
text: string
|
||||
images?: Array<{
|
||||
url: string
|
||||
}>
|
||||
reply?: boolean
|
||||
pinned: boolean
|
||||
}
|
||||
|
||||
interface PinnedMessageState {
|
||||
pinnedMessage?: PinnedMessage
|
||||
}
|
||||
|
||||
const initialState: PinnedMessageState = {}
|
||||
|
||||
const pinnedMessageSlice = createSlice({
|
||||
name: 'pinnedMessage',
|
||||
initialState,
|
||||
reducers: {
|
||||
setPinnedMessage: (state, action: PayloadAction<PinnedMessage>) => {
|
||||
state.pinnedMessage = action.payload
|
||||
},
|
||||
clearPinnedMessage: state => {
|
||||
state.pinnedMessage = undefined
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setPinnedMessage, clearPinnedMessage } = pinnedMessageSlice.actions
|
||||
|
||||
export default pinnedMessageSlice.reducer
|
56
src/redux/deviceHealthCheck/slice.tsx
Normal file
56
src/redux/deviceHealthCheck/slice.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
|
||||
interface DeviceHealthState {
|
||||
storage: number
|
||||
maxStorage: number
|
||||
cpuLoad: number[]
|
||||
memory: number[]
|
||||
maxMemory: number
|
||||
uploadRate: number[]
|
||||
downloadRate: number[]
|
||||
}
|
||||
|
||||
const initialState: DeviceHealthState = {
|
||||
storage: 44,
|
||||
maxStorage: 100,
|
||||
cpuLoad: [12, 123, 4, 90],
|
||||
memory: [25, 31, 5, 14, 20, 81],
|
||||
maxMemory: 120,
|
||||
uploadRate: [1, 4, 25, 65],
|
||||
downloadRate: [20, 3, 50, 30],
|
||||
}
|
||||
|
||||
const deviceHealthSlice = createSlice({
|
||||
name: 'deviceHealth',
|
||||
initialState,
|
||||
reducers: {
|
||||
setStorage: (
|
||||
state: DeviceHealthState,
|
||||
action: PayloadAction<{ storage: number; maxStorage: number }>,
|
||||
) => {
|
||||
state.storage = action.payload.storage
|
||||
state.maxStorage = action.payload.maxStorage
|
||||
},
|
||||
setCpuLoad: (state: DeviceHealthState, action: PayloadAction<number[]>) => {
|
||||
state.cpuLoad = action.payload
|
||||
},
|
||||
setMemory: (
|
||||
state: DeviceHealthState,
|
||||
action: PayloadAction<{ memory: number[]; maxMemory: number }>,
|
||||
) => {
|
||||
state.memory = action.payload.memory
|
||||
state.maxMemory = action.payload.maxMemory
|
||||
},
|
||||
setNetworkHealth: (
|
||||
state: DeviceHealthState,
|
||||
action: PayloadAction<{ uploadRate: number[]; downloadRate: number[] }>,
|
||||
) => {
|
||||
state.uploadRate = action.payload.uploadRate
|
||||
state.downloadRate = action.payload.downloadRate
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setStorage, setCpuLoad, setMemory, setNetworkHealth } = deviceHealthSlice.actions
|
||||
|
||||
export default deviceHealthSlice.reducer
|
14
src/redux/store.tsx
Normal file
14
src/redux/store.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
import deviceHealthReducer from './deviceHealthCheck/slice'
|
||||
import pinnedMessageReducer from './PinnedMessage/slice'
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
deviceHealth: deviceHealthReducer,
|
||||
pinnedMessage: pinnedMessageReducer,
|
||||
},
|
||||
})
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>
|
||||
export type AppDispatch = typeof store.dispatch
|
||||
export default store
|
@ -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')}`
|
||||
}
|
256
yarn.lock
256
yarn.lock
@ -1590,6 +1590,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.9.2":
|
||||
version: 7.22.10
|
||||
resolution: "@babel/runtime@npm:7.22.10"
|
||||
dependencies:
|
||||
regenerator-runtime: ^0.14.0
|
||||
checksum: 524d41517e68953dbc73a4f3616b8475e5813f64e28ba89ff5fca2c044d535c2ea1a3f310df1e5bb06162e1f0b401b5c4af73fe6e2519ca2450d9d8c44cf268d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/template@npm:^7.0.0, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3":
|
||||
version: 7.22.5
|
||||
resolution: "@babel/template@npm:7.22.5"
|
||||
@ -2158,6 +2167,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@icons/material@npm:^0.2.4":
|
||||
version: 0.2.4
|
||||
resolution: "@icons/material@npm:0.2.4"
|
||||
peerDependencies:
|
||||
react: "*"
|
||||
checksum: 24baa360cb83f7e1a9e6784ac11185d57eb895b0efd3070ec915693378330f35ff9feb248f650b9649fa3e1045601286585dc05795a4c734d4849b33900351ee
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@isaacs/cliui@npm:^8.0.2":
|
||||
version: 8.0.2
|
||||
resolution: "@isaacs/cliui@npm:8.0.2"
|
||||
@ -4050,6 +4068,26 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@reduxjs/toolkit@npm:^1.9.5":
|
||||
version: 1.9.5
|
||||
resolution: "@reduxjs/toolkit@npm:1.9.5"
|
||||
dependencies:
|
||||
immer: ^9.0.21
|
||||
redux: ^4.2.1
|
||||
redux-thunk: ^2.4.2
|
||||
reselect: ^4.1.8
|
||||
peerDependencies:
|
||||
react: ^16.9.0 || ^17.0.0 || ^18
|
||||
react-redux: ^7.2.1 || ^8.0.2
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-redux:
|
||||
optional: true
|
||||
checksum: 54672c5593d05208af577e948a338f23128d3aa01ef056ab0d40bcfa14400cf6566be99e11715388f12c1d7655cdf7c5c6b63cb92eb0fecf996c454a46a3914c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@remix-run/router@npm:1.7.2":
|
||||
version: 1.7.2
|
||||
resolution: "@remix-run/router@npm:1.7.2"
|
||||
@ -6886,6 +6924,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/hoist-non-react-statics@npm:^3.3.1":
|
||||
version: 3.3.1
|
||||
resolution: "@types/hoist-non-react-statics@npm:3.3.1"
|
||||
dependencies:
|
||||
"@types/react": "*"
|
||||
hoist-non-react-statics: ^3.3.0
|
||||
checksum: 2c0778570d9a01d05afabc781b32163f28409bb98f7245c38d5eaf082416fdb73034003f5825eb5e21313044e8d2d9e1f3fe2831e345d3d1b1d20bcd12270719
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/http-errors@npm:*":
|
||||
version: 2.0.1
|
||||
resolution: "@types/http-errors@npm:2.0.1"
|
||||
@ -7033,6 +7081,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react-color@npm:^3.0.6":
|
||||
version: 3.0.6
|
||||
resolution: "@types/react-color@npm:3.0.6"
|
||||
dependencies:
|
||||
"@types/react": "*"
|
||||
"@types/reactcss": "*"
|
||||
checksum: 8cd881d6eb725190be942c1d71f7917d3dd1b418417740f64fa6c03ae3ba16cb91d07c4b3b348cf5bae20071c8ca5d4aaf514c9a5318077d5e50bd782a5e8da2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react-dom@npm:18":
|
||||
version: 18.2.7
|
||||
resolution: "@types/react-dom@npm:18.2.7"
|
||||
@ -7062,6 +7120,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/reactcss@npm:*":
|
||||
version: 1.2.6
|
||||
resolution: "@types/reactcss@npm:1.2.6"
|
||||
dependencies:
|
||||
"@types/react": "*"
|
||||
checksum: f4711d707a1af653178c8941080e989a945feb0c529d848fed36687ee5e8a462cda183383caadf8848497b5c03bec16e6cdf22fc70462913d8d706cabb597130
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/resolve@npm:1.20.2":
|
||||
version: 1.20.2
|
||||
resolution: "@types/resolve@npm:1.20.2"
|
||||
@ -7118,6 +7185,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/use-sync-external-store@npm:^0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "@types/use-sync-external-store@npm:0.0.3"
|
||||
checksum: 161ddb8eec5dbe7279ac971531217e9af6b99f7783213566d2b502e2e2378ea19cf5e5ea4595039d730aa79d3d35c6567d48599f69773a02ffcff1776ec2a44e
|
||||
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"
|
||||
@ -8648,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"
|
||||
@ -11059,6 +11147,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2":
|
||||
version: 3.3.2
|
||||
resolution: "hoist-non-react-statics@npm:3.3.2"
|
||||
dependencies:
|
||||
react-is: ^16.7.0
|
||||
checksum: b1538270429b13901ee586aa44f4cc3ecd8831c061d06cb8322e50ea17b3f5ce4d0e2e66394761e6c8e152cd8c34fb3b4b690116c6ce2bd45b18c746516cb9e8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"homedir-polyfill@npm:^1.0.0":
|
||||
version: 1.0.3
|
||||
resolution: "homedir-polyfill@npm:1.0.3"
|
||||
@ -11220,6 +11317,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"immer@npm:^9.0.21":
|
||||
version: 9.0.21
|
||||
resolution: "immer@npm:9.0.21"
|
||||
checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"import-fresh@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "import-fresh@npm:2.0.0"
|
||||
@ -12820,6 +12924,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash-es@npm:^4.17.15":
|
||||
version: 4.17.21
|
||||
resolution: "lodash-es@npm:4.17.21"
|
||||
checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.debounce@npm:^4.0.8":
|
||||
version: 4.0.8
|
||||
resolution: "lodash.debounce@npm:4.0.8"
|
||||
@ -12848,7 +12959,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash@npm:^4.17.15, lodash@npm:^4.17.21":
|
||||
"lodash@npm:^4.0.1, lodash@npm:^4.17.15, lodash@npm:^4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash@npm:4.17.21"
|
||||
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
|
||||
@ -13024,6 +13135,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"material-colors@npm:^1.2.1":
|
||||
version: 1.2.6
|
||||
resolution: "material-colors@npm:1.2.6"
|
||||
checksum: 72d005ccccb82bab68eef3cd757e802668634fc86976dedb9fc564ce994f2d3258273766b7efecb7404a0031969e2d72201a1b74169763f0a53c0dd8d649209f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mdast-util-definitions@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "mdast-util-definitions@npm:4.0.0"
|
||||
@ -13701,6 +13819,7 @@ __metadata:
|
||||
"@fsouza/prettierd": ^0.24.2
|
||||
"@nivo/line": ^0.83.0
|
||||
"@nivo/pie": ^0.83.0
|
||||
"@reduxjs/toolkit": ^1.9.5
|
||||
"@status-im/colors": "*"
|
||||
"@status-im/components": ^0.2.6
|
||||
"@storybook/addon-essentials": ^7.2.0
|
||||
@ -13717,7 +13836,9 @@ __metadata:
|
||||
"@tamagui/react-17-patch": 1.36.4
|
||||
"@tamagui/vite-plugin": 1.36.4
|
||||
"@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
|
||||
@ -13728,11 +13849,14 @@ __metadata:
|
||||
expo-modules-core: ^1.5.9
|
||||
prettier: ^3.0.1
|
||||
react: 18
|
||||
react-color: ^2.19.3
|
||||
react-dom: 18
|
||||
react-native: ^0.72.3
|
||||
react-native-svg: ^13.10.0
|
||||
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
|
||||
@ -14585,7 +14709,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prop-types@npm:*, prop-types@npm:^15.7.2":
|
||||
"prop-types@npm:*, prop-types@npm:^15.5.10, prop-types@npm:^15.7.2":
|
||||
version: 15.8.1
|
||||
resolution: "prop-types@npm:15.8.1"
|
||||
dependencies:
|
||||
@ -14729,6 +14853,23 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-color@npm:^2.19.3":
|
||||
version: 2.19.3
|
||||
resolution: "react-color@npm:2.19.3"
|
||||
dependencies:
|
||||
"@icons/material": ^0.2.4
|
||||
lodash: ^4.17.15
|
||||
lodash-es: ^4.17.15
|
||||
material-colors: ^1.2.1
|
||||
prop-types: ^15.5.10
|
||||
reactcss: ^1.2.0
|
||||
tinycolor2: ^1.4.1
|
||||
peerDependencies:
|
||||
react: "*"
|
||||
checksum: 40b49e1aa2ab27a099cc37a3fa2d5bb906b8def4dbe2d922c0e42365e386d82b03f9b06a2b29a44a51f1e114cef72e61c0ba0740581a128d951936ea4617429b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-colorful@npm:^5.1.2":
|
||||
version: 5.6.1
|
||||
resolution: "react-colorful@npm:5.6.1"
|
||||
@ -14825,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:
|
||||
@ -14848,7 +14989,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-is@npm:^16.13.1":
|
||||
"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
|
||||
version: 16.13.1
|
||||
resolution: "react-is@npm:16.13.1"
|
||||
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
|
||||
@ -14979,6 +15120,38 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-redux@npm:^8.1.2":
|
||||
version: 8.1.2
|
||||
resolution: "react-redux@npm:8.1.2"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.12.1
|
||||
"@types/hoist-non-react-statics": ^3.3.1
|
||||
"@types/use-sync-external-store": ^0.0.3
|
||||
hoist-non-react-statics: ^3.3.2
|
||||
react-is: ^18.0.0
|
||||
use-sync-external-store: ^1.0.0
|
||||
peerDependencies:
|
||||
"@types/react": ^16.8 || ^17.0 || ^18.0
|
||||
"@types/react-dom": ^16.8 || ^17.0 || ^18.0
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
react-native: ">=0.59"
|
||||
redux: ^4 || ^5.0.0-beta.0
|
||||
peerDependenciesMeta:
|
||||
"@types/react":
|
||||
optional: true
|
||||
"@types/react-dom":
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
redux:
|
||||
optional: true
|
||||
checksum: 4d5976b0f721e4148475871fcabce2fee875cc7f70f9a292f3370d63b38aa1dd474eb303c073c5555f3e69fc732f3bac05303def60304775deb28361e3f4b7cc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-refresh@npm:^0.14.0":
|
||||
version: 0.14.0
|
||||
resolution: "react-refresh@npm:0.14.0"
|
||||
@ -15109,6 +15282,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reactcss@npm:^1.2.0":
|
||||
version: 1.2.3
|
||||
resolution: "reactcss@npm:1.2.3"
|
||||
dependencies:
|
||||
lodash: ^4.0.1
|
||||
checksum: c53e386a0881f1477e1cff661f6a6ad4c662230941f3827862193ac30f9b75cdf7bc7b4c7e5ca543d3e4e80fee1a3e9fa0056c206b1c0423726c41773ab3fe45
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"read-pkg-up@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "read-pkg-up@npm:7.0.1"
|
||||
@ -15199,6 +15381,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux-thunk@npm:^2.4.2":
|
||||
version: 2.4.2
|
||||
resolution: "redux-thunk@npm:2.4.2"
|
||||
peerDependencies:
|
||||
redux: ^4
|
||||
checksum: c7f757f6c383b8ec26152c113e20087818d18ed3edf438aaad43539e9a6b77b427ade755c9595c4a163b6ad3063adf3497e5fe6a36c68884eb1f1cfb6f049a5c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux@npm:^4.2.1":
|
||||
version: 4.2.1
|
||||
resolution: "redux@npm:4.2.1"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.9.2
|
||||
checksum: f63b9060c3a1d930ae775252bb6e579b42415aee7a23c4114e21a0b4ba7ec12f0ec76936c00f546893f06e139819f0e2855e0d55ebfce34ca9c026241a6950dd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reforest@npm:^0.12.1":
|
||||
version: 0.12.3
|
||||
resolution: "reforest@npm:0.12.3"
|
||||
@ -15234,6 +15434,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"regenerator-runtime@npm:^0.14.0":
|
||||
version: 0.14.0
|
||||
resolution: "regenerator-runtime@npm:0.14.0"
|
||||
checksum: 1c977ad82a82a4412e4f639d65d22be376d3ebdd30da2c003eeafdaaacd03fc00c2320f18120007ee700900979284fc78a9f00da7fb593f6e6eeebc673fba9a3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"regenerator-transform@npm:^0.15.1":
|
||||
version: 0.15.2
|
||||
resolution: "regenerator-transform@npm:0.15.2"
|
||||
@ -15333,6 +15540,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reselect@npm:^4.1.8":
|
||||
version: 4.1.8
|
||||
resolution: "reselect@npm:4.1.8"
|
||||
checksum: a4ac87cedab198769a29be92bc221c32da76cfdad6911eda67b4d3e7136dca86208c3b210e31632eae31ebd2cded18596f0dd230d3ccc9e978df22f233b5583e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resolve-cwd@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "resolve-cwd@npm:3.0.0"
|
||||
@ -15972,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"
|
||||
@ -16391,6 +16632,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinycolor2@npm:^1.4.1":
|
||||
version: 1.6.0
|
||||
resolution: "tinycolor2@npm:1.6.0"
|
||||
checksum: 6df4d07fceeedc0a878d7bac47e2cd47c1ceeb1078340a9eb8a295bc0651e17c750f73d47b3028d829f30b85c15e0572c0fd4142083e4c21a30a597e47f47230
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tmpl@npm:1.0.5":
|
||||
version: 1.0.5
|
||||
resolution: "tmpl@npm:1.0.5"
|
||||
|
Loading…
x
Reference in New Issue
Block a user