Skip to content
This repository has been archived by the owner on Jul 22, 2020. It is now read-only.

Commit

Permalink
feat: blocks list and detail pages
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-calavera authored and sunnygleason committed Aug 1, 2019
1 parent af4562f commit 12c6b4c
Show file tree
Hide file tree
Showing 13 changed files with 830 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/AppV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const Validators = lazy(() => import('v2/components/Validators'));
const ValidatorsAll = lazy(() => import('v2/components/Validators/All'));
const ValidatorDetail = lazy(() => import('v2/components/Validators/Detail'));
const TourDeSol = lazy(() => import('v2/components/TourDeSol'));
const Blocks = lazy(() => import('v2/components/Blocks'));
const BlockDetail = lazy(() => import('v2/components/Blocks/Detail'));

const useStyles = makeStyles(theme => ({
root: {
Expand All @@ -44,6 +46,12 @@ const useStyles = makeStyles(theme => ({
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
[theme.breakpoints.down('md')]: {
minHeight: 85,
},
[theme.breakpoints.up('md')]: {
minHeight: 50,
},
},
}));

Expand All @@ -63,6 +71,8 @@ const App = () => {
<Route exact path="/validators/all" component={ValidatorsAll} />
<Route exact path="/validators/:id" component={ValidatorDetail} />
<Route exact path="/tour-de-sol" component={TourDeSol} />
<Route exact path="/blocks" component={Blocks} />
<Route exact path="/blocks/:id" component={BlockDetail} />
</Switch>
</Suspense>
<Footer />
Expand Down
102 changes: 102 additions & 0 deletions src/v2/components/Blocks/Detail/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// @flow
import {Container} from '@material-ui/core';
import {observer} from 'mobx-react-lite';
import React, {useEffect} from 'react';
import {map} from 'lodash/fp';
import {Match, Link} from 'react-router-dom';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import SectionHeader from 'v2/components/UI/SectionHeader';
import HelpLink from 'v2/components/HelpLink';
import Avatar from 'v2/components/UI/Avatar';
import {ReactComponent as CopyIcon} from 'v2/assets/icons/copy.svg';
import Mixpanel from 'v2/mixpanel';

import TransactionsTable from '../../Transactions/Table';
import useStyles from './styles';

const BlockDetail = ({match}: {match: Match}) => {
const classes = useStyles();
const {params} = match;

useEffect(() => {
Mixpanel.track(`Clicked Block ${params.id}`);
}, [params.id]);

const block = {};

if (!block) {
return <div>Loading...</div>;
}

const specs = [
{
label: 'Time',
hint: '',
value: '06/05/2019 11:27AM',
},
{
label: 'Fee',
hint: '',
value: '0.006 SOL | $0.60',
},
{
label: 'Height',
hint: '',
value: '7887219',
},
{
label: 'reward',
hint: '',
value: '0',
},
{
label: 'mined',
hint: '',
value() {
return (
<Link to="" className={classes.mined}>
<Avatar avatarUrl="" name="" />
123123123
</Link>
);
},
},
];

const renderSpec = ({label, value}: {label: string, value: string}) => (
<li key={label}>
<div className={classes.label}>
{label}
<HelpLink term="" text="" />
</div>
<div className={classes.value}>
{typeof value === 'function' ? value() : value}
</div>
</li>
);

return (
<Container>
<div className={classes.root}>
<SectionHeader title="Block Detail">
<span className={classes.blockTitle}>
7887219
<CopyToClipboard text="7887219">
<div>
<CopyIcon />
</div>
</CopyToClipboard>
</span>
</SectionHeader>
<div className={classes.body}>
<ul className={classes.spec}>{map(renderSpec)(specs)}</ul>
<div></div>
</div>
</div>
<div className={classes.tableTitle}>Transactions</div>
<TransactionsTable transactions={[]} />
</Container>
);
};

export default observer(BlockDetail);
92 changes: 92 additions & 0 deletions src/v2/components/Blocks/Detail/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {makeStyles} from '@material-ui/core';
import getColor from 'v2/utils/getColor';

export default makeStyles(theme => ({
blockTitle: {
marginRight: 'auto',
marginLeft: 200,
display: 'flex',
[theme.breakpoints.down('sm')]: {
marginLeft: 0,
},
'& div': {
marginLeft: 10,
},
},
spec: {
display: 'flex',
flexWrap: 'wrap',
padding: 0,
[theme.breakpoints.down('xs')]: {
flexDirection: 'column',
},
'& li': {
width: '50%',
display: 'flex',
marginBottom: 48,
[theme.breakpoints.down('sm')]: {
marginBottom: 32,
flexDirection: 'column',
},
[theme.breakpoints.down('xs')]: {
width: '100%',
},
'&:nth-child(odd)': {
width: 'calc(50% - 80px)',
marginRight: 80,
[theme.breakpoints.down('xs')]: {
width: '100%',
marginRight: 0,
},
},
},
},
label: {
textTransform: 'uppercase',
fontSize: 15,
fontWeight: 'bold',
letterSpacing: 2,
width: 100,
flexShrink: 0,
marginRight: 40,
color: getColor('grey4')(theme),
display: 'flex',
alignItems: 'center',
[theme.breakpoints.down('md')]: {
marginRight: 20,
},
[theme.breakpoints.down('sm')]: {
width: '100%',
marginRight: 0,
},
},
value: {
fontSize: 15,
lineHeight: '29px',
overflow: 'hidden',
textOverflow: 'ellipsis',
'& a': {
color: getColor('main')(theme),
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
},
},
},
tableTitle: {
background: getColor('main')(theme),
textTransform: 'uppercase',
padding: '18px 33px 15px',
fontWeight: 'bold',
color: getColor('dark')(theme),
letterSpacing: 2.5,
marginBottom: 26,
},
mined: {
display: 'flex',
alignItems: 'center',
'& div': {
marginRight: 10,
},
},
}));
155 changes: 155 additions & 0 deletions src/v2/components/Blocks/Table/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// @flow

import React from 'react';
import {
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from '@material-ui/core';
import cn from 'classnames';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import {useTheme} from '@material-ui/core/styles';
import {observer} from 'mobx-react-lite';
import {Link} from 'react-router-dom';
import {map} from 'lodash/fp';
import Avatar from 'v2/components/UI/Avatar';

import HelpLink from '../../HelpLink';
import useStyles from './styles';

type THead = {
name: string,
text: string,
term: string,
width?: number,
};

const tHeads: THead[] = [
{
name: 'blocks',
text: '',
term: '',
},
{
name: 'time',
text: '',
term: '',
},
{
name: 'transactions',
text: '',
term: '',
},
{
name: 'uncles',
text: '',
term: '',
},
{
name: 'miner',
text: '',
term: '',
width: 200,
},
];

const BlocksTable = ({separate}: {separate: boolean}) => {
const classes = useStyles();
const theme = useTheme();
const showTable = useMediaQuery(theme.breakpoints.up('md'));
const blocks = [];

const renderRow = block => {
return (
<TableRow hover key={block.id}>
<TableCell align="center">
<Link to={`/blocks/${block.id}`} className={classes.name}>
7887319
</Link>
</TableCell>
<TableCell>55 sec ago</TableCell>
<TableCell>126</TableCell>
<TableCell>5</TableCell>
<TableCell>
<Avatar avatarUrl="" name="" />
{block.pubkey}
</TableCell>
</TableRow>
);
};
const renderTH = ({name, width, ...rest}: THead) => (
<TableCell key={name} width={width}>
{name}
<HelpLink {...rest} />
</TableCell>
);

return (
<div className={classes.root}>
{showTable ? (
<Table>
<TableHead className={classes.head}>
<TableRow>{map(renderTH)(tHeads)}</TableRow>
</TableHead>
<TableBody
classes={{
root: classes.body,
}}
>
{map(renderRow)(blocks)}
<TableRow hover>
<TableCell align="center">
<Link to={`/blocks/123`} className={classes.name}>
7887319
</Link>
</TableCell>
<TableCell>55 sec ago</TableCell>
<TableCell>126</TableCell>
<TableCell>5</TableCell>
<TableCell>
<div className={classes.miner}>
<Avatar avatarUrl="" name="" />
<div>0xAA15A3E6b97...</div>
</div>
</TableCell>
</TableRow>
</TableBody>
</Table>
) : (
<div className={cn(classes.list, separate && classes.vertical)}>
<div className={classes.card}>
<ul>
<li>
<div className={classes.cardTitle}>Block</div>
<div>7887219</div>
</li>
<li>
<div className={classes.cardTitle}>Time</div>
<div>55 sec ago</div>
</li>
<li>
<div className={classes.cardTitle}>Transactions</div>
<div>126</div>
</li>
<li>
<div className={classes.cardTitle}>Uncles</div>
<div>5</div>
</li>
<li>
<div className={classes.cardTitle}>Miner</div>
<div className={classes.miner}>
<Avatar avatarUrl="" name="" />
<div>0xAA15A3E6b97...</div>
</div>
</li>
</ul>
</div>
</div>
)}
</div>
);
};

export default observer(BlocksTable);
Loading

0 comments on commit 12c6b4c

Please sign in to comment.