All files / app/components/home balance-card.tsx

0% Statements 0/28
0% Branches 0/15
0% Functions 0/3
0% Lines 0/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                                                                                                                                                                                                                                   
import { InternalLink } from '@components/internal-link';
import { Title } from '@components/title';
import { features, NETWORK } from '@constants/index';
import { useBalance } from '@hooks/use-balance';
import { Box, Button, Text, ArrowIcon, EncryptionIcon, Flex, color } from '@stacks/ui';
import { delay } from '@utils/delay';
import { makeExplorerAddressLink } from '@utils/external-links';
import { isTestnet } from '@utils/network-utils';
import { safeAwait } from '@utils/safe-await';
import { toHumanReadableStx } from '@utils/unit-convert';
import { HomeSelectors } from 'app/tests/features/home.selectors';
import React, { FC, useState } from 'react';
 
interface BalanceCardProps {
  address: string | null;
  onSelectSend(): void;
  onSelectReceive(): void;
  onRequestTestnetStx({ stacking }: { stacking: boolean }): Promise<any>;
}
 
export const BalanceCard: FC<BalanceCardProps> = props => {
  const { address, onSelectReceive, onSelectSend, onRequestTestnetStx } = props;
 
  const [requestingTestnetStx, setRequestingTestnetStx] = useState(false);
  const { availableBalance, lockedBalance, totalBalance } = useBalance();
 
  const requestTestnetStacks = async (e: React.MouseEvent) => {
    Iif (NETWORK !== 'testnet') return;
    Iif (e.nativeEvent) setRequestingTestnetStx(true);
    const [error] = await safeAwait(
      Promise.all([onRequestTestnetStx({ stacking: e.nativeEvent.altKey }), delay(1500)])
    );
    Iif (error) {
      window.alert('Faucet request failed');
    }
    setRequestingTestnetStx(false);
  };
 
  return (
    <Box>
      <Flex>
        <Text textStyle="body.large.medium" display="block">
          Total balance
        </Text>
 
        {address !== null && (
          <InternalLink href={makeExplorerAddressLink(address)} textStyle="caption" ml="tight">
            View on Explorer
          </InternalLink>
        )}
      </Flex>
      <Title fontSize="40px" lineHeight="56px">
        {totalBalance === null ? '–' : toHumanReadableStx(totalBalance.toString())}
      </Title>
 
      {features.stacking && lockedBalance !== null && lockedBalance.isGreaterThan(0) && (
        <Flex
          alignItems="center"
          mt="tight"
          color={color('text-caption')}
          fontSize={['14px', '16px']}
        >
          <EncryptionIcon
            size="16px"
            color={color('feedback-alert')}
            display={['none', 'block']}
            mr="tight"
          />
          <Text>{toHumanReadableStx(lockedBalance.toString())} locked</Text>
          <Text mx="base-tight">·</Text>
          <Text>{toHumanReadableStx(availableBalance.toString())} available</Text>
        </Flex>
      )}
      <Box mt="loose">
        <Button
          size="md"
          onClick={onSelectSend}
          isDisabled={availableBalance.isEqualTo(0)}
          data-test={HomeSelectors.BtnSend}
        >
          <ArrowIcon size="12px" {...({ direction: 'up' } as any)} mr="base-tight" />
          Send
        </Button>
        <Button size="md" ml="tight" onClick={onSelectReceive} data-test={HomeSelectors.BtnReceive}>
          <ArrowIcon size="12px" {...({ direction: 'down' } as any)} mr="base-tight" />
          Receive
        </Button>
        {isTestnet() && (
          <Button
            mode="secondary"
            size="md"
            ml="tight"
            isDisabled={requestingTestnetStx}
            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
            onClick={e => requestTestnetStacks(e)}
            title="Hold alt to request more STX. Use sparingly."
          >
            <Box
              mr="tight"
              fontSize="14px"
              left="-4px"
              position="relative"
              display={['none', 'none', 'block']}
            >
              🚰
            </Box>
            {requestingTestnetStx ? 'Requesting faucet' : 'Get testnet STX'}
          </Button>
        )}
      </Box>
    </Box>
  );
};