initial ui for test my node

This commit is contained in:
fmtabbara
2022-09-07 22:43:04 +01:00
parent 2363f3ad0a
commit a95ba05e78
12 changed files with 271 additions and 1 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+6
View File
@@ -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>
);
+1
View File
@@ -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>
);
};
+2 -1
View File
@@ -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>