import React, { useEffect, useMemo } from 'react';
import { useTable, useSortBy } from 'react-table';
import { SsnStatus, Role, ContractState, OperationStatus } from '../util/enum';
import { convertToProperCommRate, convertQaToCommaStr, computeStakeAmtPercent, getTruncatedAddress, computeTotalStakeAmt } from '../util/utils';
import { SsnStats, StakeModalData } from '../util/interface';
import ReactTooltip from 'react-tooltip';
import { useAppDispatch, useAppSelector } from '../store/hooks';
import SpinnerNormal from './spinner-normal';
import { UPDATE_STAKE_MODAL_DATA } from '../store/userSlice';
function Table({ columns, data, tableId, hiddenColumns, showStakeBtn }: any) {
// showStakeBtn is true means displaying for delegators
// for delegators view, don't sort by stake amount
let tempInitialState = {};
if (showStakeBtn) {
// deleg view
// don't sort by stake amount to prevent users from staking the top most everytime
tempInitialState = {
pageIndex: 0,
hiddenColumns: hiddenColumns,
sortBy: [
{
id: 'name',
desc: false
}
]
}
} else {
// default sort by stake amt
tempInitialState = {
pageIndex: 0,
hiddenColumns: hiddenColumns,
sortBy: [
{
id: 'stakeAmt',
desc: true
}
]
}
}
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable(
{
columns,
data,
initialState: tempInitialState
}, useSortBy);
return (
<>
{headerGroups.map(headerGroup => (
{headerGroup.headers.map((column, index) => (
|
{
column.render('tipText') === '' ?
column.render('Header') :
{column.render('Header')}
}
|
))}
))}
{rows.map((row, i) => {
prepareRow(row)
return (
{row.cells.map(cell => {
return | {cell.render('Cell')} |
})}
)
})}
>
);
}
function SsnTable(props: any) {
const dispatch = useAppDispatch();
const role = useAppSelector(state => state.user.role);
const loading: OperationStatus = useAppSelector(state => state.staking.is_ssn_stats_loading);
const ssnList: SsnStats[] = useAppSelector(state => state.staking.ssn_list);
const showStakeBtn = props.showStakeBtn ? props.showStakeBtn : false; // for deleg
const totalStakeAmt = computeTotalStakeAmt(ssnList);
const handleStake = (name: string, address: string, commRate: string) => {
// set dashboard state variable
dispatch(UPDATE_STAKE_MODAL_DATA({
stake_modal: {
ssnName: name,
ssnAddress: address,
commRate: commRate,
} as StakeModalData
}));
}
var array = [...ssnList];
array= array.sort((a, b) => parseInt(b.stakeAmt) - parseInt(a.stakeAmt));
const columns = useMemo(
() => [
{
Header: 'name',
accessor: 'name',
tipText: ''
},
{
Header: 'address',
accessor: 'address',
className: 'ssn-address',
Cell: ({ row }: any) =>
<>
{getTruncatedAddress(row.original.address)}
>,
tipText: ''
},
{
Header: 'api endpoint',
accessor: 'apiUrl',
Cell: ({ row }: any) => {row.original.apiUrl},
tipText: 'Service API running by operator. Can be used as alternatives for Zilliqa API endpoint'
},
{
Header: 'stake amount (ZIL)',
accessor: 'stakeAmt',
Cell: ({ row }: any) =>
<>
{convertQaToCommaStr(row.original.stakeAmt)} ({computeStakeAmtPercent(row.original.stakeAmt, totalStakeAmt).toFixed(2)}%)
>,
tipText: 'Total amount being staked with this operator'
},
{
Header: 'buffered deposit (ZIL)',
accessor: 'bufferedDeposits',
Cell: ({ row }: any) =>
<>
{convertQaToCommaStr(row.original.bufferedDeposits)}
>,
tipText: 'Total staked amount deposited in this cycle being considered for rewards in the next cycle'
},
{
Header: 'Comm. Rate (%)',
accessor: 'commRate',
Cell: ({ row }: any) =>
{convertToProperCommRate(row.original.commRate).toFixed(2)},
tipText: 'Percentage of incoming rewards that the operator takes as commission'
},
{
Header: 'Comm. Reward (ZIL)',
accessor: 'commReward',
Cell: ({ row }: any) =>
{convertQaToCommaStr(row.original.commReward)},
tipText: 'Number of ZILs earned as commission by the operator'
},
{
Header: 'Delegators',
accessor: 'delegNum',
tipText: 'Total number of delegators staking with this operator'
},
{
Header: 'Status',
accessor: 'status',
Cell: ({ row }: any) =>
<>
{
row.original.status === SsnStatus.INACTIVE ?
<>Below
Min. Stake> :
row.original.status
}
>,
tipText: 'Determines whether the operator has met the minnimum stake amount and therefore ready to participate in staking and receive rewards'
},
{
Header: 'Stake',
accessor: 'stake',
Cell: ({ row }: any) =>
<>
>,
tipText: ''
}
// eslint-disable-next-line
], [array, role]
)
const getHiddenColumns = () => {
// hide redudant info for certain group of users, e.g. commission reward
// list the hidden column accessor names
let hiddenColumns = ["address"];
if (role !== undefined && role === Role.DELEGATOR && ContractState.IS_PAUSED.toString() !== 'true') {
hiddenColumns.push("commReward", "apiUrl");
} else if (role !== undefined && role === Role.DELEGATOR && ContractState.IS_PAUSED.toString() === 'true') {
// hide stake button if contract state is paused
hiddenColumns.push("stake");
}
if (showStakeBtn === false || role === Role.OPERATOR) {
hiddenColumns.push("stake");
}
return hiddenColumns;
}
return (
<>
{
loading === OperationStatus.PENDING &&
}
{
loading === OperationStatus.COMPLETE &&
}
>
);
}
export default SsnTable;