import React from 'react';
import { Pane, Text } from '@cybercongress/gravity';
import { connect } from 'react-redux';
import withRouter from 'src/components/helpers/withRouter';

import withDevice from 'src/components/helpers/withDevice';
import ValidatorInfo from './validatorInfo';
import {
  getValidatorsInfo,
  stakingPool,
  selfDelegationShares,
  getDelegators,
} from '../../utils/search/utils';
import { fromBech32, trimString } from '../../utils/utils';
import { Loading, Copy, Tabs } from '../../components';
import Delegated from './delegated';
import Fans from './fans';
import NotFound from '../application/notFound';
import ActionBarContainer from '../Validators/ActionBarContainer';
import Leadership from './leadership';
import Rumors from './rumors';
import { MusicalAddress } from '../portal/components';
import Loader2 from 'src/components/ui/Loader2';

const mapTabs = [
  { key: 'fans', to: 'fans' },
  { key: 'main', to: '' },
  { key: 'rumors', to: 'rumors' },
  { key: 'leadership', to: 'leadership' },
];

class ValidatorsDetails extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      validatorInfo: [],
      // eslint-disable-next-line react/no-unused-state
      data: {},
      delegated: {},
      loader: true,
      error: false,
      fans: [],
      addressPocket: null,
      unStake: false,
    };
  }

  async componentDidMount() {
    await this.checkAddressLocalStorage();
    this.init();
    // this.chekPathname();
  }

  componentDidUpdate(prevProps) {
    const {
      router: {
        location: { pathname },
      },
      defaultAccount,
    } = this.props;
    if (prevProps.router.location.pathname !== pathname) {
      this.init();
    }

    if (prevProps.defaultAccount.name !== defaultAccount.name) {
      this.updateAddressLocalStorage();
    }
  }

  updateAddressLocalStorage = async () => {
    this.setState({ loader: true, unStake: false });
    await this.checkAddressLocalStorage();
    await this.init();
  };

  init = async () => {
    // this.setState({ loader: true });
    await this.getValidatorInfo();
    this.getDelegators();
  };

  checkAddressLocalStorage = async () => {
    const { defaultAccount } = this.props;
    const { account } = defaultAccount;
    if (
      account !== null &&
      Object.prototype.hasOwnProperty.call(account, 'cyber')
    ) {
      this.setState({ addressPocket: account.cyber });
    } else {
      this.setState({
        addressPocket: null,
      });
    }
  };

  update = async () => {
    await this.getValidatorInfo();
    this.getDelegators();
  };

  // eslint-disable-next-line class-methods-use-this
  getSupply = async () => {
    const bondedTokens = await stakingPool();
    return bondedTokens.bonded_tokens;
  };

  // eslint-disable-next-line class-methods-use-this
  getDelegated = async (delegatorShares, delegateAddress, operatorAddress) => {
    const data = {
      self: 0,
      selfPercent: 0,
      others: 0,
      othersPercent: 0,
    };

    const getSelfDelegation = await selfDelegationShares(
      delegateAddress,
      operatorAddress
    );

    if (getSelfDelegation && delegatorShares > 0) {
      const selfPercent = (getSelfDelegation / delegatorShares) * 100;

      data.self = parseFloat(getSelfDelegation);
      data.selfPercent = selfPercent;
      data.others = parseFloat(delegatorShares);
      data.othersPercent = 100 - selfPercent;
    }

    return data;
  };

  getValidatorInfo = async () => {
    const {
      router: {
        params: { address },
      },
    } = this.props;

    const resultStakingPool = await this.getSupply();
    const result = await getValidatorsInfo(address);

    if (result === null) {
      return this.setState({ error: true, loader: false });
    }

    const delegateAddress = fromBech32(result.operator_address);

    const votingPower = (result.tokens / resultStakingPool) * 100;
    const delegated = await this.getDelegated(
      result.delegator_shares,
      delegateAddress,
      result.operator_address
    );

    return this.setState({
      validatorInfo: {
        delegateAddress,
        ...result,
        votingPower,
      },
      delegated: {
        total: parseFloat(result.tokens),
        delegateAddress,
        jailed: result.jailed,
        unbondingTime: result.unbonding_time,
        unbondingHeight: result.unbonding_height,
        delegatorShares: result.delegator_shares,
        ...delegated,
        ...result,
      },
    });
  };

  getDelegators = async () => {
    const {
      router: { params },
    } = this.props;
    const { address } = params;
    const { validatorInfo, addressPocket, unStake } = this.state;

    let fans = [];

    const data = await getDelegators(address);

    if (data !== null) {
      fans = data.result;
      // TODO: refactor
      Object.keys(fans).forEach((key) => {
        if (unStake === false) {
          if (addressPocket !== null) {
            if (
              fans[key].delegation.delegator_address === addressPocket.bech32
            ) {
              this.setState({
                unStake: true,
              });
            }
          }
        }
        fans[key].share =
          parseFloat(fans[key].balance.amount) /
          Math.floor(parseFloat(validatorInfo.delegator_shares));
      });
    }

    this.setState({
      fans,
      loader: false,
    });
  };

  render() {
    const {
      validatorInfo,
      loader,
      delegated,
      fans,
      error,
      addressPocket,
      unStake,
    } = this.state;
    const {
      router: { params },
    } = this.props;

    const { address, tab } = params;

    if (loader) {
      return (
        <div
          style={{
            height: '50vh',
          }}
        >
          <Loader2 />
        </div>
      );
    }

    if (error) {
      return <NotFound />;
    }

    return (
      <div>
        <main className="block-body">
          <Pane
            marginBottom={40}
            display="flex"
            justifyContent="center"
            alignItems="center"
          >
            <MusicalAddress address={validatorInfo.operator_address} />
          </Pane>
          <ValidatorInfo data={validatorInfo} marginBottom={20} />
          <Tabs
            selected={tab || 'main'}
            options={mapTabs.map((item) => ({
              key: item.key,
              to: `/network/bostrom/hero/${address}/${item.to}`,
            }))}
          />
          <Pane
            display="flex"
            marginTop={20}
            marginBottom={50}
            justifyContent="center"
            flexDirection="column"
          >
            {!tab && <Delegated data={delegated} />}
            {tab === 'fans' && <Fans data={fans} />}
            {tab === 'rumors' && (
              <Rumors accountUser={validatorInfo.operator_address} />
            )}
            {tab === 'leadership' && (
              <Leadership accountUser={validatorInfo.delegateAddress} />
            )}
          </Pane>
        </main>
        <ActionBarContainer
          updateTable={this.update}
          validators={validatorInfo}
          unStake={unStake}
          addressPocket={addressPocket}
        />
      </div>
    );
  }
}

