diff --git a/src/AppV2.js b/src/AppV2.js
index 65811885..fb07891d 100644
--- a/src/AppV2.js
+++ b/src/AppV2.js
@@ -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: {
@@ -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,
+ },
},
}));
@@ -63,6 +71,8 @@ const App = () => {
+
+
diff --git a/src/v2/components/Blocks/Detail/index.jsx b/src/v2/components/Blocks/Detail/index.jsx
new file mode 100644
index 00000000..c993f2ef
--- /dev/null
+++ b/src/v2/components/Blocks/Detail/index.jsx
@@ -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
Loading...
;
+ }
+
+ 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 (
+
+
+ 123123123
+
+ );
+ },
+ },
+ ];
+
+ const renderSpec = ({label, value}: {label: string, value: string}) => (
+
+
+ {label}
+
+
+
+ {typeof value === 'function' ? value() : value}
+
+
+ );
+
+ return (
+
+
+
+
+ 7887219
+
+
+
+
+
+
+
+
+
+ Transactions
+
+
+ );
+};
+
+export default observer(BlockDetail);
diff --git a/src/v2/components/Blocks/Detail/styles.js b/src/v2/components/Blocks/Detail/styles.js
new file mode 100644
index 00000000..d2aed5e2
--- /dev/null
+++ b/src/v2/components/Blocks/Detail/styles.js
@@ -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,
+ },
+ },
+}));
diff --git a/src/v2/components/Blocks/Table/index.jsx b/src/v2/components/Blocks/Table/index.jsx
new file mode 100644
index 00000000..50133178
--- /dev/null
+++ b/src/v2/components/Blocks/Table/index.jsx
@@ -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 (
+
+
+
+ 7887319
+
+
+ 55 sec ago
+ 126
+ 5
+
+
+ {block.pubkey}
+
+
+ );
+ };
+ const renderTH = ({name, width, ...rest}: THead) => (
+
+ {name}
+
+
+ );
+
+ return (
+
+ {showTable ? (
+
+
+ {map(renderTH)(tHeads)}
+
+
+ {map(renderRow)(blocks)}
+
+
+
+ 7887319
+
+
+ 55 sec ago
+ 126
+ 5
+
+
+
+
+
+
+ ) : (
+
+
+
+ -
+
Block
+ 7887219
+
+ -
+
Time
+ 55 sec ago
+
+ -
+
Transactions
+ 126
+
+ -
+
Uncles
+ 5
+
+ -
+
Miner
+
+
+
+
+
+ )}
+
+ );
+};
+
+export default observer(BlocksTable);
diff --git a/src/v2/components/Blocks/Table/styles.js b/src/v2/components/Blocks/Table/styles.js
new file mode 100644
index 00000000..5678a2e8
--- /dev/null
+++ b/src/v2/components/Blocks/Table/styles.js
@@ -0,0 +1,98 @@
+import {makeStyles} from '@material-ui/core';
+import getColor from 'v2/utils/getColor';
+
+export default makeStyles(theme => ({
+ root: {
+ marginTop: 19,
+ [theme.breakpoints.down('sm')]: {
+ padding: 0,
+ paddingBottom: 27,
+ marginBottom: 50,
+ },
+ },
+ head: {
+ border: '1px solid #979797',
+ '& th': {
+ textTransform: 'uppercase',
+ fontSize: 15,
+ letterSpacing: 2,
+ fontWeight: 'bold',
+ borderBottom: 'none',
+ },
+ },
+ body: {
+ '& td': {
+ fontSize: 15,
+ paddingTop: 18,
+ paddingBottom: 18,
+ maxWidth: 0,
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ },
+ },
+ name: {
+ display: 'flex',
+ alignItems: 'center',
+ color: getColor('main')(theme),
+ textDecoration: 'none',
+ '& div': {
+ '&:first-child': {
+ marginRight: 15,
+ },
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ },
+ [theme.breakpoints.down('sm')]: {
+ marginBottom: 22,
+ },
+ },
+ list: {
+ width: '100%',
+ },
+ vertical: {
+ [theme.breakpoints.down('sm')]: {
+ flexDirection: 'column',
+ },
+ },
+ card: {
+ padding: 7,
+ background: getColor('grey2')(theme),
+ '& ul': {
+ padding: 0,
+ margin: 0,
+ display: 'flex',
+ flexWrap: 'wrap',
+ '& li': {
+ padding: 10,
+ width: '33.33%',
+ [theme.breakpoints.down('xs')]: {
+ width: '50%',
+ },
+ },
+ },
+ },
+ cardVertical: {
+ [theme.breakpoints.down('sm')]: {
+ marginBottom: 2,
+ marginRight: 0,
+ maxWidth: '100%',
+ },
+ },
+ cardTitle: {
+ fontSize: 12,
+ textTransform: 'uppercase',
+ color: '#C4C4C4',
+ letterSpacing: 2,
+ fontWeight: 'bold',
+ },
+ miner: {
+ display: 'flex',
+ alignItems: 'center',
+ color: getColor('main')(theme),
+ '& div': {
+ marginLeft: 5,
+ },
+ },
+}));
diff --git a/src/v2/components/Blocks/index.jsx b/src/v2/components/Blocks/index.jsx
new file mode 100644
index 00000000..87177137
--- /dev/null
+++ b/src/v2/components/Blocks/index.jsx
@@ -0,0 +1,23 @@
+// @flow
+import {Container} from '@material-ui/core';
+import React from 'react';
+import HelpLink from 'v2/components/HelpLink';
+import SectionHeader from 'v2/components/UI/SectionHeader';
+
+import Table from './Table';
+import useStyles from './styles';
+
+const BlocksPage = () => {
+ const classes = useStyles();
+ return (
+
+
+
+ 234,654
+
+
+
+ );
+};
+
+export default BlocksPage;
diff --git a/src/v2/components/Blocks/styles.js b/src/v2/components/Blocks/styles.js
new file mode 100644
index 00000000..2be218b0
--- /dev/null
+++ b/src/v2/components/Blocks/styles.js
@@ -0,0 +1,8 @@
+import {makeStyles} from '@material-ui/core';
+
+export default makeStyles(() => ({
+ totalBlocks: {
+ marginRight: 'auto',
+ marginLeft: 100,
+ },
+}));
diff --git a/src/v2/components/HelpLink/styles.js b/src/v2/components/HelpLink/styles.js
index efd0ed2e..678e772e 100644
--- a/src/v2/components/HelpLink/styles.js
+++ b/src/v2/components/HelpLink/styles.js
@@ -10,7 +10,8 @@ export default makeStyles(theme => ({
borderRadius: '50%',
border: `1px solid ${getColor('greenDark')(theme)}`,
fontSize: 12,
- padding: '0 5px',
+ alignItems: 'center',
+ padding: '2px 5px 0',
color: getColor('greenDark')(theme),
transition: '.15s ease-in-out',
marginLeft: 5,
diff --git a/src/v2/components/Transactions/Table/index.jsx b/src/v2/components/Transactions/Table/index.jsx
new file mode 100644
index 00000000..86709a08
--- /dev/null
+++ b/src/v2/components/Transactions/Table/index.jsx
@@ -0,0 +1,186 @@
+// @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 HelpLink from 'v2/components/HelpLink';
+import TypeLabel from 'v2/components/UI/TypeLabel';
+
+import useStyles from './styles';
+
+type THead = {
+ name: string,
+ text: string,
+ term: string,
+};
+
+const tHeads: THead[] = [
+ {
+ name: 'hash',
+ text: '',
+ term: '',
+ },
+ {
+ name: 'block',
+ text: '',
+ term: '',
+ },
+ {
+ name: 'time',
+ text: '',
+ term: '',
+ },
+ {
+ name: 'application id',
+ text: '',
+ term: '',
+ },
+ {
+ name: 'type',
+ text: '',
+ term: '',
+ },
+ {
+ name: 'confirmations',
+ text: '',
+ term: '',
+ },
+];
+
+const TransactionsTable = ({
+ separate,
+ transactions,
+}: {
+ separate: boolean,
+ transactions: any[],
+}) => {
+ const classes = useStyles();
+ const theme = useTheme();
+ const showTable = useMediaQuery(theme.breakpoints.up('md'));
+
+ const renderRow = transaction => {
+ return (
+
+
+
+ 7887319
+
+
+
+
+ 7887319
+
+
+ 55 sec ago
+
+
+ 7887319
+
+
+
+
+
+
+ );
+ };
+ const renderTH = ({name, ...rest}: THead) => (
+
+ {name}
+
+
+ );
+
+ return (
+
+ {showTable ? (
+
+
+ {map(renderTH)(tHeads)}
+
+
+ {map(renderRow)(transactions)}
+
+
+
+ 5CpdpKwKUBJgD4Bd...
+
+
+
+
+ 7887319
+
+
+ 55 sec ago
+
+
+ 5CpdpKwKUBJgD4Bd...
+
+
+
+
+
+ 5
+
+
+
+ ) : (
+
+
+
+ -
+
Hash
+
+ 5CpdpKwKUBJgD4Bd...
+
+
+ -
+
Block
+
+ 7887319
+
+
+ -
+
Time
+ 55 sec ago
+
+ -
+
Application ID
+
+ 5CpdpKwKUBJgD4Bd...
+
+
+ -
+
Type
+
+
+ -
+
Confirmations
+ 5
+
+
+
+
+ )}
+
+ );
+};
+
+export default observer(TransactionsTable);
diff --git a/src/v2/components/Transactions/Table/styles.js b/src/v2/components/Transactions/Table/styles.js
new file mode 100644
index 00000000..a895378b
--- /dev/null
+++ b/src/v2/components/Transactions/Table/styles.js
@@ -0,0 +1,91 @@
+import {makeStyles} from '@material-ui/core';
+import getColor from 'v2/utils/getColor';
+
+export default makeStyles(theme => ({
+ root: {
+ marginTop: 19,
+ [theme.breakpoints.down('sm')]: {
+ padding: 0,
+ paddingBottom: 27,
+ marginBottom: 50,
+ },
+ },
+ head: {
+ border: '1px solid #979797',
+ '& th': {
+ textTransform: 'uppercase',
+ fontSize: 15,
+ letterSpacing: 2,
+ fontWeight: 'bold',
+ borderBottom: 'none',
+ whiteSpace: 'nowrap',
+ },
+ },
+ body: {
+ '& td': {
+ fontSize: 15,
+ paddingTop: 18,
+ paddingBottom: 18,
+ maxWidth: 0,
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ },
+ },
+ name: {
+ display: 'flex',
+ alignItems: 'center',
+ color: getColor('main')(theme),
+ textDecoration: 'none',
+ '& div': {
+ '&:first-child': {
+ marginRight: 15,
+ },
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ },
+ [theme.breakpoints.down('sm')]: {
+ marginBottom: 22,
+ },
+ },
+ list: {
+ width: '100%',
+ },
+ vertical: {
+ [theme.breakpoints.down('sm')]: {
+ flexDirection: 'column',
+ },
+ },
+ card: {
+ padding: 7,
+ background: getColor('grey2')(theme),
+ '& ul': {
+ padding: 0,
+ margin: 0,
+ display: 'flex',
+ flexWrap: 'wrap',
+ '& li': {
+ padding: 10,
+ width: '33.33%',
+ [theme.breakpoints.down('xs')]: {
+ width: '50%',
+ },
+ },
+ },
+ },
+ cardVertical: {
+ [theme.breakpoints.down('sm')]: {
+ marginBottom: 2,
+ marginRight: 0,
+ maxWidth: '100%',
+ },
+ },
+ cardTitle: {
+ fontSize: 12,
+ textTransform: 'uppercase',
+ color: '#C4C4C4',
+ letterSpacing: 2,
+ fontWeight: 'bold',
+ },
+}));
diff --git a/src/v2/components/UI/TypeLabel/index.jsx b/src/v2/components/UI/TypeLabel/index.jsx
new file mode 100644
index 00000000..6f43feb5
--- /dev/null
+++ b/src/v2/components/UI/TypeLabel/index.jsx
@@ -0,0 +1,18 @@
+// @flow
+import React from 'react';
+import cn from 'classnames';
+
+import useStyles from './styles';
+
+type Type = 'other' | 'consensus' | 'system' | 'loader';
+
+const TypeLabel = ({type, label}: {type: Type, label: string}) => {
+ const classes = useStyles();
+ return (
+
+ {label}
+
+ );
+};
+
+export default TypeLabel;
diff --git a/src/v2/components/UI/TypeLabel/styles.js b/src/v2/components/UI/TypeLabel/styles.js
new file mode 100644
index 00000000..4601d72f
--- /dev/null
+++ b/src/v2/components/UI/TypeLabel/styles.js
@@ -0,0 +1,41 @@
+import {makeStyles} from '@material-ui/core';
+import getColor from 'v2/utils/getColor';
+
+export default makeStyles(theme => ({
+ root: {
+ height: 27,
+ display: 'inline-flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ borderRadius: 2,
+ border: '1px solid transparent',
+ padding: '0 10px',
+ [theme.breakpoints.down('xs')]: {
+ height: 18,
+ padding: '0 7px',
+ },
+ },
+ text: {
+ textTransform: 'uppercase',
+ fontSize: 15,
+ [theme.breakpoints.down('xs')]: {
+ fontSize: 13,
+ },
+ },
+ loader: {
+ color: getColor('aqua')(theme),
+ borderColor: getColor('aqua')(theme),
+ },
+ system: {
+ color: getColor('pink')(theme),
+ borderColor: getColor('pink')(theme),
+ },
+ consensus: {
+ color: getColor('blue')(theme),
+ borderColor: getColor('blue')(theme),
+ },
+ other: {
+ color: getColor('yellow')(theme),
+ borderColor: getColor('yellow')(theme),
+ },
+}));
diff --git a/src/v2/theme.js b/src/v2/theme.js
index a80fbe7a..258bd74f 100644
--- a/src/v2/theme.js
+++ b/src/v2/theme.js
@@ -15,6 +15,10 @@ export default createMuiTheme({
greenDark: '#00a771',
primaryLoader: '#202020',
secondaryLoader: '#404040',
+ aqua: '#33f1ff',
+ pink: '#f71ef4',
+ blue: '#2069f6',
+ yellow: '#ffc617',
},
secondary: {
main: '#000',