mirror of
https://github.com/status-im/nimbus-gui.git
synced 2025-02-03 23:24:20 +00:00
Merge pull request #43 from status-im/rd-hn-.create-DeviceHealthPage
feat: create device health page
This commit is contained in:
commit
11c18a316f
Binary file not shown.
Before Width: | Height: | Size: 514 KiB After Width: | Height: | Size: 1.3 MiB |
@ -4,12 +4,17 @@ import { Provider as StatusProvider } from '@status-im/components'
|
|||||||
import './App.css'
|
import './App.css'
|
||||||
import config from '../tamagui.config'
|
import config from '../tamagui.config'
|
||||||
import LandingPage from './components/LandingPage'
|
import LandingPage from './components/LandingPage'
|
||||||
|
import DeviceHealthCheck from './pages/DeviceHealthCheck/DeviceHealthCheck'
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <LandingPage />,
|
element: <LandingPage />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/device-health-check',
|
||||||
|
element: <DeviceHealthCheck />,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
33
src/components/DeviceCPULoad.stories.tsx
Normal file
33
src/components/DeviceCPULoad.stories.tsx
Normal file
@ -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<typeof DeviceCPULoad>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
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: [],
|
||||||
|
},
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import StandartLineChart from './StandardLineChart'
|
import StandartLineChart from './StandardLineChart'
|
||||||
import IconText from './IconText'
|
import IconText from './IconText'
|
||||||
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
||||||
import { Shadow } from '@status-im/components'
|
import { Shadow, Text } from '@status-im/components'
|
||||||
|
|
||||||
type DataPoint = {
|
type DataPoint = {
|
||||||
x: number
|
x: number
|
||||||
@ -34,7 +34,16 @@ const DeviceCPULoad: React.FC<DeviceCPULoadProps> = ({ load }) => {
|
|||||||
const message = currentLoad < 80 ? 'Good' : 'Poor'
|
const message = currentLoad < 80 ? 'Good' : 'Poor'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Shadow style={{ width: '284px', height: '136px', borderRadius: '16px' }}>
|
<Shadow
|
||||||
|
variant="$2"
|
||||||
|
style={{
|
||||||
|
width: '284px',
|
||||||
|
height: '136px',
|
||||||
|
borderRadius: '16px',
|
||||||
|
border: message === 'Poor' ? '1px solid #D92344' : 'none',
|
||||||
|
backgroundColor: message === 'Poor' ? '#fefafa' : '#fff',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<YStack>
|
<YStack>
|
||||||
<XStack
|
<XStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@ -57,10 +66,17 @@ const DeviceCPULoad: React.FC<DeviceCPULoadProps> = ({ load }) => {
|
|||||||
</XStack>
|
</XStack>
|
||||||
<Separator borderColor={'#e3e3e3'} />
|
<Separator borderColor={'#e3e3e3'} />
|
||||||
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
|
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
|
||||||
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
<IconText
|
||||||
|
icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}
|
||||||
|
weight={'semibold'}
|
||||||
|
>
|
||||||
{message}
|
{message}
|
||||||
</IconText>
|
</IconText>
|
||||||
{/* <Text color={'#E95460'}>This is additional text</Text> */}
|
{message === 'Poor' && (
|
||||||
|
<Text size={13} color="#E95460">
|
||||||
|
{((currentLoad / 80) * 100).toFixed(0)}% Utilization
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</XStack>
|
</XStack>
|
||||||
</YStack>
|
</YStack>
|
||||||
</Shadow>
|
</Shadow>
|
||||||
|
35
src/components/DeviceMemoryHealth.stories.tsx
Normal file
35
src/components/DeviceMemoryHealth.stories.tsx
Normal file
@ -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<typeof DeviceMemoryHealth>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
@ -2,7 +2,7 @@ import StandartLineChart from './StandardLineChart'
|
|||||||
|
|
||||||
import IconText from './IconText'
|
import IconText from './IconText'
|
||||||
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
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 = {
|
type DataPoint = {
|
||||||
x: number
|
x: number
|
||||||
@ -16,11 +16,11 @@ type ChartData = {
|
|||||||
maxValue?: number
|
maxValue?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeviceMemoryProps = {
|
type DeviceMemoryHealthProps = {
|
||||||
currentMemory: number[]
|
currentMemory: number[]
|
||||||
maxMemory?: number
|
maxMemory: number
|
||||||
}
|
}
|
||||||
const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => {
|
const DeviceMemoryHealth = ({ currentMemory, maxMemory }: DeviceMemoryHealthProps) => {
|
||||||
const chartData: ChartData[] = [
|
const chartData: ChartData[] = [
|
||||||
{
|
{
|
||||||
id: 'cpu',
|
id: 'cpu',
|
||||||
@ -35,16 +35,25 @@ const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => {
|
|||||||
const currentLoad =
|
const currentLoad =
|
||||||
chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0
|
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 (
|
return (
|
||||||
<ShadowBox style={{ width: '284px', height: '136px' }}>
|
<ShadowBox
|
||||||
|
variant="$2"
|
||||||
|
style={{
|
||||||
|
width: '284px',
|
||||||
|
height: '136px',
|
||||||
|
borderRadius: '16px',
|
||||||
|
border: message === 'Poor' ? '1px solid #D92344' : 'none',
|
||||||
|
backgroundColor: message === 'Poor' ? '#fefafa' : '#fff',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<YStack>
|
<YStack>
|
||||||
<XStack
|
<XStack
|
||||||
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 }}>
|
||||||
@ -64,11 +73,15 @@ const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => {
|
|||||||
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
||||||
{message}
|
{message}
|
||||||
</IconText>
|
</IconText>
|
||||||
{/* <Text color={'#E95460'}>This is additional text</Text> */}
|
{message === 'Poor' && (
|
||||||
|
<Text size={13} color="#E95460">
|
||||||
|
{((currentLoad / maxMemory || 0) * 100).toFixed(0)}% Utilization
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</XStack>
|
</XStack>
|
||||||
</YStack>
|
</YStack>
|
||||||
</ShadowBox>
|
</ShadowBox>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DeviceMemory
|
export default DeviceMemoryHealth
|
||||||
|
36
src/components/DeviceNetworkHealth.stories.tsx
Normal file
36
src/components/DeviceNetworkHealth.stories.tsx
Normal file
@ -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<typeof DeviceNetworkHealth>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
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: [],
|
||||||
|
},
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import StandartLineChart from './StandardLineChart'
|
import StandartLineChart from './StandardLineChart'
|
||||||
import IconText from './IconText'
|
import IconText from './IconText'
|
||||||
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
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 = {
|
type DataPoint = {
|
||||||
x: number
|
x: number
|
||||||
@ -40,10 +40,19 @@ const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthPr
|
|||||||
const currentLoad =
|
const currentLoad =
|
||||||
chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0
|
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 (
|
return (
|
||||||
<ShadowBox style={{ width: '284px', height: '136px' }}>
|
<ShadowBox
|
||||||
|
variant="$2"
|
||||||
|
style={{
|
||||||
|
width: '284px',
|
||||||
|
height: '136px',
|
||||||
|
borderRadius: '16px',
|
||||||
|
border: message === 'Poor' ? '1px solid #D92344' : 'none',
|
||||||
|
backgroundColor: message === 'Poor' ? '#fefafa' : '#fff',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<YStack>
|
<YStack>
|
||||||
<XStack
|
<XStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@ -69,7 +78,11 @@ const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthPr
|
|||||||
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
||||||
{message}
|
{message}
|
||||||
</IconText>
|
</IconText>
|
||||||
{/* <Text color={'#E95460'}>This is additional text</Text> */}
|
{message === 'Poor' && (
|
||||||
|
<Text size={13} color="#E95460">
|
||||||
|
{((currentLoad / 60) * 100).toFixed(0)}% Utilization
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</XStack>
|
</XStack>
|
||||||
</YStack>
|
</YStack>
|
||||||
</ShadowBox>
|
</ShadowBox>
|
||||||
|
36
src/components/DeviceStorageHealth.stories.tsx
Normal file
36
src/components/DeviceStorageHealth.stories.tsx
Normal file
@ -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<typeof DeviceStorageHealth>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
@ -1,22 +1,22 @@
|
|||||||
import IconText from './IconText'
|
import IconText from './IconText'
|
||||||
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
|
||||||
import StandardGauge from './StandardGauge'
|
import StandardGauge from './StandardGauge'
|
||||||
import { Shadow } from '@status-im/components'
|
import { Shadow, Text } from '@status-im/components'
|
||||||
interface DeviceStorageHealthProps {
|
interface DeviceStorageHealthProps {
|
||||||
storage: number
|
storage: number
|
||||||
maxStorage: number
|
maxStorage: number
|
||||||
}
|
}
|
||||||
const DeviceStorageHealth: React.FC<DeviceStorageHealthProps> = ({ storage, maxStorage }) => {
|
const DeviceStorageHealth: React.FC<DeviceStorageHealthProps> = ({ storage, maxStorage }) => {
|
||||||
const message = storage < maxStorage ? 'Good' : 'Poor'
|
const message = storage < maxStorage ? 'Good' : 'Poor'
|
||||||
const data = (storage: number, maxStorage: number) => {
|
const free = maxStorage - storage
|
||||||
const used = storage
|
const utilization = (storage / (maxStorage || 1)) * 100
|
||||||
const free = maxStorage - storage
|
|
||||||
|
|
||||||
|
const data = (free: number) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: 'storage',
|
id: 'storage',
|
||||||
label: 'Used',
|
label: 'Used',
|
||||||
value: used,
|
value: storage,
|
||||||
color: '#E95460',
|
color: '#E95460',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -27,8 +27,18 @@ const DeviceStorageHealth: React.FC<DeviceStorageHealthProps> = ({ storage, maxS
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Shadow style={{ width: '284px', height: '136px', borderRadius: '16px' }}>
|
<Shadow
|
||||||
|
variant="$2"
|
||||||
|
style={{
|
||||||
|
width: '284px',
|
||||||
|
height: '136px',
|
||||||
|
borderRadius: '16px',
|
||||||
|
border: message === 'Poor' ? '1px solid #D92344' : 'none',
|
||||||
|
backgroundColor: message === 'Poor' ? '#fefafa' : '#fff',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<YStack>
|
<YStack>
|
||||||
<XStack
|
<XStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@ -45,7 +55,7 @@ const DeviceStorageHealth: React.FC<DeviceStorageHealthProps> = ({ storage, maxS
|
|||||||
height: '75px',
|
height: '75px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StandardGauge data={data(storage, maxStorage)} />
|
<StandardGauge data={data(free)} />
|
||||||
</div>
|
</div>
|
||||||
<YStack space={'$3'}>
|
<YStack space={'$3'}>
|
||||||
<Paragraph color={'#09101C'} size={'$6'} fontWeight={'600'}>
|
<Paragraph color={'#09101C'} size={'$6'} fontWeight={'600'}>
|
||||||
@ -58,10 +68,17 @@ const DeviceStorageHealth: React.FC<DeviceStorageHealthProps> = ({ storage, maxS
|
|||||||
</XStack>
|
</XStack>
|
||||||
<Separator borderColor={'#e3e3e3'} />
|
<Separator borderColor={'#e3e3e3'} />
|
||||||
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
|
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
|
||||||
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
|
<IconText
|
||||||
|
icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}
|
||||||
|
weight={'semibold'}
|
||||||
|
>
|
||||||
{message}
|
{message}
|
||||||
</IconText>
|
</IconText>
|
||||||
{/* <Text color={'#E95460'}>This is additional text</Text> */}
|
{message === 'Poor' && (
|
||||||
|
<Text size={13} color="#E95460">
|
||||||
|
{utilization.toFixed(0)}% Utilization
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</XStack>
|
</XStack>
|
||||||
</YStack>
|
</YStack>
|
||||||
</Shadow>
|
</Shadow>
|
||||||
|
@ -30,7 +30,7 @@ const HealthInfoSection = (props: HealthInfoSectionProps) => {
|
|||||||
const networkLatencyPercentage = networkLatency > 100 ? 100 : 0
|
const networkLatencyPercentage = networkLatency > 100 ? 100 : 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<YStack space={'$2'}>
|
<YStack space={'$3'}>
|
||||||
<StatusIconText
|
<StatusIconText
|
||||||
percentage={usedStoragePercentage}
|
percentage={usedStoragePercentage}
|
||||||
threshold={80}
|
threshold={80}
|
||||||
|
@ -5,9 +5,10 @@ import { Text } from '@status-im/components'
|
|||||||
type IconTextProps = {
|
type IconTextProps = {
|
||||||
icon: string
|
icon: string
|
||||||
children: string
|
children: string
|
||||||
|
weight?: 'regular' | 'medium' | 'semibold'
|
||||||
}
|
}
|
||||||
|
|
||||||
const IconText = ({ icon, children }: IconTextProps) => {
|
const IconText = ({ icon, children, weight }: IconTextProps) => {
|
||||||
return (
|
return (
|
||||||
<XStack
|
<XStack
|
||||||
style={{
|
style={{
|
||||||
@ -16,7 +17,7 @@ const IconText = ({ icon, children }: IconTextProps) => {
|
|||||||
space={'$2'}
|
space={'$2'}
|
||||||
>
|
>
|
||||||
<Icon src={icon} />
|
<Icon src={icon} />
|
||||||
<Text size={11} color={'#000000'} weight={"medium"} >
|
<Text size={13} color={'#000000'} weight={weight}>
|
||||||
{children}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
</XStack>
|
</XStack>
|
||||||
|
@ -5,7 +5,10 @@ import QuickStartBar from './QuickStartBar'
|
|||||||
function LandingPage() {
|
function LandingPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LayoutComponent content={<Content />} />
|
<LayoutComponent
|
||||||
|
content={<Content />}
|
||||||
|
rightImageSrc="src/assets/bg-img/landing-page-bg.png"
|
||||||
|
/>
|
||||||
<QuickStartBar />
|
<QuickStartBar />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ import './layout.css'
|
|||||||
type LeftProps = {
|
type LeftProps = {
|
||||||
breadcrumbBar?: ReactNode
|
breadcrumbBar?: ReactNode
|
||||||
content: ReactNode
|
content: ReactNode
|
||||||
|
rightImageSrc?: string
|
||||||
}
|
}
|
||||||
function LayoutComponent(props: LeftProps) {
|
function LayoutComponent(props: LeftProps) {
|
||||||
return (
|
return (
|
||||||
@ -12,16 +13,16 @@ function LayoutComponent(props: LeftProps) {
|
|||||||
{props.breadcrumbBar}
|
{props.breadcrumbBar}
|
||||||
<div className="container">{props.content}</div>
|
<div className="container">{props.content}</div>
|
||||||
</section>
|
</section>
|
||||||
<LayoutRight />
|
<LayoutRight rightImageSrc={props.rightImageSrc} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function LayoutRight() {
|
function LayoutRight({ rightImageSrc }: { rightImageSrc?: string }) {
|
||||||
return (
|
return (
|
||||||
<section className="layout-right">
|
<section className="layout-right">
|
||||||
<div className="image-container">
|
<div className="image-container">
|
||||||
<img src="src/assets/bg-img/day-night-bg.png" alt="" />
|
<img src={rightImageSrc} alt="background" />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
14
src/components/NimbusLogo.stories.tsx
Normal file
14
src/components/NimbusLogo.stories.tsx
Normal file
@ -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<typeof NimbusLogo>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
export const ExampleNimbusLogo: Story = {}
|
29
src/components/Titles.stories.tsx
Normal file
29
src/components/Titles.stories.tsx
Normal file
@ -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<typeof Titles>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
@ -1,25 +1,24 @@
|
|||||||
import { XStack, YStack } from 'tamagui'
|
import { XStack, YStack } from 'tamagui'
|
||||||
import { Button, Text } from '@status-im/components'
|
import { Button, Text } from '@status-im/components'
|
||||||
import Icon from './Icon'
|
import Icon from './Icon'
|
||||||
|
import Title from './Title'
|
||||||
|
|
||||||
type TitlesProps = {
|
type TitlesProps = {
|
||||||
title: string
|
title: string
|
||||||
subtitle: string
|
subtitle: string
|
||||||
button?: boolean
|
isAdvancedSettings?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const Titles = ({ title, subtitle, button }: TitlesProps) => {
|
const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => {
|
||||||
return (
|
return (
|
||||||
<YStack>
|
<YStack style={{ width: '100%' }}>
|
||||||
<XStack justifyContent="space-between">
|
<XStack style={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<Text size={27} weight="semibold">
|
<Title color={'#09101C'}>{title}</Title>
|
||||||
{title}
|
{isAdvancedSettings && (
|
||||||
</Text>
|
<Button size={32} variant="outline" icon={<Icon src={'/icons/reveal.png'} />}>
|
||||||
{button ? (
|
|
||||||
<Button variant="outline" size={32} icon={<Icon src={'/icons/reveal.png'} />}>
|
|
||||||
Advanced Settings
|
Advanced Settings
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
)}
|
||||||
</XStack>
|
</XStack>
|
||||||
<Text size={15} weight="regular">
|
<Text size={15} weight="regular">
|
||||||
{subtitle}
|
{subtitle}
|
||||||
|
16
src/pages/DeviceHealthCheck/DeviceHealthCheck.stories.tsx
Normal file
16
src/pages/DeviceHealthCheck/DeviceHealthCheck.stories.tsx
Normal file
@ -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<typeof DeviceHealthCheck>
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
type Story = StoryObj<typeof meta>
|
||||||
|
|
||||||
|
export const Page: Story = {
|
||||||
|
args: {},
|
||||||
|
}
|
68
src/pages/DeviceHealthCheck/DeviceHealthCheck.tsx
Normal file
68
src/pages/DeviceHealthCheck/DeviceHealthCheck.tsx
Normal file
@ -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 (
|
||||||
|
<LayoutComponent
|
||||||
|
content={<DeviceHealthCheckContent />}
|
||||||
|
rightImageSrc="/background-images/eye-background.png"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeviceHealthCheck
|
||||||
|
|
||||||
|
const DeviceHealthCheckContent = () => {
|
||||||
|
return (
|
||||||
|
<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}
|
||||||
|
/>
|
||||||
|
<XStack space={'$4'}>
|
||||||
|
<DeviceStorageHealth storage={44} maxStorage={30} />
|
||||||
|
<DeviceCPULoad load={[12, 123, 4, 90]} />
|
||||||
|
</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]} />
|
||||||
|
</XStack>
|
||||||
|
<HealthInfoSection
|
||||||
|
usedStorage={120}
|
||||||
|
maxStorage={160}
|
||||||
|
usedRamMemory={8}
|
||||||
|
maxRamMemory={16}
|
||||||
|
cpuClockRate={2.5}
|
||||||
|
networkLatency={75}
|
||||||
|
/>
|
||||||
|
<InformationBox
|
||||||
|
icon={<Icon src="/icons/close.png" width={11} height={11} />}
|
||||||
|
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."
|
||||||
|
/>
|
||||||
|
<Stack style={{ marginTop: '1rem' }}>
|
||||||
|
<Button>Continue</Button>
|
||||||
|
</Stack>
|
||||||
|
</YStack>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user