const mapStateToProps = (store) => {
  return {
    defaultAccount: store.pocket.defaultAccount,
  };
};

export default connect(mapStateToProps)(
  withDevice(withRouter(ValidatorsDetails))
);

Synonyms

pussy-ts/src/containers/wasm/index.jsx
pussy-ts/src/containers/trollBox/index.jsx
cyb/src/containers/movie/index.jsx
cyb/src/components/battery/index.jsx
cyb/src/components/vitalik/index.jsx
pussy-ts/src/containers/oracle/index.jsx
cyb/src/containers/wasm/index.jsx
cyb/src/components/ButtonNetwork/index.jsx
pussy-ts/src/containers/blok/index.jsx
pussy-ts/src/components/battery/index.jsx
cyb/src/components/searchSnippet/index.jsx
pussy-ts/src/containers/Objects/index.jsx
cyb/src/containers/parameters/index.jsx
pussy-ts/src/containers/parameters/index.jsx
pussy-ts/src/containers/market/index.jsx
cyb/src/containers/oracle/index.jsx
cyb/src/components/particle/index.jsx
pussy-ts/src/components/numberCurrency/index.jsx
cyb/src/components/numberCurrency/index.jsx
pussy-ts/src/containers/testKeplre/index.jsx
pussy-ts/src/components/valueImg/index.jsx
pussy-ts/src/components/ButtonNetwork/index.jsx
pussy-ts/src/containers/network/index.jsx
pussy-ts/src/components/particle/index.jsx
pussy-ts/src/containers/movie/index.jsx
cyb/src/containers/market/index.jsx
pussy-ts/src/containers/help/index.jsx
pussy-ts/src/components/statusTooltip/index.jsx
cyb/src/containers/help/index.jsx
pussy-ts/src/components/vitalik/index.jsx
cyb/src/containers/testPage/index.jsx
pussy-ts/src/components/searchSnippet/index.jsx
cyb/src/components/valueImg/index.jsx
cyb/src/components/statusTooltip/index.jsx
cyb/src/containers/trollBox/index.jsx
pussy-ts/src/containers/Validators/components/index.jsx
pussy-ts/src/containers/portal/stateComponent/index.jsx
pussy-ts/src/containers/parameters/tabs/index.jsx
pussy-ts/src/containers/wasm/codes/index.jsx
pussy-ts/src/containers/wasm/contract/index.jsx
cyb/src/containers/wasm/contract/index.jsx
cyb/src/containers/portal/stateComponent/index.jsx
cyb/src/containers/parameters/tabs/index.jsx
cyb/src/containers/temple/components/canvasOne/index.jsx
cyb/src/containers/wasm/contract/renderAbi/index.jsx
cyb/src/containers/wasm/codes/code/index.jsx
pussy-ts/src/containers/portal/components/progressCard/index.jsx
pussy-ts/src/containers/temple/components/canvasOne/index.jsx
pussy-ts/src/containers/portal/components/ActionBar/index.jsx
cyb/src/containers/wasm/codes/codePage/index.jsx
pussy-ts/src/containers/portal/components/nextUnfreeze/index.jsx
pussy-ts/src/containers/portal/components/Released/index.jsx
cyb/src/containers/portal/components/progressCard/index.jsx
cyb/src/containers/portal/components/currentGift/index.jsx
pussy-ts/src/containers/wasm/codes/code/index.jsx
pussy-ts/src/containers/wasm/contract/renderAbi/index.jsx
pussy-ts/src/containers/portal/components/currentGift/index.jsx
cyb/src/containers/portal/components/Released/index.jsx
cyb/src/containers/portal/components/imgNetwork/index.jsx
pussy-ts/src/containers/portal/components/imgNetwork/index.jsx
pussy-ts/src/containers/energy/ui/card/index.jsx
pussy-ts/src/containers/wasm/codes/codePage/index.jsx
cyb/src/containers/portal/components/nextUnfreeze/index.jsx
cyb/src/containers/energy/ui/card/index.jsx
pussy-ts/src/containers/sigma/components/cardUi/ChartTotal/index.jsx
pussy-ts/src/containers/sigma/components/cardUi/DetailsBalance/index.jsx
pussy-ts/src/containers/sigma/components/cardUi/BtnArrow/index.jsx
cyb/src/containers/sigma/components/cardUi/ChartTotal/index.jsx
cyb/src/containers/sigma/components/cardUi/BtnArrow/index.jsx
cyb/src/containers/sigma/components/cardUi/DetailsBalance/index.jsx

Neighbours