Merge branch 'main' into rd.use-icons-from-status

This commit is contained in:
RadoslavDimchev 2023-08-21 14:30:44 +03:00
commit 2317f7ebb4
51 changed files with 1178 additions and 322 deletions

View File

@ -10,6 +10,7 @@ const config: StorybookConfig = {
'@storybook/addon-interactions', '@storybook/addon-interactions',
'storybook-addon-designs', 'storybook-addon-designs',
'storybook-dark-mode', 'storybook-dark-mode',
'storybook-addon-react-router-v6',
], ],
docs: { docs: {

View File

@ -19,6 +19,7 @@
"dependencies": { "dependencies": {
"@nivo/line": "^0.83.0", "@nivo/line": "^0.83.0",
"@nivo/pie": "^0.83.0", "@nivo/pie": "^0.83.0",
"@reduxjs/toolkit": "^1.9.5",
"@status-im/colors": "*", "@status-im/colors": "*",
"@status-im/components": "^0.2.6", "@status-im/components": "^0.2.6",
"@tamagui/config": "1.36.4", "@tamagui/config": "1.36.4",
@ -28,9 +29,11 @@
"@types/react-dom": "18", "@types/react-dom": "18",
"expo-modules-core": "^1.5.9", "expo-modules-core": "^1.5.9",
"react": "18", "react": "18",
"react-color": "^2.19.3",
"react-dom": "18", "react-dom": "18",
"react-native": "^0.72.3", "react-native": "^0.72.3",
"react-native-svg": "^13.10.0", "react-native-svg": "^13.10.0",
"react-redux": "^8.1.2",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"tamagui": "1.36.4" "tamagui": "1.36.4"
}, },
@ -46,6 +49,8 @@
"@storybook/react-vite": "^7.2.0", "@storybook/react-vite": "^7.2.0",
"@storybook/test-runner": "^0.12.0", "@storybook/test-runner": "^0.12.0",
"@storybook/testing-library": "^0.2.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/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0", "@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3", "@vitejs/plugin-react": "^4.0.3",
@ -55,6 +60,7 @@
"eslint-plugin-storybook": "^0.6.13", "eslint-plugin-storybook": "^0.6.13",
"prettier": "^3.0.1", "prettier": "^3.0.1",
"storybook": "^7.2.0", "storybook": "^7.2.0",
"storybook-addon-react-router-v6": "^2.0.5",
"typescript": "^5.0.2", "typescript": "^5.0.2",
"vite": "^4.4.9" "vite": "^4.4.9"
}, },

10
public/icons/block.svg Normal file
View 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

View 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

View 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
View 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

View File

@ -1,30 +1,3 @@
#root { #root {
width: 100%; 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;
} }

View File

