@chakra-ui/react#useBoolean JavaScript Examples

The following examples show how to use @chakra-ui/react#useBoolean. 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: contacts.js    From idena-web with MIT License 4 votes vote down vote up
export default function ContactsPage() {
  const {t} = useTranslation()

  const router = useRouter()

  const [selectedContact, setSelectedContact] = React.useState(null)

  const sendInviteDisclosure = useDisclosure()
  const {
    onOpen: onOpenInviteDrawer,
    onClose: onCloseInviteDrawer,
  } = sendInviteDisclosure

  const {
    isOpen: isOpenEditContactDrawer,
    onOpen: onOpenEditContactDrawer,
    onClose: onCloseEditContactDrawer,
  } = useDisclosure()

  const {
    isOpen: isOpenKillContactDrawer,
    onOpen: onOpenKillContactDrawer,
    onClose: onCloseKillContactDrawer,
  } = useDisclosure()

  React.useEffect(() => {
    if (router.query.new !== undefined) {
      onOpenInviteDrawer()
    }
  }, [onOpenInviteDrawer, router])

  const successToast = useSuccessToast()
  const failToast = useFailToast()

  const [isMining, setIsMining] = useBoolean()

  const handleInviteMined = React.useCallback(() => {
    if (router.query.new !== undefined) {
      router.push('/contacts')
    }
    onCloseInviteDrawer()
    setIsMining.off()
  }, [onCloseInviteDrawer, router, setIsMining])

  return (
    <InviteProvider>
      <Layout>
        <Page px={0} py={0}>
          <Flex w="full">
            <ContactListSidebar
              selectedContactId={selectedContact?.id}
              onSelectContact={setSelectedContact}
              onNewContact={onOpenInviteDrawer}
            />
            <Flex flex={1} py={6} px={20}>
              {selectedContact ? (
                <ContactCard
                  contact={selectedContact}
                  onEditContact={onOpenEditContactDrawer}
                  onRemoveContact={() => {
                    setSelectedContact(null)
                  }}
                  onRecoverContact={setSelectedContact}
                  onKillContact={onOpenKillContactDrawer}
                  onInviteMined={handleInviteMined}
                />
              ) : (
                <NoContactDataPlaceholder>
                  {t('You haven’t selected contacts yet.')}
                </NoContactDataPlaceholder>
              )}
            </Flex>
          </Flex>

          <IssueInviteDrawer
            {...sendInviteDisclosure}
            inviteeAddress={router.query.address}
            isMining={isMining}
            onIssue={invite => {
              setSelectedContact(invite)
              setIsMining.on()
            }}
            onIssueFail={error => {
              failToast({
                title: error ?? t('Something went wrong'),
                status: 'error',
              })
            }}
          />

          <EditContactDrawer
            contact={selectedContact ?? {}}
            isOpen={isOpenEditContactDrawer}
            onRename={({firstName, lastName}) => {
              setSelectedContact(contact => ({
                ...contact,
                firstName,
                lastName,
              }))
              successToast(t('Changes have been saved'))
              onCloseEditContactDrawer()
            }}
            onClose={onCloseEditContactDrawer}
          />

          <KillInviteDrawer
            invite={selectedContact ?? {}}
            isOpen={isOpenKillContactDrawer}
            onClose={onCloseKillContactDrawer}
            onKill={() => {
              successToast('Invite terminated')
              onCloseKillContactDrawer()
            }}
            onFail={error => {
              failToast({
                title: 'Failed to terminate invite',
                description: error,
              })
            }}
          />
        </Page>
      </Layout>
    </InviteProvider>
  )
}
Example #2
Source File: containers.js    From idena-web with MIT License 4 votes vote down vote up
export function ReviewAdDrawer({
  ad,
  onDeployContract,
  onStartVoting,
  ...props
}) {
  const {t} = useTranslation()

  const coinbase = useCoinbase()

  const balance = useBalance(coinbase)

  const failToast = useFailToast()

  const [isPending, {on: setIsPendingOn, off: setIsPendingOff}] = useBoolean()

  const {submit} = useReviewAd({
    onBeforeSubmit: setIsPendingOn,
    onDeployContract,
    onStartVoting: React.useCallback(
      data => {
        onStartVoting(data)
        setIsPendingOff()
      },
      [onStartVoting, setIsPendingOff]
    ),
    onError: React.useCallback(
      error => {
        failToast(error)
        setIsPendingOff()
      },
      [failToast, setIsPendingOff]
    ),
  })

  const {data: deployAmount} = useDeployContractAmount()

  const {data: startAmount} = useStartAdVotingAmount()

  const formatDna = useFormatDna({maximumFractionDigits: 5})

  return (
    <AdDrawer
      isMining={isPending}
      closeOnOverlayClick={!isPending}
      closeOnEsc={!isPending}
      isCloseable={!isPending}
      {...props}
    >
      <DrawerHeader>
        <Stack spacing={4}>
          <Center
            alignSelf="flex-start"
            bg="blue.012"
            w={12}
            minH={12}
            rounded="xl"
          >
            <OracleIcon boxSize={6} color="blue.500" />
          </Center>
          <Heading color="gray.500" fontSize="lg" fontWeight={500}>
            {t('Send to Oracle Voting')}
          </Heading>
        </Stack>
      </DrawerHeader>
      <DrawerBody overflowY="auto" mx={-6} mb={10}>
        <Stack spacing={6} color="gray.500" fontSize="md" p={6} pt={0}>
          <Stack spacing={3}>
            <Text>
              {t(`Please keep in mind that you will not be able to edit the banner
              after it has been submitted for verification`)}
            </Text>
          </Stack>
          <Stack spacing={6} bg="gray.50" p={6} rounded="lg">
            <Stack isInline spacing={5} align="flex-start">
              <AdImage src={adImageThumbSrc(ad)} w="10" />
              <Box>
                <Text fontWeight={500}>{ad.title}</Text>
                <ExternalLink href={ad.url} maxW="48">
                  {ad.url}
                </ExternalLink>
              </Box>
            </Stack>
            <Stack spacing={3}>
              <HDivider />
              <InlineAdStatGroup labelWidth="20">
                <SmallInlineAdStat label={t('Language')} value={ad.language} />
                <SmallInlineAdStat label={t('Min stake')} value={ad.stake} />
                <SmallInlineAdStat label={t('Min age')} value={ad.age} />
                <SmallInlineAdStat label={t('OS')} value={ad.os} />
              </InlineAdStatGroup>
            </Stack>
          </Stack>
          <form
            id="reviewForm"
            onSubmit={async e => {
              e.preventDefault()

              const {thumb, media} = await db.table('ads').get(ad.id)

              const errors = validateAd({...ad, thumb, media})

              if (Object.values(errors).some(Boolean)) {
                failToast({
                  title: t('Unable to send invalid ad'),
                  description: t(`Please check {{fields}} fields`, {
                    fields: Object.entries(errors)
                      .filter(([, v]) => Boolean(v))
                      .map(([k]) => k)
                      .join(', '),
                  }),
                })
                return
              }

              if (deployAmount && startAmount) {
                const requiredAmount = deployAmount + startAmount

                if (balance > requiredAmount) {
                  try {
                    submit({
                      ...ad,
                      thumb: new Uint8Array(
                        await compressAdImage(await thumb.arrayBuffer(), {
                          width: 80,
                          height: 80,
                          type: thumb.type,
                        })
                      ),
                      media: new Uint8Array(
                        await compressAdImage(await media.arrayBuffer(), {
                          width: 320,
                          height: 320,
                          type: thumb.type,
                        })
                      ),
                    })
                  } catch (error) {
                    failToast({
                      title: t('Error compressing images'),
                      description: error?.message,
                    })
                  }
                } else {
                  failToast(
                    t(
                      `Insufficient funds to start reviewing ad. Please deposit at least {{missingAmount}}.`,
                      {
                        missingAmount: formatDna(
                          Math.abs(balance - requiredAmount)
                        ),
                      }
                    )
                  )
                }
              }
            }}
          >
            <Stack spacing={4}>
              <FormControl isDisabled isReadOnly>
                <Stack spacing={3}>
                  <FormLabel htmlFor="stake" mb={0}>
                    {t('Min stake, iDNA')}
                  </FormLabel>
                  <Input defaultValue={deployAmount} />
                </Stack>
              </FormControl>
              <FormControl isDisabled isReadOnly>
                <Stack spacing={3}>
                  <FormLabel htmlFor="oracleFee" mb={0}>
                    {t('Review fee, iDNA')}
                  </FormLabel>
                  <Input defaultValue={startAmount} />
                </Stack>
              </FormControl>
            </Stack>
          </form>
        </Stack>
      </DrawerBody>
      <DrawerFooter bg="white">
        <PrimaryButton
          type="submit"
          form="reviewForm"
          isLoading={isPending}
          loadingText={t('Mining...')}
        >
          {t('Send')}
        </PrimaryButton>
      </DrawerFooter>
    </AdDrawer>
  )
}
Example #3
Source File: containers.js    From idena-web with MIT License 4 votes vote down vote up
export function PublishAdDrawer({ad, onPublish, ...props}) {
  const {t} = useTranslation()

  const formatDna = useFormatDna()

  const failToast = useFailToast()

  const [{address}] = useIdentity()

  const balance = useBalance(address)

  const [isPending, {on: setIsPendingOn, off: setIsPendingOff}] = useBoolean()

  const {submit} = usePublishAd({
    onBeforeSubmit: setIsPendingOn,
    onMined: React.useCallback(() => {
      onPublish()
      setIsPendingOff()
    }, [onPublish, setIsPendingOff]),
    onError: React.useCallback(
      error => {
        failToast(error)
        setIsPendingOff()
      },
      [failToast, setIsPendingOff]
    ),
  })

  const competingAds = useCompetingAds(ad.cid, new AdTarget(ad))

  const competitorCount = competingAds?.length
  const maxCompetitor = competingAds?.sort((a, b) => b.amount - a.amount)[0]

  return (
    <AdDrawer isMining={isPending} {...props}>
      <DrawerHeader>
        <Stack spacing={4}>
          <FillCenter
            alignSelf="flex-start"
            bg="blue.012"
            w={12}
            minH={12}
            rounded="xl"
          >
            <AdsIcon boxSize={6} color="blue.500" />
          </FillCenter>
          <Heading fontSize="lg" fontWeight={500}>
            {t('Create ad campaign')}
          </Heading>
        </Stack>
      </DrawerHeader>
      <DrawerBody overflowY="auto" mx={-6} mb={10}>
        <Stack spacing="6" color="brandGray.500" fontSize="md" p={6} pt={0}>
          <Stack spacing="3">
            <Text>
              {t(
                'Your ad campaign is about to be created for the audience with the following target parameters:',
                {nsSeparator: '|'}
              )}
            </Text>
          </Stack>

          <Stack spacing="6" bg="gray.50" p={6} rounded="lg">
            <Stack isInline spacing={5} align="flex-start">
              <AdImage src={adImageThumbSrc(ad)} w="10" />
              <Box>
                <Text fontWeight={500}>{ad.title}</Text>
                <ExternalLink href={ad.url} maxW="48">
                  {ad.url}
                </ExternalLink>
              </Box>
            </Stack>
            <Stack spacing={3}>
              <HDivider />
              <InlineAdStatGroup labelWidth="24">
                <InlineAdStat
                  label={t('Competitors')}
                  value={String(competitorCount)}
                />
                <InlineAdStat
                  label={t('Max bid')}
                  value={maxCompetitor ? formatDna(maxCompetitor.amount) : '--'}
                />
              </InlineAdStatGroup>
              <HDivider />
              <InlineAdStatGroup labelWidth="20">
                <SmallInlineAdStat label={t('Language')} value={ad.language} />
                <SmallInlineAdStat label={t('Min stake')} value={ad.stake} />
                <SmallInlineAdStat label={t('Min age')} value={ad.age} />
                <SmallInlineAdStat label={t('OS')} value={ad.os} />
              </InlineAdStatGroup>
            </Stack>
          </Stack>
        </Stack>
      </DrawerBody>
      <DrawerFooter>
        <PrimaryButton
          isLoading={isPending}
          loadingText={t('Creating...')}
          onClick={() => {
            if (balance > 0) {
              submit(ad)
            } else {
              failToast(t('Insufficient funds to start campaign'))
            }
          }}
        >
          {t('Create')}
        </PrimaryButton>
      </DrawerFooter>
    </AdDrawer>
  )
}
Example #4
Source File: containers.js    From idena-web with MIT License 4 votes vote down vote up
export function BurnDrawer({ad, onBurn, ...props}) {
  const {t} = useTranslation()

  const [{address}] = useIdentity()

  const balance = useBalance(address)

  const failToast = useFailToast()

  const [isPending, {on: setIsPendingOn, off: setIsPendingOff}] = useBoolean()

  const {submit} = useBurnAd({
    onMined: React.useCallback(() => {
      onBurn()
      setIsPendingOff()
    }, [onBurn, setIsPendingOff]),
    onError: React.useCallback(
      error => {
        failToast(error)
        setIsPendingOff()
      },
      [failToast, setIsPendingOff]
    ),
  })

  const formatDna = useFormatDna()

  const competingAds = useCompetingAds(ad.cid, new AdTarget(ad))

  const competitorCount = competingAds?.length
  const maxCompetitor = competingAds?.sort((a, b) => b.amount - a.amount)[0]

  return (
    <AdDrawer isMining={isPending} {...props}>
      <DrawerHeader>
        <Stack spacing={4}>
          <FillCenter
            alignSelf="flex-start"
            bg="blue.012"
            w={12}
            minH={12}
            rounded="xl"
          >
            <AdsIcon boxSize={6} color="blue.500" />
          </FillCenter>
          <Heading fontSize="lg" fontWeight={500}>
            {t('Burn')}
          </Heading>
        </Stack>
      </DrawerHeader>
      <DrawerBody overflowY="auto" mx={-6} mb={10}>
        <Stack spacing="6" color="brandGray.500" fontSize="md" p={6} pt={0}>
          <Stack spacing="3">
            <Text>{t('Burn iDNA to make your ad visible.')}</Text>
          </Stack>

          <Stack spacing="6" bg="gray.50" p={6} rounded="lg">
            <Stack isInline spacing={5} align="flex-start">
              <AdImage src={adImageThumbSrc(ad)} w="10" />
              <Box>
                <Text fontWeight={500}>{ad.title}</Text>
                <ExternalLink href={ad.url} maxW="48">
                  {ad.url}
                </ExternalLink>
              </Box>
            </Stack>
            <Stack spacing={3}>
              <HDivider />
              <InlineAdStatGroup labelWidth="24">
                <InlineAdStat
                  label={t('Competitors')}
                  value={String(competitorCount)}
                />
                <InlineAdStat
                  label={t('Max bid')}
                  value={maxCompetitor ? formatDna(maxCompetitor.amount) : '--'}
                />
              </InlineAdStatGroup>
              <HDivider />
              <InlineAdStatGroup labelWidth="20">
                <SmallInlineAdStat label={t('Language')} value={ad.language} />
                <SmallInlineAdStat label={t('Min stake')} value={ad.stake} />
                <SmallInlineAdStat label={t('Min age')} value={ad.age} />
                <SmallInlineAdStat label={t('OS')} value={ad.os} />
              </InlineAdStatGroup>
            </Stack>
          </Stack>
          <form
            id="burnForm"
            onSubmit={e => {
              e.preventDefault()

              const amount = Number(new FormData(e.target).get('amount'))

              if (amount > 0 && amount < balance) {
                setIsPendingOn()
                submit({ad, amount})
              } else {
                failToast(
                  amount > 0
                    ? t('Insufficient funds to burn {{amount}}', {
                        amount: formatDna(amount),
                      })
                    : t('Invalid amount')
                )
              }
            }}
          >
            <FormControl>
              <Stack spacing={3}>
                <FormLabel htmlFor="amount" mb={0}>
                  {t('Amount, iDNA')}
                </FormLabel>
                <AdNumberInput
                  name="amount"
                  min={0}
                  max={Number.MAX_SAFE_INTEGER}
                  addon={t('iDNA')}
                />
              </Stack>
            </FormControl>
          </form>
        </Stack>
      </DrawerBody>
      <DrawerFooter>
        <PrimaryButton
          type="submit"
          form="burnForm"
          isLoading={isPending}
          loadingText={t('Mining...')}
        >
          {t('Burn')}
        </PrimaryButton>
      </DrawerFooter>
    </AdDrawer>
  )
}