diff --git a/public/background-images/eye-background.png b/public/background-images/eye-background.png index f0ac163d..5af468f1 100644 Binary files a/public/background-images/eye-background.png and b/public/background-images/eye-background.png differ diff --git a/src/App.tsx b/src/App.tsx index 0e64f693..177ea5ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,12 +4,17 @@ import { Provider as StatusProvider } from '@status-im/components' import './App.css' import config from '../tamagui.config' import LandingPage from './components/LandingPage' +import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck' const router = createBrowserRouter([ { path: '/', element: , }, + { + path: '/device-health-check', + element: , + }, ]) function App() { diff --git a/src/components/DeviceCPULoad.stories.tsx b/src/components/DeviceCPULoad.stories.tsx new file mode 100644 index 00000000..eec9b41c --- /dev/null +++ b/src/components/DeviceCPULoad.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import DeviceCPULoad from './DeviceCPULoad' + +const meta = { + title: 'Device Health/DeviceCPULoad', + component: DeviceCPULoad, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const GoodStats: Story = { + args: { + load: [12, 123, 4,32,40], + }, +} + +export const BadStats: Story = { + args: { + load: [12, 34, 81, 90, 91], + }, +} + +export const EmptyStats: Story = { + args: { + load: [], + }, +} diff --git a/src/components/DeviceCPULoad.tsx b/src/components/DeviceCPULoad.tsx index aec54cd2..81fa4c1b 100644 --- a/src/components/DeviceCPULoad.tsx +++ b/src/components/DeviceCPULoad.tsx @@ -1,7 +1,7 @@ import StandartLineChart from './StandardLineChart' import IconText from './IconText' import { Paragraph, Separator, XStack, YStack } from 'tamagui' -import { Shadow } from '@status-im/components' +import { Shadow, Text } from '@status-im/components' type DataPoint = { x: number @@ -34,7 +34,16 @@ const DeviceCPULoad: React.FC = ({ load }) => { const message = currentLoad < 80 ? 'Good' : 'Poor' return ( - + = ({ load }) => { - + {message} - {/* This is additional text */} + {message === 'Poor' && ( + + {((currentLoad / 80) * 100).toFixed(0)}% Utilization + + )} diff --git a/src/components/DeviceMemoryHealth.stories.tsx b/src/components/DeviceMemoryHealth.stories.tsx new file mode 100644 index 00000000..77660053 --- /dev/null +++ b/src/components/DeviceMemoryHealth.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import DeviceMemoryHealth from './DeviceMemoryHealth' + +const meta = { + title: 'Device Health/DeviceMemoryHealth', + component: DeviceMemoryHealth, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const GoodStats: Story = { + args: { + currentMemory: [25, 31, 5, 14, 20], + maxMemory: 64, + }, +} + +export const BadStats: Story = { + args: { + currentMemory: [25, 31, 5, 14, 80], + maxMemory: 64, + }, +} +export const EmptyStats: Story = { + args: { + currentMemory: [], + maxMemory:0, + }, +} diff --git a/src/components/DeviceMemoryHealth.tsx b/src/components/DeviceMemoryHealth.tsx index c9e3e916..4797642b 100644 --- a/src/components/DeviceMemoryHealth.tsx +++ b/src/components/DeviceMemoryHealth.tsx @@ -2,7 +2,7 @@ import StandartLineChart from './StandardLineChart' import IconText from './IconText' import { Paragraph, Separator, XStack, YStack } from 'tamagui' -import { Shadow as ShadowBox } from '@status-im/components' +import { Shadow as ShadowBox, Text } from '@status-im/components' type DataPoint = { x: number @@ -16,11 +16,11 @@ type ChartData = { maxValue?: number } -type DeviceMemoryProps = { +type DeviceMemoryHealthProps = { currentMemory: number[] - maxMemory?: number + maxMemory: number } -const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => { +const DeviceMemoryHealth = ({ currentMemory, maxMemory }: DeviceMemoryHealthProps) => { const chartData: ChartData[] = [ { id: 'cpu', @@ -35,16 +35,25 @@ const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => { const currentLoad = chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0 - const message = currentLoad < 80 ? 'Good' : 'Poor' + const message = currentLoad < maxMemory ? 'Good' : 'Poor' return ( - +
@@ -64,11 +73,15 @@ const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => { {message} - {/* This is additional text */} + {message === 'Poor' && ( + + {((currentLoad / maxMemory || 0) * 100).toFixed(0)}% Utilization + + )} ) } -export default DeviceMemory +export default DeviceMemoryHealth diff --git a/src/components/DeviceNetworkHealth.stories.tsx b/src/components/DeviceNetworkHealth.stories.tsx new file mode 100644 index 00000000..79def3fc --- /dev/null +++ b/src/components/DeviceNetworkHealth.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import DeviceNetworkHealth from './DeviceNetworkHealth' + +const meta = { + title: 'Device Health/DeviceNetworkHealth', + component: DeviceNetworkHealth, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const GoodStats: Story = { + args: { + uploadRate: [1, 4, 23, 61, 34], + downloadRate: [20, 3, 40, 56, 32], + }, +} + +export const BadStats: Story = { + args: { + uploadRate: [1, 4, 23, 55], + downloadRate: [20, 3, 40, 56, 80], + }, +} + +export const NoStats: Story = { + args: { + uploadRate: [], + downloadRate: [], + }, +} diff --git a/src/components/DeviceNetworkHealth.tsx b/src/components/DeviceNetworkHealth.tsx index da33dc33..38b36d02 100644 --- a/src/components/DeviceNetworkHealth.tsx +++ b/src/components/DeviceNetworkHealth.tsx @@ -1,7 +1,7 @@ import StandartLineChart from './StandardLineChart' import IconText from './IconText' import { Paragraph, Separator, XStack, YStack } from 'tamagui' -import { Shadow as ShadowBox } from '@status-im/components' +import { Shadow as ShadowBox, Text } from '@status-im/components' type DataPoint = { x: number @@ -40,10 +40,19 @@ const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthPr const currentLoad = chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0 - const message = currentLoad < 80 ? 'Good' : 'Poor' + const message = currentLoad > 60 ? 'Good' : 'Poor' return ( - + {message} - {/* This is additional text */} + {message === 'Poor' && ( + + {((currentLoad / 60) * 100).toFixed(0)}% Utilization + + )} diff --git a/src/components/DeviceStorageHealth.stories.tsx b/src/components/DeviceStorageHealth.stories.tsx new file mode 100644 index 00000000..0a27f60e --- /dev/null +++ b/src/components/DeviceStorageHealth.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import DeviceStorageHealth from './DeviceStorageHealth' + +const meta = { + title: 'Device Health/DeviceStorageHealth', + component: DeviceStorageHealth, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const GoodStats: Story = { + args: { + storage: 10, + maxStorage: 20, + }, +} + +export const BadStats: Story = { + args: { + storage: 20, + maxStorage: 20, + }, +} + +export const NoStats: Story = { + args: { + storage: 0, + maxStorage: 0, + }, +} diff --git a/src/components/DeviceStorageHealth.tsx b/src/components/DeviceStorageHealth.tsx index bad50d2e..71440ae8 100644 --- a/src/components/DeviceStorageHealth.tsx +++ b/src/components/DeviceStorageHealth.tsx @@ -1,22 +1,22 @@ import IconText from './IconText' import { Paragraph, Separator, XStack, YStack } from 'tamagui' import StandardGauge from './StandardGauge' -import { Shadow } from '@status-im/components' +import { Shadow, Text } from '@status-im/components' interface DeviceStorageHealthProps { storage: number maxStorage: number } const DeviceStorageHealth: React.FC = ({ storage, maxStorage }) => { const message = storage < maxStorage ? 'Good' : 'Poor' - const data = (storage: number, maxStorage: number) => { - const used = storage - const free = maxStorage - storage + const free = maxStorage - storage + const utilization = (storage / (maxStorage || 1)) * 100 + const data = (free: number) => { return [ { id: 'storage', label: 'Used', - value: used, + value: storage, color: '#E95460', }, { @@ -27,8 +27,18 @@ const DeviceStorageHealth: React.FC = ({ storage, maxS }, ] } + return ( - + = ({ storage, maxS height: '75px', }} > - +
@@ -58,10 +68,17 @@ const DeviceStorageHealth: React.FC = ({ storage, maxS
- + {message} - {/* This is additional text */} + {message === 'Poor' && ( + + {utilization.toFixed(0)}% Utilization + + )}
diff --git a/src/components/HealthInfoSection.tsx b/src/components/HealthInfoSection.tsx index 6144735e..87edee70 100644 --- a/src/components/HealthInfoSection.tsx +++ b/src/components/HealthInfoSection.tsx @@ -30,7 +30,7 @@ const HealthInfoSection = (props: HealthInfoSectionProps) => { const networkLatencyPercentage = networkLatency > 100 ? 100 : 0 return ( - + { +const IconText = ({ icon, children, weight }: IconTextProps) => { return ( { space={'$2'} > - + {children} diff --git a/src/components/LandingPage.tsx b/src/components/LandingPage.tsx index fdf14abe..dd793d44 100644 --- a/src/components/LandingPage.tsx +++ b/src/components/LandingPage.tsx @@ -5,7 +5,10 @@ import QuickStartBar from './QuickStartBar' function LandingPage() { return ( <> - } /> + } + rightImageSrc="src/assets/bg-img/landing-page-bg.png" + /> ) diff --git a/src/components/LayoutComponent.tsx b/src/components/LayoutComponent.tsx index ac29c35b..2b14c04b 100644 --- a/src/components/LayoutComponent.tsx +++ b/src/components/LayoutComponent.tsx @@ -4,6 +4,7 @@ import './layout.css' type LeftProps = { breadcrumbBar?: ReactNode content: ReactNode + rightImageSrc?: string } function LayoutComponent(props: LeftProps) { return ( @@ -12,16 +13,16 @@ function LayoutComponent(props: LeftProps) { {props.breadcrumbBar}
{props.content}
- + ) } -function LayoutRight() { +function LayoutRight({ rightImageSrc }: { rightImageSrc?: string }) { return (
- + background
) diff --git a/src/components/NimbusLogo.stories.tsx b/src/components/NimbusLogo.stories.tsx new file mode 100644 index 00000000..ca49f7c1 --- /dev/null +++ b/src/components/NimbusLogo.stories.tsx @@ -0,0 +1,14 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import NimbusLogo from './NimbusLogo' + +const meta = { + title: 'General/NimbusLogo', + component: NimbusLogo, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const ExampleNimbusLogo: Story = {} diff --git a/src/components/Titles.stories.tsx b/src/components/Titles.stories.tsx new file mode 100644 index 00000000..35037908 --- /dev/null +++ b/src/components/Titles.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import Titles from './Titles' + +const meta = { + title: 'General/Titles', + component: Titles, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const WelcomeTitles: Story = { + args: { + title: 'Welcome, John. This is your complete access to a truly decentralized Web 3.0', + subtitle: + 'Status Nodes allows you to finally take control and ownership of the services you wish to run in a completely trustless and decentralized manner.', + isAdvancedSettings: false, + }, +} + +export const DeviceHealthCheckTitles: Story = { + args: { + title: 'Device Health Check', + subtitle: 'Configure your device to start Staking on Nimbus', + isAdvancedSettings: true, + }, +} diff --git a/src/components/Titles.tsx b/src/components/Titles.tsx index 609e66bf..29aaae53 100644 --- a/src/components/Titles.tsx +++ b/src/components/Titles.tsx @@ -1,25 +1,24 @@ import { XStack, YStack } from 'tamagui' import { Button, Text } from '@status-im/components' import Icon from './Icon' +import Title from './Title' type TitlesProps = { title: string subtitle: string - button?: boolean + isAdvancedSettings?: boolean } -const Titles = ({ title, subtitle, button }: TitlesProps) => { +const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => { return ( - - - - {title} - - {button ? ( - - ) : null} + )} {subtitle} diff --git a/src/pages/DeviceHealthCheck/DeviceHealthCheck.stories.tsx b/src/pages/DeviceHealthCheck/DeviceHealthCheck.stories.tsx new file mode 100644 index 00000000..30828e76 --- /dev/null +++ b/src/pages/DeviceHealthCheck/DeviceHealthCheck.stories.tsx @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import DeviceHealthCheck from './DeviceHealthCheck' + +const meta = { + title: 'Pages/DeviceHealthCheck', + component: DeviceHealthCheck, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Page: Story = { + args: {}, +} diff --git a/src/pages/DeviceHealthCheck/DeviceHealthCheck.tsx b/src/pages/DeviceHealthCheck/DeviceHealthCheck.tsx new file mode 100644 index 00000000..785e5d0f --- /dev/null +++ b/src/pages/DeviceHealthCheck/DeviceHealthCheck.tsx @@ -0,0 +1,68 @@ +import { Stack, XStack, YStack } from 'tamagui' +import LayoutComponent from '../../components/LayoutComponent' +import NimbusLogo from '../../components/NimbusLogo' +import Titles from '../../components/Titles' +import DeviceStorageHealth from '../../components/DeviceStorageHealth' +import DeviceCPULoad from '../../components/DeviceCPULoad' +import HealthInfoSection from '../../components/HealthInfoSection' +import { Button, InformationBox } from '@status-im/components' +import Icon from '../../components/Icon' +import DeviceMemory from '../../components/DeviceMemoryHealth' +import DeviceNetworkHealth from '../../components/DeviceNetworkHealth' + +const DeviceHealthCheck = () => { + return ( + } + rightImageSrc="/background-images/eye-background.png" + /> + ) +} + +export default DeviceHealthCheck + +const DeviceHealthCheckContent = () => { + return ( +
+ + + + + + + + + + + + + } + message="The information provided in the Nodes Health Check is meant to utilized as a guide to guage the readiness of your device, however please do your own due diligence prior to commiting any funds. Read our Health Check Disclosure for more information." + /> + + + + +
+ ) +}