@ -7,6 +7,11 @@ import LandingPage from './pages/LandingPage/LandingPage'
import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck' import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck'
import ConnectDevicePage from './pages/ConnectDevicePage/ConnectDevicePage' import ConnectDevicePage from './pages/ConnectDevicePage/ConnectDevicePage'
import DeviceSyncStatus from './pages/DeviceSyncStatus/DeviceSyncStatus' 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([ const router = createBrowserRouter([
{ {
@ -20,21 +25,27 @@ const router = createBrowserRouter([
{ {
path: '/connect-device', path: '/connect-device',
element: <ConnectDevicePage />, element: <ConnectDevicePage />,
}, },
{ {
path: '/device-sync-status', path: '/device-sync-status',
element: <DeviceSyncStatus />, element: <DeviceSyncStatus />,
} },
{
path: '/pair-device',
element: <PairDevice />,
},
{ path: '/create-local-node', element: <CreateLocalNodePage /> },
]) ])
function App() { function App() {
return ( return (
<TamaguiProvider config={config}> <ReduxProvider store={store}>
<StatusProvider> <TamaguiProvider config={config}>
<RouterProvider router={router} /> <StatusProvider>
</StatusProvider> <PinnedNotification />
</TamaguiProvider> <RouterProvider router={router} />
</StatusProvider>
</TamaguiProvider>
</ReduxProvider>
) )
} }

View File

@ -59,7 +59,7 @@ const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthPr
justifyContent="space-between" justifyContent="space-between"
style={{ style={{
padding: '8px 16px', padding: '8px 16px',
position: 'relative', // Make XStack a positioning context position: 'relative',
}} }}
> >
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}> <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>

View File

@ -4,19 +4,14 @@
padding: 1rem 2rem; padding: 1rem 2rem;
margin: 0.5rem; margin: 0.5rem;
} }
.breadcrumb-bar-ul {
list-style-type: none;
display: flex;
padding: 0;
margin: 0;
}
.breadcrumb-bar-li { .breadcrumb-bar-li {
padding: 0 1em;
color: #647084; color: #647084;
font-size: 15px;
font-weight: 500; font-weight: 500;
position: relative; position: relative;
} }
.breadcrumb-bar-li:last-child {
color: #09101C;
}
.breadcrumb-bar-li::after { .breadcrumb-bar-li::after {
display: inline-block; display: inline-block;
content: url("/icons/chevron.svg"); content: url("/icons/chevron.svg");
@ -26,10 +21,7 @@
left: 100%; left: 100%;
transform: translateX(-50%); transform: translateX(-50%);
} }
.breadcrumb-bar-li:last-child {
color: #09101C;
}
.breadcrumb-bar-li:last-child::after { .breadcrumb-bar-li:last-child::after {
display: none; display: none;
} }

View File

@ -1,4 +1,4 @@
import './breadcrumbbar.css' import './BreadcrumbBar.css'
type BreadcrumbBarProps = { type BreadcrumbBarProps = {
breadcrumbList: string[] breadcrumbList: string[]

View 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: {},
}

View 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

View File

@ -0,0 +1,6 @@
.input-container {
background-color: #fff;
border-radius: 12px;
margin-top: 8px;
width: 100%;
}

View File

@ -1,5 +1,6 @@
import { Input as StatusInput, Text } from '@status-im/components' import { Input as StatusInput, Text } from '@status-im/components'
import { Label } from 'tamagui' import { Label } from 'tamagui'
import './LabelInputField.css'
type LabelInputProps = { type LabelInputProps = {
labelText: string labelText: string
@ -12,7 +13,9 @@ function LabelInputField({ labelText, placeholderText }: LabelInputProps) {
<Text size={13} weight="regular" color={'#647084'}> <Text size={13} weight="regular" color={'#647084'}>
{labelText} {labelText}
</Text> </Text>
<StatusInput placeholder={placeholderText} width={'100%'} /> <div className="input-container">
<StatusInput placeholder={placeholderText} width={'100%'} />
</div>
</Label> </Label>
) )
} }

View 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

View File

@ -14,22 +14,12 @@
} }
.quick-start-bar > div { .quick-start-bar > div {
width: 100%; width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 24px; border-radius: 24px;
background: rgba(100, 112, 132, 0.05); background: rgba(100, 112, 132, 0.05);
margin-left: 1rem; 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 { .quick-start-bar ul li {
padding: 0 1rem;
color: #0D1625; color: #0D1625;
font-size: 13px; font-size: 13px;
} }

View File

@ -38,7 +38,6 @@ const QuickStartBar = () => {
<li>Nodes Community</li> <li>Nodes Community</li>
<li>Documentation</li> <li>Documentation</li>
</ul> </ul>
<button className="inversed">Quick Start</button>
</div> </div>
</nav> </nav>
) )

View File

@ -0,0 +1,4 @@
.tag-container div:nth-child(1) {
background:transparent;
}

View 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

View File

@ -7,7 +7,7 @@ type TitleProps = {
const Title = ({ color, children }: TitleProps) => { const Title = ({ color, children }: TitleProps) => {
return ( return (
<Text size={27} weight={'medium'} color={color}> <Text size={27} weight={'semibold'} color={color}>
{children} {children}
</Text> </Text>
) )

View File

@ -11,7 +11,7 @@ type TitlesProps = {
const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => { const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => {
return ( return (
<YStack style={{ width: '100%' }}> <YStack style={{ width: '100%', margin: '0 0 1em' }}>
<XStack style={{ justifyContent: 'space-between', alignItems: 'center' }}> <XStack style={{ justifyContent: 'space-between', alignItems: 'center' }}>
<Title color={'#09101C'}>{title}</Title> <Title color={'#09101C'}>{title}</Title>
{isAdvancedSettings && ( {isAdvancedSettings && (

View 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

View File

@ -0,0 +1,5 @@
.nimbus-logomark{
width: auto;
height: 30%;
}

View File

@ -1,5 +1,6 @@
import { XStack } from 'tamagui' import { XStack } from 'tamagui'
import BetaTag from './BetaTag' import BetaTag from './BetaTag'
import './NimbusLogo.css'
const NimbusLogo = () => { const NimbusLogo = () => {
return ( return (

View File

@ -25,8 +25,8 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: end; justify-content: end;
height: 100%; height: 100%;
margin: 0 auto; padding: 70px 0 0;
} }
.container-inner { .container-inner {
max-width: 70%; max-width: 70%;
@ -34,88 +34,42 @@
display: flex; display: flex;
flex-direction: column; 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 { .content {
flex-grow: 1; flex-grow: 1;
} }
.content .title {
font-size: 27px; /* LAYOUT RIGHT ELEMENT WITH IMAGE TAKING UP THE WHOLE HIGHT OF THE VIEWPORT */
font-weight: 600; .layout-right {
margin-bottom: 0.25em; flex: 0 0 45%;
} max-width: 45%;
.content .subtitle { z-index: 0;
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;
} }
.image-container {
/* LAYOUT RIGHT ELEMENT WITH IMAGE TAKING UP THE WHOLE HIGHT OF THE VIEWPORT */ height: 100%;
.layout-right { position: relative;
flex: 0 0 45%; overflow: hidden;
max-width: 45%; }
z-index: 0; .image-container::before {
} display: block;
content: "";
.image-container { padding-bottom: 100%;
height: 100%; }
position: relative; .image-container::after {
overflow: hidden; display: block;
} content: "";
.image-container::before { position: absolute;
display: block; top: 0;
content: ""; left: -1%;
padding-bottom: 100%; width: 50%;
} height: 100%;
.image-container::after { background: linear-gradient(to right, rgba(255, 255, 255, 1) 20%, rgba(255, 255, 255, 0.0));
display: block; }
content: ""; .image-container img {
position: absolute; position: absolute;
top: 0; top: 50%;
left: -1%; left: 50%;
width: 50%; transform: translate(-50%, -50%);
height: 100%; height: 140%;
background: linear-gradient(to right, rgba(255, 255, 255, 1) 20%, rgba(255, 255, 255, 0.0)); width: auto;
} }
.image-container img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 140%;
width: auto;
}

View File

@ -13,69 +13,46 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
} }
#storybook-root { #storybook-root {
width: 100%; width: 100%;
} }
body { body {
margin: 0; margin: 0;
display: flex; display: flex;
min-width: 320px; min-width: 320px;
min-height: 100vh; min-height: 100vh;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
line-height: 1.2; line-height: 1.2;
font-weight: 700; font-weight: 700;
} }
h1 {
font-size: 3.2em;
}
a { a {
font-weight: 500; font-weight: 500;
text-decoration: inherit; text-decoration: inherit;
cursor: pointer; cursor: pointer;
} }
a:hover {
color: #535bf2;
}
button { button {
border-radius: 12px; border-radius: 12px;
border: 1px solid transparent; border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 15px; font-size: 15px;
font-weight: 500; font-weight: 500;
font-family: inherit; 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; cursor: pointer;
transition: border-color 0.25s; transition: border-color 0.25s;
} }
button:hover {
border-color: #646cff;
}
button:focus, button:focus,
button:focus-visible { button:focus-visible {
outline: 4px auto -webkit-focus-ring-color; outline: 4px auto -webkit-focus-ring-color;
} }
.nimbus-logomark{ ul{
width: auto; list-style-type: none;
height: 30%; padding: 0;
margin: 0;
display: flex;
}
ul li {
padding: 0 1rem;
font-size: 15px;
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
:root { :root {

View 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: {},
}

View 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

View File

@ -1,16 +1,25 @@
import type { Meta, StoryObj } from '@storybook/react' import type { Meta, StoryObj } from '@storybook/react'
import { Provider as ReduxProvider } from 'react-redux'
import store from '../../redux/store'
import DeviceHealthCheck from './DeviceHealthCheck' import DeviceHealthCheck from './DeviceHealthCheck'
const meta = { const meta: Meta = {
title: 'Pages/DeviceHealthCheck', title: 'Pages/DeviceHealthCheck',
component: DeviceHealthCheck, component: DeviceHealthCheck,
decorators: [
StoryObj => (
<ReduxProvider store={store}>
<StoryObj />
</ReduxProvider>
),
],
tags: ['autodocs'], tags: ['autodocs'],
} satisfies Meta<typeof DeviceHealthCheck> }
export default meta export default meta
type Story = StoryObj<typeof meta>
export const Page: Story = { type DeviceHealthCheckStory = StoryObj<typeof DeviceHealthCheck>
export const Page: DeviceHealthCheckStory = {
args: {}, args: {},
} }

View File

@ -9,8 +9,13 @@ import { Button, InformationBox } from '@status-im/components'
import DeviceMemory from '../../components/Charts/DeviceMemoryHealth' import DeviceMemory from '../../components/Charts/DeviceMemoryHealth'
import DeviceNetworkHealth from '../../components/Charts/DeviceNetworkHealth' import DeviceNetworkHealth from '../../components/Charts/DeviceNetworkHealth'
import { CloseCircleIcon } from '@status-im/icons' import { CloseCircleIcon } from '@status-im/icons'
import { useSelector } from 'react-redux'
import { RootState } from '../../redux/store'
const DeviceHealthCheck = () => { const DeviceHealthCheck = () => {
const deviceHealthState = useSelector((state: RootState) => state.deviceHealth)
console.log(deviceHealthState)
return ( return (
<PageWrapperShadow rightImageSrc="/background-images/eye-background.png"> <PageWrapperShadow rightImageSrc="/background-images/eye-background.png">
<YStack <YStack
@ -29,12 +34,21 @@ const DeviceHealthCheck = () => {
isAdvancedSettings={true} isAdvancedSettings={true}
/> />
<XStack space={'$4'}> <XStack space={'$4'}>
<DeviceStorageHealth storage={44} maxStorage={30} /> <DeviceStorageHealth
<DeviceCPULoad load={[12, 123, 4, 90]} /> storage={deviceHealthState.storage}
maxStorage={deviceHealthState.maxMemory}
/>
<DeviceCPULoad load={deviceHealthState.cpuLoad} />
</XStack> </XStack>
<XStack space={'$4'}> <XStack space={'$4'}>
<DeviceMemory currentMemory={[25, 31, 5, 14, 20, 81]} maxMemory={38} /> <DeviceMemory
<DeviceNetworkHealth uploadRate={[1, 4, 23, 55]} downloadRate={[20, 3, 40, 56]} /> currentMemory={deviceHealthState.memory}
maxMemory={deviceHealthState.maxMemory}
/>
<DeviceNetworkHealth
uploadRate={deviceHealthState.uploadRate}
downloadRate={deviceHealthState.downloadRate}
/>
</XStack> </XStack>
<HealthInfoSection <HealthInfoSection
usedStorage={120} usedStorage={120}

View File

@ -1,4 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react' import type { Meta, StoryObj } from '@storybook/react'
import { Provider as ReduxProvider } from 'react-redux'
import store from '../../redux/store'
import DeviceSyncStatus from './DeviceSyncStatus' import DeviceSyncStatus from './DeviceSyncStatus'
@ -11,9 +13,11 @@ const meta = {
tags: ['autodocs'], tags: ['autodocs'],
decorators: [ decorators: [
Story => ( Story => (
<div style={{ height: '100%', width: '100%' }}> <ReduxProvider store={store}>
<Story /> <div style={{ height: '100%', width: '100%' }}>
</div> <Story />
</div>
</ReduxProvider>
), ),
], ],
} satisfies Meta<typeof DeviceSyncStatus> } satisfies Meta<typeof DeviceSyncStatus>

View File

@ -1,57 +1,50 @@
import { Stack, YStack } from 'tamagui' 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 Titles from '../../components/General/Titles'
import NimbusLogo from '../../components/Logos/NimbusLogo' import NimbusLogo from '../../components/Logos/NimbusLogo'
import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow' import PageWrapperShadow from '../../components/PageWrappers/PageWrapperShadow'
import SyncStatusCardConsensus from './SyncStatusCardConsensus' import SyncStatusCardConsensus from './SyncStatusCardConsensus'
import SyncStatusCardExecution from './SyncStatusCardExecution' import SyncStatusCardExecution from './SyncStatusCardExecution'
import { setPinnedMessage } from '../../redux/PinnedMessage/slice'
import { useDispatch } from 'react-redux'
import { useEffect } from 'react'
const DeviceSyncStatus = () => { 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 ( return (
<PageWrapperShadow rightImageSrc="/background-images/sync-status-background.png"> <PageWrapperShadow rightImageSrc="/background-images/sync-status-background.png">
<Stack> <YStack
<PinnedMessage space={'$4'}
messages={[ style={{
{ justifyContent: 'end',
id: '123', alignItems: 'start',
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.', maxWidth: '100%',
reactions: { love: new Set(['userId1', 'userId2']) }, }}
}, >
{ <NimbusLogo />
id: '123', <Titles
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.', title="Sync Status"
reactions: { love: new Set(['userId3', 'userId4w']) }, subtitle="Monitor your Validator Client and Beacon Node syncing progression."
},
]}
/> />
</Stack> <YStack style={{ width: '100%' }}>
<div className="container-inner landing-page"> <SyncStatusCardExecution synced={132432} total={200000} />
<YStack <SyncStatusCardConsensus synced={149500} total={160000} />
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> </YStack>
</div> <Stack style={{ marginTop: '1rem' }}>
<Button>Continue</Button>
</Stack>
</YStack>
</PageWrapperShadow> </PageWrapperShadow>
) )
} }

View File

@ -36,7 +36,7 @@ const SyncStatusCardConsensus: React.FC<DeviceStorageHealthProps> = ({ synced, t
<Shadow <Shadow
variant="$2" variant="$2"
style={{ style={{
width: '632px', width: '100%',
borderRadius: '16px', borderRadius: '16px',
borderTopLeftRadius: '0px', borderTopLeftRadius: '0px',
borderTopRightRadius: '0px', borderTopRightRadius: '0px',

View File

@ -35,7 +35,7 @@ const SyncStatusCardExecution: React.FC<DeviceStorageHealthProps> = ({ synced, t
<Shadow <Shadow
variant="$2" variant="$2"
style={{ style={{
width: '632px', width: '100%',
borderRadius: '16px', borderRadius: '16px',
borderBottomRightRadius: '0px', borderBottomRightRadius: '0px',
borderBottomLeftRadius: '0px', borderBottomLeftRadius: '0px',

View File

@ -1,7 +1,4 @@
.landing-page header div img { .landing-page {
margin-right: 0.5rem; height: 100%;
} }
.landing-page .content .subtitle {
margin-bottom: 3em;
}

File diff suppressed because one or more lines are too long

View 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>
)
}

View 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,
},
}

View 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

View 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: {},
}

View 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

View 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: {},
}

View 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

View 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,
},
}

View 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

View 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

View 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
View 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

View File

@ -16,3 +16,9 @@
export function assertUnreachable(value: never): never { export function assertUnreachable(value: never): never {
throw new Error(`Unreachable case: ${value}`); 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
View File

@ -1590,6 +1590,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@babel/template@npm:^7.0.0, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3":
version: 7.22.5 version: 7.22.5
resolution: "@babel/template@npm:7.22.5" resolution: "@babel/template@npm:7.22.5"
@ -2158,6 +2167,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@isaacs/cliui@npm:^8.0.2":
version: 8.0.2 version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2" resolution: "@isaacs/cliui@npm:8.0.2"
@ -4050,6 +4068,26 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@remix-run/router@npm:1.7.2":
version: 1.7.2 version: 1.7.2
resolution: "@remix-run/router@npm:1.7.2" resolution: "@remix-run/router@npm:1.7.2"
@ -6886,6 +6924,16 @@ __metadata:
languageName: node languageName: node
linkType: hard 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:*": "@types/http-errors@npm:*":
version: 2.0.1 version: 2.0.1
resolution: "@types/http-errors@npm:2.0.1" resolution: "@types/http-errors@npm:2.0.1"
@ -7033,6 +7081,16 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@types/react-dom@npm:18":
version: 18.2.7 version: 18.2.7
resolution: "@types/react-dom@npm:18.2.7" resolution: "@types/react-dom@npm:18.2.7"
@ -7062,6 +7120,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@types/resolve@npm:1.20.2":
version: 1.20.2 version: 1.20.2
resolution: "@types/resolve@npm:1.20.2" resolution: "@types/resolve@npm:1.20.2"
@ -7118,6 +7185,20 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@types/wait-on@npm:^5.2.0":
version: 5.3.1 version: 5.3.1
resolution: "@types/wait-on@npm:5.3.1" resolution: "@types/wait-on@npm:5.3.1"
@ -8648,6 +8729,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "compressible@npm:~2.0.16":
version: 2.0.18 version: 2.0.18
resolution: "compressible@npm:2.0.18" resolution: "compressible@npm:2.0.18"
@ -11059,6 +11147,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "homedir-polyfill@npm:^1.0.0":
version: 1.0.3 version: 1.0.3
resolution: "homedir-polyfill@npm:1.0.3" resolution: "homedir-polyfill@npm:1.0.3"
@ -11220,6 +11317,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "import-fresh@npm:^2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "import-fresh@npm:2.0.0" resolution: "import-fresh@npm:2.0.0"
@ -12820,6 +12924,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "lodash.debounce@npm:^4.0.8":
version: 4.0.8 version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8" resolution: "lodash.debounce@npm:4.0.8"
@ -12848,7 +12959,7 @@ __metadata:
languageName: node languageName: node
linkType: hard 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 version: 4.17.21
resolution: "lodash@npm:4.17.21" resolution: "lodash@npm:4.17.21"
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
@ -13024,6 +13135,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "mdast-util-definitions@npm:^4.0.0":
version: 4.0.0 version: 4.0.0
resolution: "mdast-util-definitions@npm:4.0.0" resolution: "mdast-util-definitions@npm:4.0.0"
@ -13701,6 +13819,7 @@ __metadata:
"@fsouza/prettierd": ^0.24.2 "@fsouza/prettierd": ^0.24.2
"@nivo/line": ^0.83.0 "@nivo/line": ^0.83.0
"@nivo/pie": ^0.83.0 "@nivo/pie": ^0.83.0
"@reduxjs/toolkit": ^1.9.5
"@status-im/colors": "*" "@status-im/colors": "*"
"@status-im/components": ^0.2.6 "@status-im/components": ^0.2.6
"@storybook/addon-essentials": ^7.2.0 "@storybook/addon-essentials": ^7.2.0
@ -13717,7 +13836,9 @@ __metadata:
"@tamagui/react-17-patch": 1.36.4 "@tamagui/react-17-patch": 1.36.4
"@tamagui/vite-plugin": 1.36.4 "@tamagui/vite-plugin": 1.36.4
"@types/react": 18 "@types/react": 18
"@types/react-color": ^3.0.6
"@types/react-dom": 18 "@types/react-dom": 18
"@types/uuid": ^9.0.2
"@typescript-eslint/eslint-plugin": ^6.0.0 "@typescript-eslint/eslint-plugin": ^6.0.0
"@typescript-eslint/parser": ^6.0.0 "@typescript-eslint/parser": ^6.0.0
"@vitejs/plugin-react": ^4.0.3 "@vitejs/plugin-react": ^4.0.3
@ -13728,11 +13849,14 @@ __metadata:
expo-modules-core: ^1.5.9 expo-modules-core: ^1.5.9
prettier: ^3.0.1 prettier: ^3.0.1
react: 18 react: 18
react-color: ^2.19.3
react-dom: 18 react-dom: 18
react-native: ^0.72.3 react-native: ^0.72.3
react-native-svg: ^13.10.0 react-native-svg: ^13.10.0
react-redux: ^8.1.2
react-router-dom: ^6.14.2 react-router-dom: ^6.14.2
storybook: ^7.2.0 storybook: ^7.2.0
storybook-addon-react-router-v6: ^2.0.5
tamagui: 1.36.4 tamagui: 1.36.4
typescript: ^5.0.2 typescript: ^5.0.2
vite: ^4.4.9 vite: ^4.4.9
@ -14585,7 +14709,7 @@ __metadata:
languageName: node languageName: node
linkType: hard 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 version: 15.8.1
resolution: "prop-types@npm:15.8.1" resolution: "prop-types@npm:15.8.1"
dependencies: dependencies:
@ -14729,6 +14853,23 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "react-colorful@npm:^5.1.2":
version: 5.6.1 version: 5.6.1
resolution: "react-colorful@npm:5.6.1" resolution: "react-colorful@npm:5.6.1"
@ -14825,7 +14966,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-inspector@npm:^6.0.0": "react-inspector@npm:6.0.2, react-inspector@npm:^6.0.0":
version: 6.0.2 version: 6.0.2
resolution: "react-inspector@npm:6.0.2" resolution: "react-inspector@npm:6.0.2"
peerDependencies: peerDependencies:
@ -14848,7 +14989,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-is@npm:^16.13.1": "react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1 version: 16.13.1
resolution: "react-is@npm:16.13.1" resolution: "react-is@npm:16.13.1"
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
@ -14979,6 +15120,38 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "react-refresh@npm:^0.14.0":
version: 0.14.0 version: 0.14.0
resolution: "react-refresh@npm:0.14.0" resolution: "react-refresh@npm:0.14.0"
@ -15109,6 +15282,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "read-pkg-up@npm:^7.0.1":
version: 7.0.1 version: 7.0.1
resolution: "read-pkg-up@npm:7.0.1" resolution: "read-pkg-up@npm:7.0.1"
@ -15199,6 +15381,24 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "reforest@npm:^0.12.1":
version: 0.12.3 version: 0.12.3
resolution: "reforest@npm:0.12.3" resolution: "reforest@npm:0.12.3"
@ -15234,6 +15434,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "regenerator-transform@npm:^0.15.1":
version: 0.15.2 version: 0.15.2
resolution: "regenerator-transform@npm:0.15.2" resolution: "regenerator-transform@npm:0.15.2"
@ -15333,6 +15540,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "resolve-cwd@npm:^3.0.0":
version: 3.0.0 version: 3.0.0
resolution: "resolve-cwd@npm:3.0.0" resolution: "resolve-cwd@npm:3.0.0"
@ -15972,6 +16186,33 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "storybook@npm:^7.2.0":
version: 7.2.1 version: 7.2.1
resolution: "storybook@npm:7.2.1" resolution: "storybook@npm:7.2.1"
@ -16391,6 +16632,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "tmpl@npm:1.0.5":
version: 1.0.5 version: 1.0.5
resolution: "tmpl@npm:1.0.5" resolution: "tmpl@npm:1.0.5"