polkadot-js/apps

View on GitHub
packages/page-nis/src/Overview/BidAdd.tsx

Summary

Maintainability
C
1 day
Test Coverage
// Copyright 2017-2024 @polkadot/app-nis authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { BN } from '@polkadot/util';

import React, { useMemo, useState } from 'react';

import { Button, InputAddress, InputBalance, InputNumber, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useToggle } from '@polkadot/react-hooks';
import { Available } from '@polkadot/react-query';
import { BN_ONE } from '@polkadot/util';

import { useTranslation } from '../translate.js';

interface Props {
  className?: string;
  isDisabled?: boolean;
  proxies: Record<string, string[]>;
}

function Bid ({ className, isDisabled, proxies }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const { api } = useApi();
  const [isOpen, toggleOpen] = useToggle();
  const [accountId, setAccountId] = useState<string | null>(null);
  const [proxyId, setProxyId] = useState<string | null>(null);
  const [amount, setAmount] = useState<BN | undefined>();
  const [duration, setDuration] = useState<BN | undefined>();

  const tx = useMemo(
    () => accountId && amount && duration
      ? api.tx.proxy.proxy(accountId, null, api.tx.nis.placeBid(amount, duration))
      : null,
    [api, accountId, amount, duration]
  );

  const proxiedAccounts = Object.keys(proxies);
  const isAmountError = !amount || amount.isZero() || amount.lt(api.consts.nis.minBid);
  const isDurationError = !duration || !duration.gte(BN_ONE) || duration.gt(api.consts.nis.queueCount);

  return (
    <>
      <Button
        icon='plus'
        isDisabled={!proxiedAccounts.length || isDisabled}
        label={t('Bid via Proxy')}
        onClick={toggleOpen}
      />
      {isOpen && (
        <Modal
          className={className}
          header={t('submit nis bid')}
          onClose={toggleOpen}
          size='large'
        >
          <Modal.Content>
            <Modal.Columns hint={t('This account will make the bid for the nis and pay all associated fees.')}>
              <InputAddress
                filter={proxiedAccounts}
                label={t('use proxied account')}
                labelExtra={
                  <Available
                    label={<span className='label'>{t('transferrable')}</span>}
                    params={accountId}
                  />
                }
                onChange={setAccountId}
                type='account'
              />
              {accountId && (
                <InputAddress
                  filter={proxies[accountId]}
                  label={t('send via proxy')}
                  onChange={setProxyId}
                  type='account'
                />
              )}
            </Modal.Columns>
            <Modal.Columns hint={t('The amount you wish to lock for the duration. It needs to be more than the nis minimum.')}>
              <InputBalance
                autoFocus
                defaultValue={api.consts.nis.minBid}
                isError={isAmountError}
                isZeroable={false}
                label={t('bid amount')}
                onChange={setAmount}
              />
              <InputBalance
                defaultValue={api.consts.nis.minBid}
                isDisabled
                label={t('minimum bid amount')}
              />
            </Modal.Columns>
            <Modal.Columns hint={t('The number of periods this bid is to be locked for, less than the maximum period.')}>
              <InputNumber
                defaultValue={BN_ONE}
                isError={isDurationError}
                isZeroable={false}
                label={t('lock periods')}
                onChange={setDuration}
              />
              <InputNumber
                defaultValue={api.consts.nis.queueCount}
                isDisabled
                label={t('maximum lock periods')}
              />
              {!isDurationError && (
                <InputNumber
                  defaultValue={api.consts.nis.basePeriod.mul(duration)}
                  isDisabled
                  label={t('length of lock (blocks, calculated)')}
                />
              )}
            </Modal.Columns>
          </Modal.Content>
          <Modal.Actions>
            <TxButton
              accountId={proxyId}
              extrinsic={tx}
              icon='check'
              isDisabled={isAmountError || isDurationError || !accountId}
              label={t('Bid')}
              onStart={toggleOpen}
            />
          </Modal.Actions>
        </Modal>
      )}
    </>
  );
}

export default React.memo(Bid);