initial ui for test my node
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -40,6 +40,12 @@ export const Nav = () => {
|
||||
Icon: Delegate,
|
||||
onClick: () => navigate('/delegation'),
|
||||
},
|
||||
{
|
||||
label: 'Test my node',
|
||||
route: '/test-my-node',
|
||||
Icon: Delegate,
|
||||
onClick: () => navigate('/test-my-node'),
|
||||
},
|
||||
{
|
||||
label: 'Docs',
|
||||
route: '/admin',
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import { Button, Grid, Stack } from '@mui/material';
|
||||
import testNode from 'src/assets/test-node-illustration.jpg';
|
||||
import { DescriptionItem } from '../components/overview';
|
||||
|
||||
const content = [
|
||||
{
|
||||
title: 'How is works',
|
||||
description:
|
||||
'This is your APY playground - play with the parameters on left to see estimated rewards on the right side',
|
||||
},
|
||||
{
|
||||
title: 'Test path',
|
||||
description:
|
||||
'This is your APY playground - play with the parameters on left to see estimated rewards on the right side',
|
||||
},
|
||||
{
|
||||
title: 'Results',
|
||||
description:
|
||||
'This is your APY playground - play with the parameters on left to see estimated rewards on the right side',
|
||||
},
|
||||
];
|
||||
|
||||
export const Overview = ({ onStartTest }: { onStartTest: () => void }) => (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item md={12} lg={6}>
|
||||
<img src={testNode} />
|
||||
</Grid>
|
||||
<Grid item container direction="column" md={12} lg={6}>
|
||||
<Grid item>
|
||||
<Stack>{content.map(DescriptionItem)}</Stack>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button fullWidth variant="contained" disableElevation onClick={onStartTest}>
|
||||
Start test
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
@@ -0,0 +1,90 @@
|
||||
import React from 'react';
|
||||
import { ArrowForward, CheckCircleOutline, Description, Download } from '@mui/icons-material';
|
||||
import { Box, Button, Card, Chip, CircularProgress, Divider, Grid, Stack, Typography } from '@mui/material';
|
||||
import format from 'date-fns/format';
|
||||
import { ResultsCard } from '../components/ResultsCard';
|
||||
import { ResultsCardDetail } from '../components/ResultsCardDetail';
|
||||
import { PathChip } from '../components/PathChip';
|
||||
|
||||
const NodeSpeed = ({ Mbps, performance }: { Mbps: number; performance: 'poor' | 'fair' | 'good' }) => (
|
||||
<ResultsCard
|
||||
label="Node speed"
|
||||
detail={`${performance === 'good' ? 'Fast' : performance === 'poor' ? 'Slow' : 'Fair'} node`}
|
||||
isOk={performance === 'good'}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
width: 250,
|
||||
height: 250,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
mx: 'auto',
|
||||
mt: 4,
|
||||
}}
|
||||
>
|
||||
<CircularProgress
|
||||
variant="determinate"
|
||||
value={performance === 'poor' ? 12.5 : performance === 'good' ? 85 : 65}
|
||||
size={250}
|
||||
sx={{ position: 'absolute', top: 0, left: 0 }}
|
||||
color={performance === 'poor' ? 'error' : performance === 'good' ? 'success' : 'warning'}
|
||||
/>
|
||||
<Stack alignItems="center" gap={1}>
|
||||
<Typography fontWeight="bold" variant="h4">
|
||||
{Mbps}
|
||||
</Typography>
|
||||
<Typography>Mbps</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
</ResultsCard>
|
||||
);
|
||||
|
||||
const Packets = ({ sent, received }: { sent: string; received: string }) => (
|
||||
<ResultsCard label="Packets" detail="98% packets" isOk>
|
||||
<Divider sx={{ my: 2 }} />
|
||||
<ResultsCardDetail label="Packets sent" detail={sent} />
|
||||
<Divider sx={{ my: 2 }} />
|
||||
<ResultsCardDetail label="Packets received" detail={received} />
|
||||
</ResultsCard>
|
||||
);
|
||||
|
||||
const Path = ({ layer }: { layer: number }) => (
|
||||
<ResultsCard label="Path" detail="Your node was in layer 2" isOk>
|
||||
<Stack direction="row" alignItems="center" gap={1} sx={{ mt: 2 }}>
|
||||
<PathChip label="Gateway" highlight={false} />
|
||||
<ArrowForward sx={{ color: 'grey.500' }} />
|
||||
<PathChip label="Node - Layer 1" highlight={layer === 1} />
|
||||
<ArrowForward sx={{ color: 'grey.500' }} />
|
||||
<PathChip label="Node - Layer 2" highlight={layer === 2} />
|
||||
<ArrowForward sx={{ color: 'grey.500' }} />
|
||||
<PathChip label="Node - Layer 3" highlight={layer === 3} />
|
||||
</Stack>
|
||||
</ResultsCard>
|
||||
);
|
||||
|
||||
export const Results = () => (
|
||||
<>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 1 }}>
|
||||
<Box display="flex" gap={1}>
|
||||
<Typography fontWeight="bold" component="span">
|
||||
Test date
|
||||
</Typography>
|
||||
<Typography>{format(new Date(), 'dd/MM/yyyy HH:mm')}</Typography>
|
||||
</Box>
|
||||
<Button startIcon={<Download />}>Save to PDF</Button>
|
||||
</Stack>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item md={5}>
|
||||
<NodeSpeed Mbps={150.01} performance="good" />
|
||||
</Grid>
|
||||
<Grid item container direction="column" md={7}>
|
||||
<Stack spacing={2}>
|
||||
<Packets sent="5000" received="1000" />
|
||||
<Path layer={2} />
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { Box, CircularProgress, Stack, Typography } from '@mui/material';
|
||||
|
||||
export const TestProgress = ({ totalPackets, packetsSent }: { totalPackets: number; packetsSent: number }) => {
|
||||
const percentage = Math.round((packetsSent / totalPackets) * 100);
|
||||
|
||||
return (
|
||||
<Stack alignItems="center" gap={3}>
|
||||
<Typography sx={{ textTransform: 'uppercase' }}>Test in progress</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
width: 250,
|
||||
height: 250,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<CircularProgress
|
||||
variant="determinate"
|
||||
value={percentage}
|
||||
size={250}
|
||||
sx={{ position: 'absolute', top: 0, left: 0 }}
|
||||
/>
|
||||
<Typography fontWeight="bold" variant="h4">
|
||||
{percentage}%
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography>Sending packets...</Typography>
|
||||
<Typography>{`${packetsSent} / ${totalPackets}`}</Typography>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Chip } from '@mui/material';
|
||||
|
||||
export const PathChip = ({ label, highlight }: { label: string; highlight: boolean }) => (
|
||||
<Chip label={label} size="medium" color={highlight ? 'primary' : 'default'} />
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { CheckCircleOutline } from '@mui/icons-material';
|
||||
import { Card } from '@mui/material';
|
||||
import { ResultsCardDetail } from './ResultsCardDetail';
|
||||
|
||||
export const ResultsCard: React.FC<{ label: string; detail: string; isOk: boolean }> = ({
|
||||
label,
|
||||
detail,
|
||||
isOk,
|
||||
children,
|
||||
}) => (
|
||||
<Card variant="outlined" sx={{ p: 3 }}>
|
||||
<ResultsCardDetail
|
||||
label={label}
|
||||
detail={detail}
|
||||
boldLabel
|
||||
DescriptionIcon={isOk && <CheckCircleOutline sx={{ color: 'success.light' }} />}
|
||||
/>
|
||||
{children}
|
||||
</Card>
|
||||
);
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Box, Stack, Typography } from '@mui/material';
|
||||
|
||||
export const ResultsCardDetail = ({
|
||||
label,
|
||||
detail,
|
||||
DescriptionIcon,
|
||||
boldLabel,
|
||||
}: {
|
||||
label: string;
|
||||
detail: string;
|
||||
DescriptionIcon?: React.ReactNode;
|
||||
boldLabel?: boolean;
|
||||
}) => (
|
||||
<Stack direction="row" justifyContent="space-between">
|
||||
<Typography fontWeight={boldLabel ? 'bold' : 'regular'}>{label}</Typography>
|
||||
<Box display="flex" gap={1} alignItems="center">
|
||||
<Typography>{detail}</Typography>
|
||||
{DescriptionIcon}
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
export const DescriptionItem = ({ title, description }: { title: string; description: string }) => (
|
||||
<Box>
|
||||
<Typography fontWeight="bold" sx={{ mb: 1 }}>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography fontSize="small" sx={{ color: 'grey.700', mb: 2 }}>
|
||||
{description}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
@@ -5,3 +5,4 @@ export * from './bonding';
|
||||
export * from './delegation';
|
||||
export * from './internal-docs';
|
||||
export * from './unbond';
|
||||
export * from './test-my-node';
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import React, { useState } from 'react';
|
||||
import { NymCard } from 'src/components';
|
||||
import { Overview } from 'src/components/TestMyNode/Overview';
|
||||
import { Results } from 'src/components/TestMyNode/Results';
|
||||
import { TestProgress } from 'src/components/TestMyNode/TestProgress';
|
||||
|
||||
export const TestNode = () => {
|
||||
const [view, setView] = useState('overview');
|
||||
const [packetsSent, setPacketsSent] = useState(0);
|
||||
const totalPackets = 500;
|
||||
|
||||
const mockPacketTransfer = (sent: number) => {
|
||||
if (sent - 1 < totalPackets) {
|
||||
setPacketsSent(sent);
|
||||
setTimeout(() => {
|
||||
mockPacketTransfer(sent + 1);
|
||||
}, 12.5);
|
||||
}
|
||||
if (sent === totalPackets) {
|
||||
setView('results');
|
||||
}
|
||||
};
|
||||
|
||||
const startTest = () => {
|
||||
setView('start-test');
|
||||
mockPacketTransfer(0);
|
||||
};
|
||||
|
||||
return (
|
||||
<NymCard title="Test Node">
|
||||
{view === 'overview' && <Overview onStartTest={startTest} />}
|
||||
{view === 'start-test' && <TestProgress totalPackets={totalPackets} packetsSent={packetsSent} />}
|
||||
{view === 'results' && <Results />}
|
||||
</NymCard>
|
||||
);
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import { ApplicationLayout } from 'src/layouts';
|
||||
import { Terminal } from 'src/pages/terminal';
|
||||
import { Send } from 'src/components/Send';
|
||||
import { Receive } from '../components/Receive';
|
||||
import { Balance, InternalDocs, Unbond, DelegationPage, Admin, BondingPage } from '../pages';
|
||||
import { Balance, InternalDocs, Unbond, DelegationPage, Admin, BondingPage, TestNode } from '../pages';
|
||||
|
||||
export const AppRoutes = () => (
|
||||
<ApplicationLayout>
|
||||
@@ -16,6 +16,7 @@ export const AppRoutes = () => (
|
||||
<Route path="/bonding" element={<BondingPage />} />
|
||||
<Route path="/unbond" element={<Unbond />} />
|
||||
<Route path="/delegation" element={<DelegationPage />} />
|
||||
<Route path="/test-my-node" element={<TestNode />} />
|
||||
<Route path="/docs" element={<InternalDocs />} />
|
||||
<Route path="/admin" element={<Admin />} />
|
||||
</Routes>
|
||||
|
||||
Reference in New Issue
Block a user