@chakra-ui/icons#SettingsIcon TypeScript Examples

The following examples show how to use @chakra-ui/icons#SettingsIcon. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ElementListItem.tsx    From openchakra with MIT License 5 votes vote down vote up
ElementListItem = forwardRef(
  (
    {
      type,
      opacity = 1,
      onSelect,
      onMouseOut,
      onMouseOver,
      draggable,
      name,
    }: Props,
    ref: React.Ref<HTMLDivElement>,
  ) => {
    return (
      <Box
        boxSizing="border-box"
        transition="margin 200ms"
        my={1}
        borderRadius="md"
        p={1}
        display="flex"
        alignItems="center"
        cursor={draggable ? 'move' : undefined}
        opacity={opacity}
        ref={ref}
        onMouseOver={onMouseOver}
        onMouseOut={onMouseOut}
      >
        <Flex justify="space-between" align="center" w="100%">
          <Flex align="center">
            {draggable && <ArrowUpDownIcon path="" fontSize="xs" mr={2} />}
            <Text letterSpacing="wide" fontSize="sm" textTransform="capitalize">
              {name || type}
            </Text>
          </Flex>
          <ActionButton
            label="Inspect"
            onClick={onSelect}
            icon={<SettingsIcon path="" />}
            colorScheme="blackAlpha"
          />
        </Flex>
      </Box>
    )
  },
)
Example #2
Source File: Navbar.tsx    From coindrop with GNU General Public License v3.0 5 votes vote down vote up
UserMenu = () => {
    const { colorMode, toggleColorMode } = useColorMode();
    const { logout } = useUser();
    return (
        <Menu placement="bottom-end">
            <MenuButton as={Button} variant="ghost">
                <HamburgerMenuIcon />
            </MenuButton>
            <MenuList>
                <NextLink href="/account">
                    <MenuItem>
                        <Flex
                            align="center"
                        >
                            <SettingsIcon mr={2} />
                            My Account
                        </Flex>
                    </MenuItem>
                </NextLink>
                {/* This is an external link to ensure Ecwid scripts run on page changes */}
                {/* Should figure out a way to trigger the scripts manually within /shop */}
                {/* <Link href="/shop" style={{textDecoration: "none"}}>
                    <MenuItem>
                        <Flex
                            align="center"
                        >
                            <Icon mr={2} as={AiOutlineShopping} />
                            Shop
                        </Flex>
                    </MenuItem>
                </Link> */}
                <MenuItem
                    onClick={toggleColorMode}
                >
                    <Flex
                        align="center"
                    >
                        {colorMode === 'dark' ? <SunIcon mr={2} /> : <MoonIcon mr={2} />}
                        {colorMode === 'dark' ? 'Light mode' : 'Dark mode'}
                    </Flex>
                </MenuItem>
                <MenuItem
                    onClick={() => {
                        logout();
                    }}
                >
                    <Flex
                        align="center"
                    >
                        <LogoutIcon mr={2} />
                        Log out
                    </Flex>
                </MenuItem>
            </MenuList>
        </Menu>
    );
}
Example #3
Source File: AmountSelect.tsx    From rari-dApp with GNU Affero General Public License v3.0 4 votes vote down vote up
AmountSelect = ({ onClose, mode, openOptions }: Props) => {
  const toast = useToast();

  const queryClient = useQueryClient();

  const [userAction, setUserAction] = useState(UserAction.NO_ACTION);

  const [userEnteredAmount, _setUserEnteredAmount] = useState("");

  const [amount, _setAmount] = useState<BigNumber | null>(
    () => new BigNumber(0)
  );

  const { t } = useTranslation();

  const { rari, address } = useRari();

  const { data: balance } = useTokenBalance(LP_TOKEN_CONTRACT);

  const { data: staked } = useQuery(address + "pool2BalanceBN", () => {
    return rari.governance.rgt.sushiSwapDistributions.stakingBalanceOf(address);
  });

  const updateAmount = (newAmount: string) => {
    if (newAmount.startsWith("-")) {
      return;
    }

    _setUserEnteredAmount(newAmount);

    try {
      BigNumber.DEBUG = true;

      // Try to set the amount to BigNumber(newAmount):
      const bigAmount = new BigNumber(newAmount);
      _setAmount(bigAmount.multipliedBy(10 ** 18));
    } catch (e) {
      // If the number was invalid, set the amount to null to disable confirming:
      _setAmount(null);
    }

    setUserAction(UserAction.NO_ACTION);
  };

  const amountIsValid = (() => {
    if (amount === null || amount.isZero()) {
      return false;
    }

    if (!balance || !staked) {
      return false;
    }

    if (mode === Mode.DEPOSIT) {
      return amount.lte(balance.toString());
    } else {
      return amount.lte(staked.toString());
    }
  })();

  let depositOrWithdrawAlert;

  if (amount === null || amount.isZero()) {
    if (mode === Mode.DEPOSIT) {
      depositOrWithdrawAlert = t("Enter a valid amount to deposit.");
    } else if (mode === Mode.WITHDRAW) {
      depositOrWithdrawAlert = t("Enter a valid amount to withdraw.");
    }
  } else if (!balance) {
    depositOrWithdrawAlert = t("Loading your balance of {{token}}...", {
      token: "ETH-RGT SLP",
    });
  } else if (!amountIsValid) {
    depositOrWithdrawAlert = t("You don't have enough {{token}}.", {
      token: "ETH-RGT SLP",
    });
  } else {
    depositOrWithdrawAlert = t("Click confirm to continue!");
  }

  const onConfirm = async () => {
    try {
      setUserAction(UserAction.WAITING_FOR_TRANSACTIONS);

      //@ts-ignore
      const amountBN = rari.web3.utils.toBN(amount!.decimalPlaces(0));

      if (mode === Mode.DEPOSIT) {
        await rari.governance.rgt.sushiSwapDistributions.deposit(amountBN, {
          from: address,
        });
      } else {
        await rari.governance.rgt.sushiSwapDistributions.withdraw(amountBN, {
          from: address,
        });
      }

      queryClient.refetchQueries();
      // Wait 2 seconds for refetch and then close modal.
      // We do this instead of waiting the refetch because some refetches take a while or error out and we want to close now.
      await new Promise((resolve) => setTimeout(resolve, 2000));
      onClose();
    } catch (e) {
      handleGenericError(e, toast);
      setUserAction(UserAction.NO_ACTION);
    }
  };

  return userAction === UserAction.WAITING_FOR_TRANSACTIONS ? (
    <Column expand mainAxisAlignment="center" crossAxisAlignment="center" p={4}>
      <HashLoader size={70} color={"#929192"} loading />
      <Heading mt="30px" textAlign="center" size="md">
        {t("Check your wallet to submit the transactions")}
      </Heading>
      <Text fontSize="sm" mt="15px" textAlign="center">
        {mode === Mode.DEPOSIT
          ? t("Do not close this tab until you submit both transactions!")
          : t("You may close this tab after submitting the transaction.")}
      </Text>
    </Column>
  ) : (
    <>
      <Row
        width="100%"
        mainAxisAlignment="space-between"
        crossAxisAlignment="center"
        p={4}
      >
        <Box width="40px" />
        <Heading fontSize="27px">
          {mode === Mode.DEPOSIT ? t("Deposit") : t("Withdraw")}
        </Heading>
        <IconButton
          color="#FFFFFF"
          variant="ghost"
          aria-label="Options"
          icon={<SettingsIcon />}
          _hover={{
            transform: "rotate(360deg)",
            transition: "all 0.7s ease-in-out",
          }}
          _active={{}}
          onClick={openOptions}
        />
      </Row>

      <ModalDivider />

      <Column
        mainAxisAlignment="space-between"
        crossAxisAlignment="center"
        p={4}
        height="100%"
      >
        <Text fontWeight="bold" fontSize="sm" textAlign="center">
          <Link
            href="https://www.notion.so/Fees-e4689d7b800f485098548dd9e9d0a69f"
            isExternal
          >
            {depositOrWithdrawAlert}
          </Link>
        </Text>

        <DashboardBox width="100%" height="70px" mt={4}>
          <Row
            p={4}
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            expand
          >
            <AmountInput
              displayAmount={userEnteredAmount}
              updateAmount={updateAmount}
            />

            <TokenNameAndMaxButton updateAmount={updateAmount} mode={mode} />
          </Row>
        </DashboardBox>

        <Button
          mt={4}
          fontWeight="bold"
          fontSize="2xl"
          borderRadius="10px"
          width="100%"
          height="70px"
          bg={"#929192"}
          _hover={{ transform: "scale(1.02)" }}
          _active={{ transform: "scale(0.95)" }}
          color={"#FFF"}
          onClick={onConfirm}
          isLoading={!balance}
          isDisabled={!amountIsValid}
        >
          {t("Confirm")}
        </Button>
      </Column>
    </>
  );
}
Example #4
Source File: AmountSelect.tsx    From rari-dApp with GNU Affero General Public License v3.0 4 votes vote down vote up
AmountSelect = ({
  selectedToken,
  openCoinSelect,
  mode,
  openOptions,
  onClose,
}: Props) => {
  const token = tokens[selectedToken];

  const poolType = usePoolType();

  const { rari, address } = useRari();

  const {
    data: selectedTokenBalance,
    isLoading: isSelectedTokenBalanceLoading,
  } = useTokenBalance(token.address);

  const [userAction, setUserAction] = useState(UserAction.NO_ACTION);

  const [quoteAmount, setQuoteAmount] = useState<null | BN>(null);

  const [userEnteredAmount, _setUserEnteredAmount] = useState("");

  const [amount, _setAmount] = useState<BigNumber | null>(
    () => new BigNumber(0)
  );

  const updateAmount = (newAmount: string) => {
    if (newAmount.startsWith("-")) {
      return;
    }

    _setUserEnteredAmount(newAmount);

    try {
      BigNumber.DEBUG = true;

      // Try to set the amount to BigNumber(newAmount):
      const bigAmount = new BigNumber(newAmount);
      _setAmount(bigAmount.multipliedBy(10 ** token.decimals));
    } catch (e) {
      console.log(e);

      // If the number was invalid, set the amount to null to disable confirming:
      _setAmount(null);
    }

    setUserAction(UserAction.NO_ACTION);
  };

  const { max, isMaxLoading } = useMaxWithdraw(token.symbol);

  const amountIsValid = (() => {
    if (amount === null || amount.isZero()) {
      return false;
    }

    if (mode === Mode.DEPOSIT) {
      if (isSelectedTokenBalanceLoading) {
        return false;
      }

      return amount.lte(selectedTokenBalance!.toString());
    } else {
      if (isMaxLoading) {
        return false;
      }

      return amount.lte(max!.toString());
    }
  })();

  const { t } = useTranslation();

  let depositOrWithdrawAlert;

  if (amount === null) {
    depositOrWithdrawAlert =
      mode === Mode.DEPOSIT
        ? t("Enter a valid amount to deposit.")
        : t("Enter a valid amount to withdraw.");
  } else if (amount.isZero()) {
    if (poolType === Pool.ETH) {
      depositOrWithdrawAlert =
        mode === Mode.DEPOSIT
          ? t("Enter a valid amount to deposit.")
          : t("Enter a valid amount to withdraw.");
    } else {
      depositOrWithdrawAlert =
        mode === Mode.DEPOSIT
          ? t("Choose which token you want to deposit.")
          : t("Choose which token you want to withdraw.");
    }
  } else if (isSelectedTokenBalanceLoading) {
    depositOrWithdrawAlert = t("Loading your balance of {{token}}...", {
      token: selectedToken,
    });
  } else if (!amountIsValid) {
    depositOrWithdrawAlert =
      mode === Mode.DEPOSIT
        ? t("You don't have enough {{token}}.", {
            token: selectedToken,
          })
        : t("You cannot withdraw this much {{token}}.", {
            token: selectedToken,
          });
  } else {
    if (poolType === Pool.YIELD) {
      depositOrWithdrawAlert = t(
        "This pool has withdrawal & interest fees. Click to learn more."
      );
    } else {
      if (mode === Mode.DEPOSIT) {
        depositOrWithdrawAlert = t(
          "This pool has performance fees. Click to learn more."
        );
      } else {
        depositOrWithdrawAlert = t("Click review + confirm to withdraw!");
      }
    }
  }

  const toast = useToast();

  const queryClient = useQueryClient();

  const onConfirm = async () => {
    try {
      const pool = getSDKPool({ rari, pool: poolType });

      //@ts-ignore
      const amountBN = rari.web3.utils.toBN(amount!.decimalPlaces(0));

      // If clicking for the first time:
      if (userAction === UserAction.NO_ACTION) {
        setUserAction(UserAction.REQUESTED_QUOTE);

        let quote: BN;
        let slippage: BN;

        if (mode === Mode.DEPOSIT) {
          const [amountToBeAdded, , _slippage] =
            (await pool.deposits.validateDeposit(
              token.symbol,
              amountBN,
              address,
              true
            )) as BN[];

          quote = amountToBeAdded;
          slippage = _slippage;
        } else {
          const [amountToBeRemoved, , _slippage] =
            (await pool.withdrawals.validateWithdrawal(
              token.symbol,
              amountBN,
              address,
              true
            )) as BN[];

          quote = amountToBeRemoved;
          slippage = _slippage;
        }

        if (slippage) {
          const slippagePercent = (parseInt(slippage.toString()) / 1e18) * 100;
          const formattedSlippage = slippagePercent.toFixed(2) + "%";

          console.log("Slippage of " + formattedSlippage);

          // If slippage is >4% and user does not want to continue:
          if (
            slippagePercent > 4 &&
            !window.confirm(
              t(
                "High slippage of {{formattedSlippage}} for {{token}}, do you still wish to continue with this transaction?",
                { formattedSlippage, token: token.symbol }
              )
            )
          ) {
            setUserAction(UserAction.NO_ACTION);
            return;
          }
        }

        setQuoteAmount(quote);

        setUserAction(UserAction.VIEWING_QUOTE);

        return;
      }

      // They must have already seen the quote as the button to trigger this function is disabled while it's loading:
      // This means they are now ready to start sending transactions:

      setUserAction(UserAction.WAITING_FOR_TRANSACTIONS);

      if (mode === Mode.DEPOSIT) {
        // (Third item in array is approvalReceipt)
        const [, , , depositReceipt] = await pool.deposits.deposit(
          token.symbol,
          amountBN,
          quoteAmount!,
          {
            from: address,
          }
        );

        if (!depositReceipt) {
          throw new Error(
            t(
              "Prices and/or slippage have changed. Please reload the page and try again. If the problem persists, please contact us."
            )
          );
        }
      } else {
        // (Third item in array is withdrawReceipt)
        await pool.withdrawals.withdraw(token.symbol, amountBN, quoteAmount!, {
          from: address,
        });
      }

      queryClient.refetchQueries();
      // Wait 2 seconds for refetch and then close modal.
      // We do this instead of waiting the refetch because some refetches take a while or error out and we want to close now.
      await new Promise((resolve) => setTimeout(resolve, 2000));

      onClose();
    } catch (e) {
      handleGenericError(e, toast);
      setUserAction(UserAction.NO_ACTION);
    }
  };

  return userAction === UserAction.WAITING_FOR_TRANSACTIONS ? (
    <Column expand mainAxisAlignment="center" crossAxisAlignment="center" p={4}>
      <HashLoader size={70} color={token.color} loading />
      <Heading mt="30px" textAlign="center" size="md">
        {mode === Mode.DEPOSIT
          ? t("Check your wallet to submit the transactions")
          : t("Check your wallet to submit the transaction")}
      </Heading>
      <Text fontSize="sm" mt="15px" textAlign="center">
        {mode === Mode.DEPOSIT
          ? t("Do not close this tab until you submit both transactions!")
          : t("You may close this tab after submitting the transaction.")}
      </Text>
      <Text fontSize="xs" mt="5px" textAlign="center">
        {t(
          "Do not increase the price of gas more than 1.5x the prefilled amount!"
        )}
      </Text>
    </Column>
  ) : (
    <>
      <Row
        width="100%"
        mainAxisAlignment="space-between"
        crossAxisAlignment="center"
        p={4}
      >
        <Box width="40px" />
        <Heading fontSize="27px">
          {mode === Mode.DEPOSIT ? t("Deposit") : t("Withdraw")}
        </Heading>
        <IconButton
          color="#FFFFFF"
          variant="ghost"
          aria-label="Options"
          icon={<SettingsIcon />}
          _hover={{
            transform: "rotate(360deg)",
            transition: "all 0.7s ease-in-out",
          }}
          _active={{}}
          onClick={openOptions}
        />
      </Row>
      <ModalDivider />
      <Column
        mainAxisAlignment="space-between"
        crossAxisAlignment="center"
        p={4}
        height="100%"
      >
        <Text fontWeight="bold" fontSize="13px" textAlign="center">
          <Link
            href="https://www.notion.so/Fees-e4689d7b800f485098548dd9e9d0a69f"
            isExternal
          >
            {depositOrWithdrawAlert}
          </Link>
        </Text>
        <DashboardBox width="100%" height="70px">
          <Row
            p={4}
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            expand
          >
            <AmountInput
              selectedToken={selectedToken}
              displayAmount={userEnteredAmount}
              updateAmount={updateAmount}
            />

            <TokenNameAndMaxButton
              openCoinSelect={openCoinSelect}
              selectedToken={selectedToken}
              updateAmount={updateAmount}
              mode={mode}
            />
          </Row>
        </DashboardBox>

        <Button
          fontWeight="bold"
          fontSize="2xl"
          borderRadius="10px"
          width="100%"
          height="70px"
          bg={token.color}
          _hover={{ transform: "scale(1.02)" }}
          _active={{ transform: "scale(0.95)" }}
          color={token.overlayTextColor}
          isLoading={
            isSelectedTokenBalanceLoading ||
            userAction === UserAction.REQUESTED_QUOTE
          }
          onClick={onConfirm}
          isDisabled={!amountIsValid}
        >
          {userAction === UserAction.VIEWING_QUOTE ? t("Confirm") : t("Review")}
        </Button>

        {poolHasDivergenceRisk(poolType) ? (
          <Link
            href="https://www.notion.so/Capital-Allocation-Risks-f4bccf324a594f46b849e6358e0a2464#631d223f598b42e28f9758541c1b1525"
            isExternal
          >
            <Text fontSize="xs" textAlign="center">
              {t(
                "You may experience divergence loss in this pool. Click for more info."
              )}
            </Text>
          </Link>
        ) : null}
      </Column>
      {userAction === UserAction.VIEWING_QUOTE ? (
        <ApprovalNotch color={token.color} mode={mode} amount={quoteAmount!} />
      ) : null}
    </>
  );
}
Example #5
Source File: index.tsx    From engine with MIT License 4 votes vote down vote up
Header = () => (
  <AccordionItem>
    <Heading>
      <AccordionButton _expanded={{ bg: "gray.300", color: "white" }}>
        <Box flex="1" textAlign="left">
          Header
        </Box>
        <AccordionIcon />
      </AccordionButton>
    </Heading>
    <AccordionPanel pb={4}>
      <HStack mb="3">
        <Box w="70%">
          Fill values from a past runtime call, a unit test or auto determine
          values based on observe and update dependencies
        </Box>
        <Box w="30%">
          <Button size="sm" mr="3" mb="2" color="teal">
            Auto
          </Button>
          <Popover>
            <PopoverTrigger>
              <Button size="sm" mr="3" mb="2" color="purple">
                From call
              </Button>
            </PopoverTrigger>
            <PopoverContent>
              <PopoverArrow />
              <PopoverHeader>Runtime call history (5)</PopoverHeader>
              <PopoverCloseButton />
              <PopoverBody>
                <OrderedList>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    23/02/2022 14:15:10.123
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    23/02/2022 14:13:2.130
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    23/02/2022 14:12:41.500
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    23/02/2022 13:21:20.341
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    23/02/2022 12:40:19.983
                  </ListItem>
                </OrderedList>
              </PopoverBody>
            </PopoverContent>
          </Popover>
          <Popover>
            <PopoverTrigger>
              <Button size="sm" color="blue">
                From test
              </Button>
            </PopoverTrigger>
            <PopoverContent>
              <PopoverArrow />
              <PopoverHeader>Tests (100% coverage)</PopoverHeader>
              <PopoverCloseButton />
              <PopoverBody>
                <OrderedList>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    should ensure guards work (30% coverage)
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    should do computation when y is less (70% coverage)
                  </ListItem>
                  <ListItem
                    cursor="pointer"
                    _hover={{
                      color: "teal.500",
                    }}
                  >
                    should reject if y is greater than (64% coverage)
                  </ListItem>
                </OrderedList>
              </PopoverBody>
            </PopoverContent>
          </Popover>
        </Box>
      </HStack>

      <Divider mb="4" />

      <Box mb="4">
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="pie" w="32" />
            <Input defaultValue="3.14" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="http" w="32" />
            <Input defaultValue={`axios from "axios"`} />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input defaultValue="[mock]" bg="black.100" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="operation" w="32" />
            <Input defaultValue="prop.operation" />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input defaultValue="sum" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="foo" w="32" />
            <Input defaultValue="observe.foo.value" />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input defaultValue="123" bg="teal.800" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="bam" w="32" />
            <Input defaultValue="observe.bar.internal.something" />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input defaultValue="321" bg="teal.800" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="updateSome" w="32" />
            <Input defaultValue="update.a.value.somewhere" />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input defaultValue="444" bg="yellow.700" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
        <HStack>
          <InputGroup size="sm" w="70%">
            <InputLeftAddon children="" w="32" />
            <Input placeholder="enter something..." />
          </InputGroup>
          <InputGroup size="sm" w="30%">
            <Input placeholder="sample value" />
            <InputRightAddon children={<SettingsIcon />} cursor="pointer" />
          </InputGroup>
        </HStack>
      </Box>

      <HStack>
        <Text w="70%" size="sm">
          Last run took 14ms
        </Text>
        <ButtonGroup variant="outline" spacing="4">
          <Button size="sm" colorScheme="black">
            Save as test
          </Button>
          <Button size="sm" colorScheme="green" variant="solid">
            Run
          </Button>
        </ButtonGroup>
      </HStack>
    </AccordionPanel>
  </AccordionItem>
)
Example #6
Source File: PublicPiggybankPage.tsx    From coindrop with GNU General Public License v3.0 4 votes vote down vote up
PublicPiggybankPage: FunctionComponent = () => {
    const { query: { piggybankName } } = useRouter();
    const { piggybankDbData } = useContext(PublicPiggybankDataContext);
    const theme = useTheme();
    const { user } = useUser();
    const { colorMode } = useColorMode();
    const accentColorLevelInitial = getAccentColorLevelInitial(colorMode);
    const accentColorLevelHover = getAccentColorLevelHover(colorMode);
    const {
        name,
        website,
        accentColor = "orange",
        verb,
        owner_uid,
    } = piggybankDbData;
    const accentColorInitial = theme.colors[accentColor][accentColorLevelInitial];
    const accentColorHover = theme.colors[accentColor][accentColorLevelHover];
    const pagePaymentMethodsDataEntries = Object.entries(piggybankDbData.paymentMethods ?? {});
    const preferredAddresses = pagePaymentMethodsDataEntries.filter(([, paymentMethodData]: any) => paymentMethodData.isPreferred);
    const otherAddresses = pagePaymentMethodsDataEntries.filter(([, paymentMethodData]: any) => !paymentMethodData.isPreferred);
    const WrapGroup: FunctionComponent = ({ children }) => (
        <Wrap
            justify="center"
        >
            {children}
        </Wrap>
    );

    type PaymentMethodButtonsFromEntriesProps = {
        entries: PaymentMethodDbObjEntry[]
    }
    const PaymentMethodButtonsFromEntries: FunctionComponent<PaymentMethodButtonsFromEntriesProps> = ({ entries }) => (
        <WrapGroup>
            {entries
            .sort(sortArrayByEntriesKeyAlphabetical)
            .map(([paymentMethodId, paymentMethodData]) => (
                <WrapItem key={paymentMethodId}>
                    <PaymentMethodButton
                        key={paymentMethodId}
                        paymentMethod={paymentMethodId}
                        paymentMethodValue={paymentMethodData.address}
                        isPreferred={paymentMethodData.isPreferred}
                        accentColor={accentColor}
                    />
                </WrapItem>
            ))}
        </WrapGroup>
    );
    const piggybankExists = !!owner_uid;
    const initialSetupComplete = name && accentColor && verb && pagePaymentMethodsDataEntries.length > 0;
    return (
        <>
        <NextSeo
            title={`${name ?? piggybankName}'s Coindrop (coindrop.to/${piggybankName})`}
            description={`Send money to ${name} with no fees`}
        />
        <Container
            maxW={theme.breakpoints.lg}
            mx="auto"
        >
            {user?.id
            && user.id === owner_uid
            && (
                <>
                <DataRefetcher />
                <ManagePiggybankBar
                    editButtonOptions={
                        initialSetupComplete
                        ? ({
                            text: 'Configure',
                            color: undefined,
                            icon: <SettingsIcon />,
                        }) : ({
                            text: 'Set up',
                            color: 'green',
                            icon: <SettingsIcon />,
                        })
                    }
                    initialSetupComplete={initialSetupComplete}
                />
                </>
            )}
            {initialSetupComplete ? (
                <Box
                    mb={6}
                >
                    <Box
                        padding="10px"
                        my={2}
                        mx={3}
                    >
                        <Center>
                            <Avatar />
                        </Center>
                        <Heading textAlign="center">
                            Choose a payment method to
                            {` ${verb} `}
                            {website ? (
                                <Link href={website} target="_blank" rel="noreferrer">
                                    <Heading
                                        as="span"
                                        color={accentColorInitial}
                                        textDecoration="underline"
                                        css={css`
                                            &:hover {
                                                color: ${accentColorHover};
                                            }
                                        `}
                                    >
                                            {name}
                                    </Heading>
                                </Link>
                            ) : (
                                <Heading
                                    as="span"
                                    color={accentColorInitial}
                                >
                                        {name}
                                </Heading>
                            )}
                            :
                        </Heading>
                    </Box>
                    <PaymentMethodButtonsFromEntries
                        entries={preferredAddresses}
                    />
                    <PaymentMethodButtonsFromEntries
                        entries={otherAddresses}
                    />
                    <PoweredByCoindropLink />
                </Box>
            ) : (
                <Heading mt={4} textAlign="center">
                    {piggybankExists ? 'This Coindrop has not been set up yet.' : 'This Coindrop does not exist'}
                    {/* TODO: Include action buttons to log in or landing page */}
                </Heading>
            )}
        </Container>
        </>
    );
}