react-feather#Check TypeScript Examples

The following examples show how to use react-feather#Check. 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: DepositSuccess.tsx    From frontend-v1 with GNU Affero General Public License v3.0 6 votes vote down vote up
DepositSuccess: FC<Props> = ({
  depositUrl,
  setShowSuccess,
  setDepositUrl,
  showSuccess,
}) => {
  // Make sure we scroll to top when deposit screen mounts
  useEffect(() => {
    window.scroll(0, 0);
  }, []);
  const message =
    showSuccess === "withdraw" ? "Withdrawal succeeded" : "Deposit succeeded";
  return (
    <div>
      <DepositTopWrapper>
        <SuccessText>{message}</SuccessText>
        <CheckMarkWrapper>
          <Check strokeWidth={5} />
        </CheckMarkWrapper>
      </DepositTopWrapper>
      <DepositBottomWrapper>
        <EtherscanUrl>
          <a target="_blank" href={depositUrl} rel="noreferrer">
            Etherscan <ArrowUpRight width={16} height={16} />
          </a>
        </EtherscanUrl>
        <DepositButton
          onClick={() => {
            setShowSuccess(undefined);
            setDepositUrl("");
          }}
        >
          Close
        </DepositButton>
      </DepositBottomWrapper>
    </div>
  );
}
Example #2
Source File: VariantItem.tsx    From calories-in with MIT License 6 votes vote down vote up
function VariantItem({ name, isSelected, ...rest }: Props) {
  return (
    <Box
      position="relative"
      as="button"
      width="100%"
      textAlign="left"
      borderRadius={4}
      p={3}
      fontSize="sm"
      fontWeight="semibold"
      _hover={{ bg: 'gray.50' }}
      _active={{
        bg: 'gray.100',
      }}
      {...rest}
    >
      <Flex justifyContent="space-between">
        <Text fontSize="md" fontWeight="normal">
          {name}
        </Text>
        {isSelected && (
          <Flex alignItems="center">
            <Check color="green" size={20} />
          </Flex>
        )}
      </Flex>
    </Box>
  )
}
Example #3
Source File: PortionItem.tsx    From calories-in with MIT License 6 votes vote down vote up
function PortionItem({ portion, isSelected, ...rest }: Props) {
  const { unit } = portion

  return (
    <Box
      position="relative"
      as="button"
      width="100%"
      textAlign="left"
      borderRadius={4}
      p={3}
      fontSize="sm"
      fontWeight="semibold"
      _hover={{ bg: 'gray.50' }}
      _active={{
        bg: 'gray.100',
      }}
      {...rest}
    >
      <Flex justifyContent="space-between">
        <Text
          color={isSelected ? 'teal.600' : undefined}
          fontSize="md"
          fontWeight="500"
        >
          {unit}{' '}
          <Text as="span" color={isSelected ? 'teal.600' : 'gray.500'}>
            {getPortionDescription(portion)}
          </Text>
        </Text>
        {isSelected && (
          <Flex alignItems="center">
            <Check color="green" size={20} />
          </Flex>
        )}
      </Flex>
    </Box>
  )
}
Example #4
Source File: FeedPasswordDialog.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export function FeedPasswordDialog({ feedName, onProceed, onCancel, loading }: Props): ReactElement {
  const [password, setPassword] = useState('')

  function onProceedClick() {
    return onProceed(password)
  }

  return (
    <SwarmDialog>
      <Box mb={4}>
        <TitleWithClose onClose={onCancel}>Update Feed</TitleWithClose>
      </Box>
      <Box mb={2}>
        <Typography>Please enter the password for “{feedName}”:</Typography>
      </Box>
      <Box mb={4}>
        <SwarmTextInput
          label="Password"
          name="password"
          onChange={event => {
            setPassword(event.target.value)
          }}
          password
        />
      </Box>
      <ExpandableListItemActions>
        <SwarmButton iconType={Check} onClick={onProceedClick} disabled={loading} loading={loading}>
          Proceed
        </SwarmButton>
        <SwarmButton iconType={X} onClick={onCancel} cancel disabled={loading}>
          Cancel
        </SwarmButton>
      </ExpandableListItemActions>
    </SwarmDialog>
  )
}
Example #5
Source File: index.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export default function Index({ header, title, p, next }: Props): ReactElement {
  const { nodeAddresses, balance } = useContext(Context)
  const navigate = useNavigate()

  if (!balance || !nodeAddresses) {
    return <Loading />
  }

  const disabled = balance.dai.toDecimal.lte(1)

  return (
    <>
      <HistoryHeader>{header}</HistoryHeader>
      <Box mb={4}>
        <TopUpProgressIndicator index={0} />
      </Box>
      <Box mb={2}>
        <Typography style={{ fontWeight: 'bold' }}>{title}</Typography>
      </Box>
      <Box mb={4}>{p}</Box>
      <SwarmDivider mb={4} />
      <Box mb={0.25}>
        <ExpandableListItemKey label="Funding wallet address" value={balance.address} expanded />
      </Box>
      <Box mb={4}>
        <ExpandableListItem label="xDAI balance" value={balance.dai.toSignificantDigits(4)} />
      </Box>
      <Grid container direction="row" justifyContent="space-between">
        <SwarmButton iconType={Check} onClick={() => navigate(next)} disabled={disabled}>
          Proceed
        </SwarmButton>
        {disabled ? <Typography>Please deposit xDAI to the address above in order to proceed.</Typography> : null}
      </Grid>
    </>
  )
}
Example #6
Source File: Checkbox.tsx    From yet-another-generic-startpage with MIT License 6 votes vote down vote up
Checkbox = ({ checked, onChange, label }: CheckboxProps) => {
  const handleChange = () => onChange?.(!checked)
  const handleKeyPress = (key: string) => key === " " && handleChange()

  return (
    <Label onClick={handleChange}>
      <Box
        role="checkbox"
        aria-checked={checked}
        tabIndex={0}
        onKeyPress={event => handleKeyPress(event.key)}
      >
        <Check />
      </Box>
      <LabelText>{label}</LabelText>
    </Label>
  )
}
Example #7
Source File: Confirmation.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export default function Confirmation(): ReactElement {
  const navigate = useNavigate()

  const styles = useStyles()

  return (
    <>
      <HistoryHeader>Connect to the blockchain</HistoryHeader>
      <Grid container direction="column" alignItems="center">
        <Box mb={6}>
          <div className={styles.checkWrapper}>
            <Check size={100} color="#ededed" />
          </div>
        </Box>
        <Box mb={1}>
          <Typography style={{ fontWeight: 'bold' }}>Your node&apos;s RPC endpoint is set up correctly!</Typography>
        </Box>
        <Box mb={4}>
          <Typography align="center">Lastly, you will need to top-up your node wallet.</Typography>
          <Typography align="center">
            If you&apos;re not familiar with cryptocurrencies, you can start with a bank card.
          </Typography>
        </Box>
        <ExpandableListItemActions>
          <SwarmButton iconType={Battery} onClick={() => navigate(ROUTES.TOP_UP_BANK_CARD)}>
            Get started with bank card
          </SwarmButton>
          <SwarmButton iconType={BatteryCharging} onClick={() => navigate(ROUTES.TOP_UP_CRYPTO)}>
            Use DAI
          </SwarmButton>
          <SwarmButton iconType={Gift} onClick={() => navigate(ROUTES.TOP_UP_GIFT_CODE)}>
            Use a gift code
          </SwarmButton>
        </ExpandableListItemActions>
      </Grid>
    </>
  )
}
Example #8
Source File: index.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export default function Index(): ReactElement {
  const { jsonRpcProvider, setJsonRpcProvider } = useContext(Context)

  const [provider, setProvider] = useState(jsonRpcProvider)

  const { enqueueSnackbar } = useSnackbar()
  const navigate = useNavigate()

  async function onSubmit() {
    try {
      await Rpc.eth_getBlockByNumber(provider)
      enqueueSnackbar('Connected to RPC provider successfully.', { variant: 'success' })
      setJsonRpcProvider(provider)
      navigate(ROUTES.CONFIRMATION)
    } catch (error) {
      enqueueSnackbar('Could not connect to RPC provider.', { variant: 'error' })
    }
  }

  return (
    <>
      <HistoryHeader>Connect to the blockchain</HistoryHeader>
      <Box mb={1}>
        <Typography style={{ fontWeight: 'bold' }}>Set up RPC endpoint</Typography>
      </Box>
      <Box mb={4}>
        <Typography>
          To connect to and retrieve data from the blockchain, you&apos;ll need to connect to a publicly-provided node
          via the node&apos;s RPC endpoint. If you&apos;re not familiar with this, you may use{' '}
          <a href="https://getblock.io/" target="_blank" rel="noreferrer">
            https://getblock.io/
          </a>
          .
        </Typography>
      </Box>
      <Box mb={2}>
        <SwarmTextInput
          name="rpc-endpoint"
          label="RPC Endpoint"
          onChange={event => setProvider(event.target.value)}
          defaultValue={jsonRpcProvider}
        />
      </Box>
      <SwarmButton iconType={Check} onClick={onSubmit}>
        Connect
      </SwarmButton>
    </>
  )
}
Example #9
Source File: Menu.tsx    From calories-in with MIT License 5 votes vote down vote up
CheckStyled = chakra(Check)
Example #10
Source File: Menu.tsx    From calories-in with MIT License 5 votes vote down vote up
CheckStyled = chakra(Check)
Example #11
Source File: index.tsx    From limit-orders-lib with GNU General Public License v3.0 5 votes vote down vote up
ResponsiveCheck = styled(Check)`
  size: 13px;
`
Example #12
Source File: TermsAndConditionsPopup.tsx    From gateway-ui with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export default function TermsAndConditionsPopup({ handleAgree }: Props): ReactElement | null {
  const classes = useStyles()
  const navigate = useNavigate()

  return (
    <Layout
      top={[
        <Header
          key="top1"
          rightAction={
            <IconButton onClick={() => navigate(ROUTES.LANDING_PAGE)}>
              <X strokeWidth={1} />
            </IconButton>
          }
        >
          {text.termsAndConditions.header}
        </Header>,
        <Typography key="top2" variant="subtitle1">
          {text.termsAndConditions.tagline1}{' '}
          <Link href={ROUTES.TERMS_AND_CONDITIONS} color="inherit" underline="always" target="blank">
            {text.termsAndConditions.termsAndConditions}
          </Link>{' '}
          {text.termsAndConditions.tagline2}
        </Typography>,
      ]}
      center={[
        <div key="center">
          <Paper square elevation={0} className={classes.paper}>
            <div className={classes.ul}>
              {text.termsAndConditions.featuresAndLimitations.map(t => [
                <Typography key={`${t}-bee`} variant="body1">
                  <ArrowRight strokeWidth={1} />
                </Typography>,
                <Typography key={`${t}-text`} variant="body1">
                  {t}
                </Typography>,
              ])}
            </div>
            <Typography variant="body2">
              {text.termsAndConditions.disclaimer1}{' '}
              <Link href={ROUTES.TERMS_AND_CONDITIONS} color="inherit" underline="always" target="blank">
                {text.termsAndConditions.disclaimer2}
              </Link>
            </Typography>
          </Paper>
          <Button
            variant="contained"
            className={classes.button}
            size="small"
            style={{ marginTop: 2, paddingLeft: 16, paddingRight: 16 }}
            onClick={() => navigate(ROUTES.LANDING_PAGE)}
          >
            <CornerUpLeft strokeWidth={1} />
            {text.accessPage.backAction}
            <CornerUpLeft style={{ opacity: 0 }} />
          </Button>
        </div>,
      ]}
      bottom={[
        <div key="bottom1" style={{ zIndex: 1000 }}>
          <Footer>
            <Button variant="contained" className={classes.button} size="large" onClick={handleAgree}>
              <Check strokeWidth={1} />
              {text.termsAndConditions.agreeAction}
              <Check style={{ opacity: 0 }} />
            </Button>
          </Footer>
        </div>,
      ]}
    />
  )
}
Example #13
Source File: UploadActionBar.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export function UploadActionBar({
  step,
  onUpload,
  onCancel,
  onGoBack,
  onProceed,
  isUploading,
  hasStamp,
  uploadLabel,
  stampMode,
  setStampMode,
}: Props): ReactElement {
  if (step === 0) {
    return (
      <>
        <Box mb={1}>
          <ExpandableListItemActions>
            <SwarmButton onClick={onProceed} iconType={Layers}>
              Add Postage Stamp
            </SwarmButton>
            <SwarmButton onClick={onCancel} iconType={X} cancel>
              Cancel
            </SwarmButton>
          </ExpandableListItemActions>
        </Box>
        <DocumentationText>You need a postage stamp to upload.</DocumentationText>
      </>
    )
  }

  if (step === 1) {
    return (
      <Grid container direction="row" justifyContent="space-between">
        <ExpandableListItemActions>
          {stampMode === 'SELECT' && (
            <SwarmButton onClick={onProceed} iconType={Check} disabled={!hasStamp}>
              Proceed With Selected Stamp
            </SwarmButton>
          )}
          <SwarmButton onClick={onGoBack} iconType={ArrowLeft} cancel>
            Back To Preview
          </SwarmButton>
        </ExpandableListItemActions>
        <SwarmButton
          onClick={() => setStampMode(stampMode === 'BUY' ? 'SELECT' : 'BUY')}
          iconType={stampMode === 'BUY' ? Layers : PlusSquare}
        >
          {stampMode === 'BUY' ? 'Use Existing Stamp' : 'Buy New Stamp'}
        </SwarmButton>
      </Grid>
    )
  }

  if (step === 2) {
    return (
      <ExpandableListItemActions>
        <SwarmButton onClick={onUpload} iconType={Check} disabled={isUploading} loading={isUploading}>
          {uploadLabel}
        </SwarmButton>
        <SwarmButton onClick={onGoBack} iconType={ArrowLeft} disabled={isUploading} cancel>
          Change Postage Stamp
        </SwarmButton>
      </ExpandableListItemActions>
    )
  }

  return <></>
}
Example #14
Source File: SelectionFilter.tsx    From covidex with MIT License 5 votes vote down vote up
SelectionFilter: React.FC<SelectionFilterProps> = ({
  options = [],
  selectedOptions = new Set([]),
  setSelectedOptions = () => {},
  maxDisplayed = 5,
}) => {
  const theme = useTheme();

  const [numberDisplayed, setNumberDisplayed] = useState<number>(maxDisplayed);
  const [optionQuery, setOptionQuery] = useState<string>('');

  const notSelected = options.length > 0
    ? options.filter((option) => !selectedOptions.has(option) && option !== '').sort()
    : [];
  const sortedOptions: string[] = [...Array.from(selectedOptions).sort(), ...notSelected];
  const filteredOptions = sortedOptions.filter(
    (option) => optionQuery === '' || option.toLowerCase().includes(optionQuery.toLowerCase()),
  );

  return (
    <FilterWrapper>
      {sortedOptions.length > maxDisplayed && (
        <QueryInput
          placeholder="Find a filter..."
          value={optionQuery}
          onChange={(e: ChangeEvent<HTMLInputElement>) => setOptionQuery(e.target.value)}
        />
      )}
      {filteredOptions.slice(0, numberDisplayed).map((option, idx) => {
        return (
          <OptionWrapper
            key={idx}
            onClick={() => setSelectedOptions(option)}
            onMouseDown={(e: any) => e.preventDefault()}
          >
            <Checkbox className="checkbox" checked={selectedOptions.has(option)}>
              {selectedOptions.has(option) && (
                <Check strokeWidth={3} color={theme.white} size={14} />
              )}
            </Checkbox>
            <OptionText>{option}</OptionText>
          </OptionWrapper>
        );
      })}
      {filteredOptions.length > numberDisplayed && (
        <ShowMoreText
          onClick={() => setNumberDisplayed(numberDisplayed + 10)}
          onMouseDown={(e: any) => e.preventDefault()}
        >
          More filters...
        </ShowMoreText>
      )}
    </FilterWrapper>
  );
}
Example #15
Source File: LogoText.tsx    From sybil-interface with GNU General Public License v3.0 5 votes vote down vote up
CheckMark = styled(Check)`
  height: 12px;
  width: 12px;
  margin-left: 3px;
`
Example #16
Source File: index.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export default function Index(): ReactElement {
  const { giftWallets, addGiftWallet } = useContext(TopUpContext)
  const { balance } = useContext(BeeContext)

  const [loading, setLoading] = useState(false)
  const [balances, setBalances] = useState<ResolvedWallet[]>([])

  useEffect(() => {
    async function mapGiftWallets() {
      const results = []
      for (const giftWallet of giftWallets) {
        results.push(await ResolvedWallet.make(giftWallet))
      }
      setBalances(results)
    }

    mapGiftWallets()
  }, [giftWallets])

  const { enqueueSnackbar } = useSnackbar()
  const navigate = useNavigate()

  async function onCreate() {
    enqueueSnackbar('Sending funds to gift wallet...')
    setLoading(true)
    try {
      const wallet = generateWallet()
      addGiftWallet(wallet)
      await createGiftWallet(wallet.getAddressString())
      enqueueSnackbar('Succesfully funded gift wallet', { variant: 'success' })
    } catch (error) {
      enqueueSnackbar(`Failed to fund gift wallet: ${error}`, { variant: 'error' })
    } finally {
      setLoading(false)
    }
  }

  function onCancel() {
    navigate(-1)
  }

  if (!balance) {
    return <Loading />
  }

  return (
    <>
      <HistoryHeader>Invite to Swarm...</HistoryHeader>
      <Box mb={4}>
        <Typography>
          Generate and share a gift wallet that anyone can use to set-up their light node with Swarm Desktop. This will
          use 1 XDAI and 5 BZZ from your node wallet.
        </Typography>
      </Box>
      <Box mb={0.25}>
        <ExpandableListItem label="XDAI balance" value={`${balance.dai.toSignificantDigits(4)} XDAI`} />
      </Box>
      <Box mb={2}>
        <ExpandableListItem label="BZZ balance" value={`${balance.bzz.toSignificantDigits(4)} BZZ`} />
      </Box>
      <Box mb={4}>
        {balances.map((x, i) => (
          <Box mb={2} key={i}>
            <ExpandableListItemKey label={`swarm${String(i).padStart(3, '0')}`} value={x.privateKey} />
            <ExpandableListItemKey label="Address" value={x.address} />
            <ExpandableListItem label="XDAI balance" value={`${x.dai.toSignificantDigits(4)} XDAI`} />
            <ExpandableListItem label="BZZ balance" value={`${x.bzz.toSignificantDigits(4)} BZZ`} />
          </Box>
        ))}
      </Box>
      <ExpandableListItemActions>
        <SwarmButton onClick={onCreate} iconType={Check} loading={loading} disabled={loading}>
          Generate gift wallet
        </SwarmButton>
        <SwarmButton onClick={onCancel} cancel iconType={X} disabled={loading}>
          Cancel
        </SwarmButton>
      </ExpandableListItemActions>
    </>
  )
}
Example #17
Source File: PostageStampCreation.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export function PostageStampCreation({ onFinished }: Props): ReactElement {
  const { chainState } = useContext(BeeContext)
  const { refresh } = useContext(StampsContext)
  const { beeDebugApi } = useContext(SettingsContext)

  const { enqueueSnackbar } = useSnackbar()

  function getFileSize(depth: number): string {
    if (isNaN(depth) || depth < 17 || depth > 255) {
      return '-'
    }

    return `~${getHumanReadableFileSize(convertDepthToBytes(depth))}`
  }

  function getTtl(amount: number): string {
    const isCurrentPriceAvailable = chainState && chainState.currentPrice

    if (amount <= 0 || !isCurrentPriceAvailable) {
      return '-'
    }

    const pricePerBlock = Number.parseInt(chainState.currentPrice, 10)

    return `${secondsToTimeString(
      convertAmountToSeconds(amount, pricePerBlock),
    )} (with price of ${pricePerBlock.toFixed(0)} per block)`
  }

  function getPrice(depth: number, amount: bigint): string {
    const hasInvalidInput = amount <= 0 || isNaN(depth) || depth < 17 || depth > 255

    if (hasInvalidInput) {
      return '-'
    }

    const price = calculateStampPrice(depth, amount)

    return `${price.toSignificantDigits()} BZZ`
  }

  return (
    <Formik
      initialValues={initialFormValues}
      onSubmit={async (values: FormValues, actions: FormikHelpers<FormValues>) => {
        try {
          // This is really just a typeguard, the validation pretty much guarantees these will have the right values
          if (!values.depth || !values.amount) return

          if (!beeDebugApi) return

          const amount = BigInt(values.amount)
          const depth = Number.parseInt(values.depth)
          const options = values.label ? { label: values.label } : undefined
          const batch = await beeDebugApi.createPostageBatch(amount.toString(), depth, options)
          await waitUntilStampUsable(batch, beeDebugApi)
          actions.resetForm()
          await refresh()
          onFinished()
        } catch (e) {
          enqueueSnackbar(`Error: ${(e as Error).message}`, { variant: 'error' })
          actions.setSubmitting(false)
        }
      }}
      validate={(values: FormValues) => {
        const errors: FormErrors = {}

        // Depth
        if (!values.depth) errors.depth = 'Required field'
        else {
          const depth = new BigNumber(values.depth)

          if (!depth.isInteger()) errors.depth = 'Depth must be an integer'
          else if (depth.isLessThan(16)) errors.depth = 'Minimal depth is 16'
          else if (depth.isGreaterThan(255)) errors.depth = 'Depth has to be at most 255'
        }

        // Amount
        if (!values.amount) errors.amount = 'Required field'
        else {
          const amount = new BigNumber(values.amount)

          if (!amount.isInteger()) errors.amount = 'Amount must be an integer'
          else if (amount.isLessThanOrEqualTo(0)) errors.amount = 'Amount must be greater than 0'
        }

        return errors
      }}
    >
      {({ submitForm, isValid, isSubmitting, values, errors }) => (
        <Form>
          <Box mb={2}>
            <SwarmTextInput name="depth" label="Depth" formik />
            <Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
              <Grid container justifyContent="space-between">
                <Typography>Corresponding file size</Typography>
                <Typography>{!errors.depth && values.depth ? getFileSize(parseInt(values.depth, 10)) : '-'}</Typography>
              </Grid>
            </Box>
          </Box>
          <Box mb={2}>
            <SwarmTextInput name="amount" label="Amount" formik />
            <Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
              <Grid container justifyContent="space-between">
                <Typography>Corresponding TTL (Time to live)</Typography>
                <Typography>
                  {!errors.amount && values.amount ? getTtl(Number.parseInt(values.amount, 10)) : '-'}
                </Typography>
              </Grid>
            </Box>
          </Box>
          <Box mb={2}>
            <SwarmTextInput name="label" label="Label" optional formik />
          </Box>
          <Box mb={4} sx={{ bgcolor: '#fcf2e8' }} p={2}>
            <Grid container justifyContent="space-between">
              <Typography>Indicative Price</Typography>
              <Typography>
                {!errors.amount && !errors.depth && values.amount && values.depth
                  ? getPrice(parseInt(values.depth, 10), BigInt(values.amount))
                  : '-'}
              </Typography>
            </Grid>
          </Box>
          <SwarmButton
            disabled={isSubmitting || !isValid || !values.amount || !values.depth}
            onClick={submitForm}
            iconType={Check}
            loading={isSubmitting}
          >
            Buy New Stamp
          </SwarmButton>
        </Form>
      )}
    </Formik>
  )
}
Example #18
Source File: GiftCardFund.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export function GiftCardFund(): ReactElement {
  const { nodeAddresses, balance } = useContext(BeeContext)
  const { jsonRpcProvider } = useContext(TopUpContext)

  const [loading, setLoading] = useState(false)
  const [wallet, setWallet] = useState<ResolvedWallet | null>(null)

  const { privateKeyString } = useParams()

  const { enqueueSnackbar } = useSnackbar()
  const navigate = useNavigate()

  useEffect(() => {
    if (!privateKeyString) {
      return
    }

    ResolvedWallet.make(privateKeyString).then(setWallet)
  }, [privateKeyString])

  if (!wallet || !balance) {
    return <Loading />
  }

  async function onFund() {
    if (!wallet || !nodeAddresses) {
      return
    }

    setLoading(true)

    try {
      await wallet.transfer(nodeAddresses.ethereum)
      enqueueSnackbar('Successfully funded node, restarting...', { variant: 'success' })
      await sleepMs(5_000)
      await upgradeToLightNode(jsonRpcProvider)
      await restartBeeNode()
      navigate(ROUTES.RESTART_LIGHT)
    } catch (error) {
      enqueueSnackbar(`Failed to fund/restart node: ${error}`, { variant: 'error' })
    } finally {
      setLoading(false)
    }
  }

  return (
    <>
      <HistoryHeader>Top-up with gift code</HistoryHeader>
      <Box mb={4}>
        <ProgressIndicator index={1} steps={['Paste gift code', 'Fund your node']} />
      </Box>
      <Box mb={2}>
        <Typography style={{ fontWeight: 'bold' }}>Send funds to your Bee node</Typography>
      </Box>
      <Box mb={4}>
        <Typography>
          Deposit all the funds from the gift wallet to your node wallet address. You can use the button below to
          transfer all funds to your node.
        </Typography>
      </Box>
      <SwarmDivider mb={4} />
      <Box mb={0.25}>
        <ExpandableListItemKey label="Gift wallet address" value={wallet.address || 'N/A'} />
      </Box>
      <Box mb={0.25}>
        <ExpandableListItem label="XDAI balance" value={`${wallet.dai.toSignificantDigits(4)} XDAI`} />
      </Box>
      <Box mb={4}>
        <ExpandableListItem label="BZZ balance" value={`${wallet.bzz.toSignificantDigits(4)} BZZ`} />
      </Box>
      <Box mb={4}>
        <ArrowDown size={24} color="#aaaaaa" />
      </Box>
      <Box mb={0.25}>
        <ExpandableListItemKey label="Node wallet address" value={nodeAddresses?.ethereum || 'N/A'} expanded />
      </Box>
      <Box mb={0.25}>
        <ExpandableListItem label="XDAI balance" value={`${balance.dai.toSignificantDigits(4)} XDAI`} />
      </Box>
      <Box mb={2}>
        <ExpandableListItem label="BZZ balance" value={`${balance.bzz.toSignificantDigits(4)} BZZ`} />
      </Box>
      <SwarmButton iconType={Check} onClick={onFund} disabled={loading} loading={loading}>
        Send all funds to your node
      </SwarmButton>
    </>
  )
}
Example #19
Source File: Swap.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export function Swap({ header }: Props): ReactElement {
  const [loading, setLoading] = useState(false)
  const [hasSwapped, setSwapped] = useState(false)

  const { jsonRpcProvider } = useContext(TopUpContext)
  const { balance } = useContext(BeeContext)

  const navigate = useNavigate()
  const { enqueueSnackbar } = useSnackbar()

  if (!balance) {
    return <Loading />
  }

  const daiToSwap = balance.dai.minusBaseUnits('1')

  const daiAfterSwap = new DaiToken(balance.dai.toBigNumber.minus(daiToSwap.toBigNumber))
  const bzzAfterSwap = new BzzToken(daiToSwap.toBigNumber.dividedToIntegerBy(200))

  async function onSwap() {
    if (hasSwapped) {
      return
    }
    setLoading(true)
    setSwapped(true)
    try {
      await performSwap(daiToSwap.toString)
      enqueueSnackbar('Successfully swapped, restarting...', { variant: 'success' })
      await sleepMs(5_000)
      await upgradeToLightNode(jsonRpcProvider)
      await restartBeeNode()
      navigate(ROUTES.RESTART_LIGHT)
      enqueueSnackbar('Upgraded to light node', { variant: 'success' })
    } catch (error) {
      enqueueSnackbar(`Failed to swap: ${error}`, { variant: 'error' })
    } finally {
      setLoading(false)
    }
  }

  return (
    <>
      <HistoryHeader>{header}</HistoryHeader>
      <Box mb={4}>
        <TopUpProgressIndicator index={1} />
      </Box>
      <Box mb={2}>
        <Typography style={{ fontWeight: 'bold' }}>Swap some xDAI to BZZ</Typography>
      </Box>
      <Box mb={4}>
        <Typography>
          You need to swap xDAI to BZZ in order to use Swarm. Make sure to keep at least 1 xDAI in order to pay for
          transaction costs on the network.
        </Typography>
      </Box>
      <SwarmDivider mb={4} />
      <Box mb={4}>
        <Typography>
          Your current balance is {balance.dai.toSignificantDigits(4)} xDAI and {balance.bzz.toSignificantDigits(4)}{' '}
          BZZ.
        </Typography>
      </Box>
      <Box mb={4}>
        <SwarmTextInput
          label="Amount to swap"
          defaultValue={`${daiToSwap.toSignificantDigits(4)} XDAI`}
          name="x"
          onChange={() => false}
        />
      </Box>
      <Box mb={4}>
        <ArrowDown size={24} color="#aaaaaa" />
      </Box>
      <Box mb={0.25}>
        <ExpandableListItemKey label="Funding wallet address" value={balance.address} expanded />
      </Box>
      <Box mb={0.25}>
        <ExpandableListItem
          label="Resulting XDAI balance after swap"
          value={`${daiAfterSwap.toSignificantDigits(4)} XDAI`}
        />
      </Box>
      <Box mb={2}>
        <ExpandableListItem
          label="Resulting BZZ balance after swap"
          value={`${bzzAfterSwap.toSignificantDigits(4)} BZZ`}
        />
      </Box>
      <ExpandableListItemActions>
        <SwarmButton
          iconType={Check}
          onClick={onSwap}
          disabled={hasSwapped || loading || balance.dai.toDecimal.lte(1)}
          loading={loading}
        >
          Swap Now
        </SwarmButton>
      </ExpandableListItemActions>
    </>
  )
}
Example #20
Source File: ImportFeedDialog.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export function ImportFeedDialog({ onClose }: Props): ReactElement {
  const [textareaValue, setTextareaValue] = useState('')
  const [name, setName] = useState('')
  const fileInputRef = useRef(null)

  const { identities, setIdentities } = useContext(Context)

  const { enqueueSnackbar } = useSnackbar()

  const classes = useStyles()

  async function onImport() {
    const feed = await importIdentity(name, textareaValue)

    if (feed) {
      onFeedReady(feed)
    } else {
      enqueueSnackbar('Feed is not valid', { variant: 'error' })
    }
  }

  function onUploadIdentityFile() {
    if (fileInputRef.current) {
      const input = fileInputRef.current as HTMLInputElement
      input.click()
    }
  }

  function onIdentityFileSelected(event: React.ChangeEvent<HTMLInputElement>) {
    const fileReader = new FileReader()
    const file = event.target?.files?.[0]
    fileReader.onload = async event => {
      const string = event.target?.result

      if (string) {
        const feed = await importIdentity(name, string as string)

        if (feed) {
          onFeedReady(feed)
        } else {
          enqueueSnackbar('Feed is not valid', { variant: 'error' })
        }
      }
    }

    if (file) {
      fileReader.readAsText(file)
    }
  }

  function onFeedReady(identity: Identity) {
    persistIdentity(identities, identity)
    setIdentities(identities)
    enqueueSnackbar('Feed imported successfully', { variant: 'success' })
    onClose()
  }

  return (
    <SwarmDialog>
      <input onChange={onIdentityFileSelected} ref={fileInputRef} className={classes.displayNone} type="file" />
      <Box mb={4}>
        <TitleWithClose onClose={onClose}>Import</TitleWithClose>
      </Box>
      <Box mb={2}>
        <SwarmTextInput label="Identity Name" name="name" onChange={event => setName(event.target.value)} />
      </Box>
      <Box mb={4}>
        <TextareaAutosize
          className={classes.textarea}
          minRows={5}
          onChange={event => setTextareaValue(event.target.value)}
        />
      </Box>
      <ExpandableListItemActions>
        <SwarmButton iconType={Upload} onClick={onUploadIdentityFile}>
          Upload Json File
        </SwarmButton>
        <SwarmButton iconType={Check} onClick={onImport}>
          Use Pasted Text
        </SwarmButton>
      </ExpandableListItemActions>
    </SwarmDialog>
  )
}
Example #21
Source File: Share.tsx    From gateway-ui with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
SharePage = ({ uploadReference, metadata }: Props): ReactElement => {
  const classes = useStyles()
  const navigate = useNavigate()
  const isWebsite = metadata?.isWebsite

  const bzzLink = `https://${encodeManifestReference(uploadReference)}.${BZZ_LINK_DOMAIN}/`
  const linkHeader = isWebsite ? 'Bzz Link' : 'Web link'
  const linkUrl = isWebsite ? bzzLink : `${GATEWAY_URL}${ROUTES.ACCESS_HASH(uploadReference)}`

  const [copiedToClipboard, setCopiedToClipboard] = useState<boolean>(false)
  const [activeValue, setActiveValue] = useState<string>(uploadReference)

  return (
    <Layout
      top={[
        <Header
          key="top1"
          leftAction={
            <IconButton
              onClick={() => {
                navigate(ROUTES.LANDING_PAGE)
              }}
            >
              <ArrowLeft strokeWidth={1} />
            </IconButton>
          }
        >
          {text.shareHashPage.header}
        </Header>,
        <Typography key="top2" variant="subtitle1">
          {text.shareHashPage.tagline}
        </Typography>,
      ]}
      center={[
        <Tabs
          key="center1"
          onChange={reference => {
            if (reference !== activeValue) {
              setActiveValue(reference)
              setCopiedToClipboard(false)
            }
          }}
          values={[
            {
              label: linkHeader,
              component: (
                <div>
                  <Paper
                    square
                    elevation={0}
                    style={{ overflowWrap: 'break-word', textAlign: 'left', padding: 16, margin: 4 }}
                  >
                    <Typography variant="caption">{linkUrl}</Typography>
                  </Paper>
                  {isWebsite && (
                    <Button
                      variant="contained"
                      style={{ margin: 4, width: 'auto' }}
                      className={classes.button}
                      href={bzzLink}
                      target="blank"
                    >
                      <ExternalLink strokeWidth={1} />
                      {text.accessHashPage.openWebsite}
                      <ExternalLink style={{ opacity: 0 }} />
                    </Button>
                  )}
                </div>
              ),
              value: linkUrl,
            },
            {
              label: 'Swarm hash',
              component: (
                <Paper
                  square
                  elevation={0}
                  style={{ overflowWrap: 'break-word', textAlign: 'left', padding: 16, margin: 4 }}
                >
                  <Typography variant="caption">{uploadReference}</Typography>
                </Paper>
              ),
              value: uploadReference,
            },
          ]}
        />,
      ]}
      bottom={[
        <Typography key="bottom1" variant="body2">
          {text.shareHashPage.disclaimer}
        </Typography>,
        <Footer key="bottom2">
          <CopyToClipboard text={activeValue}>
            <Button
              variant="contained"
              className={classes.button}
              size="large"
              onClick={e => {
                e.stopPropagation()
                setCopiedToClipboard(true)
              }}
            >
              {copiedToClipboard ? <Check strokeWidth={1} /> : <Clipboard strokeWidth={1} />}
              {copiedToClipboard ? text.shareHashPage.copyLinkActionSuccess : text.shareHashPage.copyLinkAction}
              {/* Needed to properly align icon to the right and label to center */}
              <Clipboard style={{ opacity: 0 }} />
            </Button>
          </CopyToClipboard>
        </Footer>,
      ]}
    />
  )
}
Example #22
Source File: CreateNewFeed.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export default function CreateNewFeed(): ReactElement {
  const { beeApi, beeDebugApi } = useContext(SettingsContext)
  const { identities, setIdentities } = useContext(FeedsContext)
  const [loading, setLoading] = useState(false)
  const { enqueueSnackbar } = useSnackbar()

  const navigate = useNavigate()

  async function onSubmit(values: FormValues) {
    setLoading(true)

    if (!beeApi) {
      enqueueSnackbar(<span>Bee API unavailabe</span>, { variant: 'error' })
      setLoading(false)

      return
    }
    const wallet = generateWallet()
    const stamps = await beeDebugApi?.getAllPostageBatch()

    if (!stamps || !stamps.length) {
      enqueueSnackbar(<span>No stamp available</span>, { variant: 'error' })
      setLoading(false)

      return
    }

    if (!values.identityName || !values.type) {
      enqueueSnackbar(<span>Form is unfinished</span>, { variant: 'error' })
      setLoading(false)

      return
    }

    const identity = await convertWalletToIdentity(wallet, values.type, values.identityName, values.password)
    persistIdentity(identities, identity)
    setIdentities(identities)
    navigate(ROUTES.FEEDS)
    setLoading(false)
  }

  function cancel() {
    navigate(-1)
  }

  return (
    <div>
      <HistoryHeader>Create new feed</HistoryHeader>
      <Box mb={4}>
        <DocumentationText>
          To create a feed you will need to create an identity. Please refer to the{' '}
          <a
            href="https://docs.ethswarm.org/api/#tag/Feed/paths/~1feeds~1{owner}~1{topic}/post"
            target="_blank"
            rel="noreferrer"
          >
            official Bee documentation
          </a>{' '}
          to understand how feeds work.
        </DocumentationText>
      </Box>
      <Formik initialValues={initialValues} onSubmit={onSubmit}>
        {({ submitForm, values }) => (
          <Form>
            <Box mb={0.25}>
              <SwarmTextInput name="identityName" label="Identity name" formik />
            </Box>
            <Box mb={0.25}>
              <SwarmSelect
                formik
                name="type"
                options={[
                  { label: 'Keypair Only', value: 'PRIVATE_KEY' },
                  { label: 'Password Protected', value: 'V3' },
                ]}
              />
            </Box>
            {values.type === 'V3' && <SwarmTextInput name="password" label="Password" password formik />}
            <Box mt={2}>
              <ExpandableListItemKey label="Topic" value={'00'.repeat(32)} />
            </Box>
            <Box mt={2} sx={{ bgcolor: '#fcf2e8' }} p={2}>
              <Grid container justifyContent="space-between">
                <Typography>Feeds name</Typography>
                <Typography>{values.identityName} Website</Typography>
              </Grid>
            </Box>
            <Box mt={1.25}>
              <ExpandableListItemActions>
                <SwarmButton onClick={submitForm} iconType={Check} disabled={loading} loading={loading}>
                  Create Feed
                </SwarmButton>
                <SwarmButton onClick={cancel} iconType={X} disabled={loading} cancel>
                  Cancel
                </SwarmButton>
              </ExpandableListItemActions>
            </Box>
          </Form>
        )}
      </Formik>
    </div>
  )
}
Example #23
Source File: NewConfirmation.tsx    From frontend-v1 with GNU Affero General Public License v3.0 4 votes vote down vote up
Confirmation: React.FC = () => {
  const { deposit, toggle } = useDeposits();
  const [l1DepositSuccess] = useState(true);

  if (!deposit) return null;
  // const amountMinusFees = receiveAmount(deposit.amount, deposit.fees);

  const tokenInfo = TOKENS_LIST[deposit.fromChain].find(
    (t) => t.address === deposit.token
  );

  return (
    <Layout>
      <Wrapper>
        <Header>
          <SuccessIconRow>
            <SuccessIcon>
              <Check strokeWidth={4} />
            </SuccessIcon>
            {l1DepositSuccess ? (
              <SuccessIcon>
                <Check strokeWidth={4} />
              </SuccessIcon>
            ) : (
              <ConfirmationIcon>
                <div>~2 minutes</div>
              </ConfirmationIcon>
            )}
          </SuccessIconRow>
          {l1DepositSuccess ? <SuccessIconRow /> : <ConfirmationLine />}
          <SuccessInfoRow>
            <SuccessInfoBlock>
              <SuccessInfoText>Deposit succeeded</SuccessInfoText>
              <Link
                href={CHAINS[deposit.fromChain].constructExplorerLink(
                  deposit.txHash
                )}
                target="_blank"
                rel="noopener norefferrer"
              >
                Explorer <ArrowUpRight width={16} height={16} />
              </Link>
            </SuccessInfoBlock>
            <SuccessInfoBlock>
              {l1DepositSuccess ? (
                <>
                  <SuccessInfoText>Transfer succeeded</SuccessInfoText>
                  <Link
                    href={CHAINS[deposit.fromChain].constructExplorerLink(
                      deposit.txHash
                    )}
                    target="_blank"
                    rel="noopener norefferrer"
                  >
                    Explorer <ArrowUpRight width={16} height={16} />
                  </Link>
                </>
              ) : (
                <ConfirmationText>Funds transferred</ConfirmationText>
              )}
            </SuccessInfoBlock>
          </SuccessInfoRow>
        </Header>
        <InfoSection>
          <div>
            <Row>
              <Info>
                <h3>Send</h3>
                <div>
                  <Logo
                    src={tokenInfo?.logoURI}
                    alt={`${tokenInfo?.symbol} logo`}
                  />
                  <div>
                    {formatUnits(deposit.amount, tokenInfo?.decimals ?? 18)}{" "}
                    {tokenInfo?.symbol}
                  </div>
                </div>
              </Info>
              <Info></Info>
              {/* <Info>
                <h3>Receiving</h3>
                <div>
                  <Logo
                    src={tokenInfo?.logoURI}
                    alt={`${tokenInfo?.symbol} logo`}
                  />
                  <div>
                    {formatUnits(amountMinusFees, tokenInfo?.decimals ?? 18)}{" "}
                    {tokenInfo?.symbol}
                  </div>
                </div>
              </Info> */}
            </Row>
            <Info>
              <h3>From</h3>
              <div>
                <Logo
                  src={CHAINS[deposit.fromChain].logoURI}
                  alt={`${CHAINS[deposit.fromChain].name} logo`}
                />
                <div>
                  <SecondaryLink
                    href={`${CHAINS[deposit.fromChain].explorerUrl}/address/${
                      deposit.from
                    }`}
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    {deposit.from}
                  </SecondaryLink>
                </div>
              </div>
            </Info>
            <Info>
              <h3>To</h3>
              <div>
                <Logo
                  src={CHAINS[deposit.toChain].logoURI}
                  alt={`${CHAINS[deposit.toChain].name} logo`}
                />
                <div>
                  <SecondaryLink
                    href={`${CHAINS[deposit.toChain].explorerUrl}/address/${
                      deposit.toAddress
                    }`}
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    {deposit.toAddress}
                  </SecondaryLink>
                </div>
              </div>
            </Info>
            <Info>
              <h3>Estimated time of arrival</h3>
              <div>
                <div>~2 minutes</div>
              </div>
            </Info>
          </div>
          <Button onClick={() => toggle({ showConfirmationScreen: false })}>
            Close
          </Button>
        </InfoSection>
      </Wrapper>
    </Layout>
  );
}
Example #24
Source File: Confirmation.tsx    From frontend-v1 with GNU Affero General Public License v3.0 4 votes vote down vote up
Confirmation: React.FC = () => {
  const { deposit, toggle } = useDeposits();

  if (!deposit) return null;
  const amountMinusFees = receiveAmount(deposit.amount, deposit.fees);
  const tokenInfo = TOKENS_LIST[deposit.fromChain].find(
    (t) => t.address === deposit.token
  );
  const isWETH = tokenInfo?.symbol === "WETH";

  return (
    <Layout>
      <Wrapper>
        <Header>
          <Heading>Deposit succeeded</Heading>
          <SubHeading>
            Your funds will arrive in{" "}
            {getConfirmationDepositTime(deposit.toChain)}
          </SubHeading>
          <SuccessIcon>
            <Check strokeWidth={4} />
          </SuccessIcon>
        </Header>
        <InfoSection>
          <Link
            href={CHAINS[deposit.fromChain].constructExplorerLink(
              deposit.txHash
            )}
            target="_blank"
            rel="noopener norefferrer"
          >
            Explorer <ArrowUpRight width={16} height={16} />
          </Link>
          <div>
            <Row>
              <Info>
                <h3>Sending</h3>
                <div>
                  <Logo
                    src={tokenInfo?.logoURI}
                    alt={`${tokenInfo?.symbol} logo`}
                  />
                  <div>
                    {formatUnits(deposit.amount, tokenInfo?.decimals ?? 18)}{" "}
                    {tokenInfo?.symbol}
                  </div>
                </div>
              </Info>
              <Info></Info>
              <Info>
                <h3>Receiving</h3>
                <div>
                  <Logo
                    src={isWETH ? MAINNET_ETH?.logoURI : tokenInfo?.logoURI}
                    alt={`${
                      isWETH ? MAINNET_ETH?.symbol : tokenInfo?.symbol
                    } logo`}
                  />
                  <div>
                    {formatUnits(
                      amountMinusFees,
                      (isWETH ? MAINNET_ETH?.decimals : tokenInfo?.decimals) ??
                        18
                    )}{" "}
                    {isWETH ? MAINNET_ETH?.symbol : tokenInfo?.symbol}
                  </div>
                </div>
              </Info>
            </Row>
            <Info>
              <h3>From</h3>
              <div>
                <Logo
                  src={CHAINS[deposit.fromChain].logoURI}
                  alt={`${CHAINS[deposit.fromChain].name} logo`}
                />
                <div>
                  <SecondaryLink
                    href={`${CHAINS[deposit.fromChain].explorerUrl}/address/${
                      deposit.from
                    }`}
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    <span>{deposit.from}</span>
                    <span>{shortenAddressLong(deposit.from ?? "")}</span>
                  </SecondaryLink>
                </div>
              </div>
            </Info>
            <Info>
              <h3>To</h3>
              <div>
                <Logo
                  src={CHAINS[deposit.toChain].logoURI}
                  alt={`${CHAINS[deposit.toChain].name} logo`}
                />
                <div>
                  <SecondaryLink
                    href={`${CHAINS[deposit.toChain].explorerUrl}/address/${
                      deposit.toAddress
                    }`}
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    <span>{deposit.toAddress}</span>
                    <span>{shortenAddressLong(deposit.toAddress ?? "")}</span>
                  </SecondaryLink>
                </div>
              </div>
            </Info>
            <Info>
              <h3>Estimated time of arrival</h3>
              <div>
                <div>{getConfirmationDepositTime(deposit.toChain)}</div>
              </div>
            </Info>
          </div>
          <Button onClick={() => toggle({ showConfirmationScreen: false })}>
            Close
          </Button>
        </InfoSection>
      </Wrapper>
    </Layout>
  );
}