Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tables #6

Merged
merged 3 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"prepare": "husky install"
},
"dependencies": {
"axios": "^0.24.0",
"highcharts": "^9.3.1",
"highcharts-react-official": "^3.1.0",
"next": "12.0.2",
Expand Down
2,324 changes: 236 additions & 2,088 deletions src/assets/data/ledger.list.blocks.json

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions src/components/Panel3/Panel3.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { useEffect, useState } from 'react';
import styles from './Panel3.module.css';
import RTTable from 'components/atoms/RTTable/RTTable';
import RTTRow from 'components/atoms/RTTable/RTTRow';
import RTTRowBlock from 'components/atoms/RTTable/RTTRowBlock';
import axios from 'axios';

function Panel3(props) {
const [tableBlockRowElements, setTableBlockRowElements] = useState([]);
const [tableTxRowElements, setTableTxRowElements] = useState([]);
const blockSpeed = 30 * 1000; // in seconds
let lastBlock = 0;
const MAX_ROWS = 6;
const CHANNELS = { 0: 'Stake', 1: 'Prime', 2: 'Hash' };

function addNewBlockRow(newRowData) {
//console.log('adding block ' + newRowData.height);
lastBlock = newRowData.height;
const newRow = (
<RTTRowBlock
key={newRowData.height}
block={newRowData.height}
mint={newRowData.mint}
txns={newRowData.tx.length}
size={newRowData.size}
channel={`Channel: ${CHANNELS[newRowData.channel]}`}
/>
);
setTableBlockRowElements((tableBlockRowElements) => [
newRow,
...tableBlockRowElements.slice(0, MAX_ROWS - 1),
]);
}

function addNewTxRow(newRowData) {
//console.log('adding txn ');
//console.log(newRowData);

const newRow = (
<RTTRow
fromId={newRowData[0]?.contracts[0].from}
toId={newRowData[0]?.contracts[0].to}
txnId={newRowData[0]?.txid}
operation={newRowData[0]?.contracts[0].OP}
txType={newRowData[0]?.type}
amount={newRowData[0]?.contracts[0].amount}
confirmations={newRowData[0]?.confirmations}
contracts={newRowData[0]?.contracts.length}
/>
);
setTableTxRowElements((tableBlockRowElements) => [
newRow,
...tableBlockRowElements.slice(0, MAX_ROWS - 1),
]);
}

async function handleAddRow() {
const latestBlockUrl = `${process.env.NEXT_PUBLIC_NEXUS_BASE_URL}/latestBlock`;
const latestBlockResp = await axios.get(latestBlockUrl);
const newRowData = latestBlockResp.data;
// FIXME: when using state for lastblock the if block fails (state out of sync) , currently fixed using let
if (lastBlock != newRowData.height) {
addNewBlockRow(newRowData);
addNewTxRow(newRowData.tx);
}
}

async function loadTable(limit) {
const recentBlocksUrl = `${process.env.NEXT_PUBLIC_NEXUS_BASE_URL}/ledger/list/blocks?verbose=summary&limit=${limit}`;
const resp = await axios.get(recentBlocksUrl);
const newBlocksData = resp.data.result;
//console.log(newBlocksData);
// TODO:
// Ignore the txs with type=tritium base
// If type=legacy user , then show the input field as from and output as to
// If type=tritium user, then show
// If the tx has from and to fields in the contracts and then display if they exist , otherwise ignore

newBlocksData.reverse().map((block) => {
addNewBlockRow(block);
addNewTxRow(block.tx);
block.tx.forEach((txn) => {
// addNewContractRow(txn);
if (txn.type === 'tritium base') {
//console.log('tritium base txn');
}
// else if()
});
});
}

useEffect(() => {
// TODO: fetch 6 latest blocks using limit
loadTable(6);
}, []);

useEffect(() => {
const interval1 = setInterval(handleAddRow, blockSpeed);
return () => {
clearInterval(interval1);
};
}, []);

return (
<div className={styles.container}>
<RTTable label="Recent Blocks">{tableBlockRowElements}</RTTable>
<RTTable label="Recent Transactions">{tableTxRowElements}</RTTable>
</div>
);
}

export default Panel3;

/*
TODO:
* load 10 rows data on first page load
* Fetch latestBlock from api in useEffect to load new rows
* Clear the tableRows if it excees MAXROWS

*/
5 changes: 5 additions & 0 deletions src/components/Panel3/Panel3.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.container {
display: flex;
min-height: 25rem;
gap: 2rem;
}
48 changes: 48 additions & 0 deletions src/components/atoms/RTTable/RTTRow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styles from './RTTRow.module.css';

function RTTRow(props) {
const {
fromId,
toId,
txnId,
operation,
txType,
amount,
confirmations,
contracts,
} = props;

return (
<div className={styles.rttrow}>
<div className={styles.rttrowTop}>
<div className={styles.fromTag}>
<div className={styles.tagText}>From:{fromId}</div>
</div>
<div className={styles.toTag}>
<div className={styles.tagText}>To: {toId}</div>
</div>
</div>
<div className={styles.rttrowBottom}>
<div className={styles.rttrowName}>{operation}</div>
<div className={styles.txnType}>
{txType}
<div className={styles.lowerThirdText}>type</div>
</div>
<div className={styles.txnId}>
<div className={styles.txnIdValue}>{txnId}</div>
<div className={styles.lowerThirdText}>txn_id</div>
</div>

<div className={styles.txnAmount}>
{amount}NXS<div className={styles.lowerThirdText}>amount</div>
</div>
<div className={styles.confirmations}>
Confirmations: {confirmations}
</div>
<div className={styles.contracts}>Contracts: {contracts}</div>
</div>
</div>
);
}

export default RTTRow;
126 changes: 126 additions & 0 deletions src/components/atoms/RTTable/RTTRow.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
.rttrow {
position: relative;
width: 524px;
height: 52px;
background: var(--theme-page-background);
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
border-radius: 4px;
margin-bottom: 2px;
display: flex;
flex-direction: column;
overflow: hidden;
}

.rttrowTop {
height: 18px;
}
.rttrowBottom {
display: grid;
display: -ms-grid;
grid-template-columns: 1rem repeat(3, 1fr) auto auto;
-ms-grid-columns: 1rem repeat(5, 1fr);
align-items: center;
justify-content: start;
grid-gap: 4px;
}

.fromTag,
.toTag {
position: absolute;
width: 178px;
height: 18px;
left: 3.44%;
top: 0%;
bottom: 67.31%;
/* Midnight Blue */
background: var(--theme-page-not-background);
border-radius: 2px;
/* truncate text */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
overflow: hidden;
}

.toTag {
left: 62.6%;
right: 3.44%;
}

.tagText {
font-family: Lato;
font-size: var(--font-xs);
text-align: center;
line-height: 1.6;
color: var(--white);
}

.rttrowName {
font-family: 'Lato';
font-weight: normal;
font-size: var(--font-xs);
/* Ocean Blue */
color: var(--theme-page-text-secondary);
transform: rotate(-90deg) translateX(-8px);
}

.txnType {
position: relative;
font-family: Lato;
font-style: normal;
font-weight: normal;
font-size: 12px;
line-height: 14px;
color: var(--theme-page-text);
}
.lowerThirdText {
position: absolute;
bottom: 0;
top: 100%;
right: 4%;
font-size: var(--font-xxs);
text-align: right;
}

.txnId {
position: relative;
font-family: Lato;
font-size: var(--font-s);
color: var(--theme-page-text);
}
.txnIdValue {
/* truncate text */
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
overflow: hidden;
}

.txnAmount {
position: relative;
font-family: Lato;
font-weight: normal;
font-size: var(--font-s);
color: var(--theme-page-text);
}

.confirmations {
/* Confirmations: 7 */
font-family: Lato;
font-style: normal;
font-weight: normal;
font-size: 10px;
line-height: 12px;
color: var(--theme-page-text);
}

.contracts {
font-family: Lato;
font-style: normal;
font-weight: normal;
font-size: 10px;
line-height: 12px;
margin-right: 8px;
color: var(--theme-page-text);
}
37 changes: 37 additions & 0 deletions src/components/atoms/RTTable/RTTRowBlock.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import styles from './RTTRowBlock.module.css';

function RTTRowBlock(props) {
const { block, channel, utc, date, mint, size, txns } = props;
return (
<div className={styles.container}>
<div className={styles.cardType}>BLOCK</div>
<div className={styles.cardTag}>
<div className={styles.carTagName}>{channel}</div>
</div>
<div className={styles.dataCotainer}>
<div className={styles.blockNumber}>{block}</div>
<div className={styles.time}>
<div className={styles.timeInUTC}>
<span className={styles.timeUnit}>UTC</span>
<span>{utc}</span>
</div>
<div className={styles.date}>{date}</div>
</div>
<div className={styles.mint}>
<span>{mint}</span>
<div className={styles.labelUnit}>mint</div>
</div>
<div className={styles.size}>
<span>{size}</span>
<div className={styles.labelUnit}>size</div>
</div>
<div className={styles.txns}>
<span>{txns}</span>
<div className={styles.labelUnit}>txns</div>
</div>
</div>
</div>
);
}

export default RTTRowBlock;
Loading