react-query#UseQueryResult TypeScript Examples

The following examples show how to use react-query#UseQueryResult. 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: nativeBalances.ts    From anchor-web-app with Apache License 2.0 6 votes vote down vote up
export function useEvmNativeBalanceQuery(
  walletAddress?: EVMAddr,
): UseQueryResult<u<Eth> | undefined> {
  const { queryErrorReporter } = useApp();
  const { nativeWalletAddress } = useAccount();
  const { provider } = useEvmWallet();

  return useQuery(
    [
      EVM_QUERY_KEY.EVM_NATIVE_BALANCES,
      walletAddress ?? (nativeWalletAddress as EVMAddr | undefined),
      (walletAddress: EVMAddr): Promise<BigNumber> | undefined => {
        if (!provider) {
          return;
        }

        return provider.getBalance(walletAddress);
      },
    ],
    queryFn,
    {
      refetchInterval: REFETCH_INTERVAL,
      keepPreviousData: true,
      onError: queryErrorReporter,
    },
  );
}
Example #2
Source File: usePoolAPY.ts    From rari-dApp with GNU Affero General Public License v3.0 6 votes vote down vote up
usePoolsAPY = (pools: PoolInterface[]) => {
  const { rari } = useRari();

  const poolAPYs: UseQueryResult[] = useQueries(
    pools.map(({ type: poolType }) => {
      return {
        queryKey: poolType + " apy",
        queryFn: () => fetchPoolAPY(rari, poolType),
      };
    })
  );

  return useMemo(() => {
    return !poolAPYs.length ? [] : poolAPYs.map(({ data: poolAPY }) => poolAPY);
  }, [poolAPYs]);
}
Example #3
Source File: EditPage.tsx    From frontend with MIT License 6 votes vote down vote up
export default function EditPage() {
  const { t } = useTranslation('transfer')

  const router = useRouter()
  const id = String(router.query.id)

  const { data: transfer }: UseQueryResult<TransferResponse> = useTransfer(id)
  const { data: campaigns }: UseQueryResult<CampaignResponse[]> = useCampaignList()

  return (
    <AdminLayout>
      <AdminContainer title={t('transfers')}>
        <Container maxWidth="md" sx={{ py: 5 }}>
          {transfer && campaigns && <EditForm transfer={transfer} campaigns={campaigns} id={id} />}
        </Container>
      </AdminContainer>
    </AdminLayout>
  )
}
Example #4
Source File: useAxiosQuery.ts    From nextclade with MIT License 6 votes vote down vote up
export function useAxiosQuery<TData = unknown>(
  url: string,
  options?: UseAxiosQueryOptions<TData>,
): UseQueryResult<TData, Error> {
  return useQuery<TData, Error>(
    url,
    async () => {
      if (options?.delay) {
        await new Promise((resolve) => {
          setInterval(resolve, options.delay)
        })
      }
      return axiosFetch(url)
    },
    {
      staleTime: Number.POSITIVE_INFINITY,
      refetchOnMount: false,
      refetchOnWindowFocus: false,
      refetchOnReconnect: true,
      refetchInterval: Number.POSITIVE_INFINITY,
      ...options,
    },
  )
}
Example #5
Source File: use-get-vaults.tsx    From interbtc-ui with Apache License 2.0 6 votes vote down vote up
useGetVaults = ({ address }: { address: string; }): Array<VaultExt<BitcoinUnit>> => {
  // TODO: can we handle this check at the application level rather than in components and utilties?
  // https://www.notion.so/interlay/Handle-api-loaded-check-at-application-level-38fe5d146c8143a88cef2dde7b0e19d8
  const { bridgeLoaded } = useSelector((state: StoreType) => state.general);

  // TODO: updating react-query to > 3.28.0 will allow us to type this properly
  const vaults = useQueries<Array<UseQueryResult<unknown, unknown>>>(
    VAULT_COLLATERAL.map(token => {
      return {
        queryKey: ['vaults', address, token],
        queryFn: () => getVaults(newAccountId(window.bridge.api, address), token),
        options: {
          enabled: !!bridgeLoaded
        }
      };
    })
  );

  return parseVaults(vaults);
}
Example #6
Source File: balance.ts    From anchor-web-app with Apache License 2.0 6 votes vote down vote up
export function useAncBalanceQuery(
  walletAddress: HumanAddr | undefined | null,
): UseQueryResult<AncBalance | undefined> {
  const { queryClient, contractAddress, queryErrorReporter } =
    useAnchorWebapp();

  const result = useQuery(
    [
      ANCHOR_QUERY_KEY.ANC_BALANCE,
      walletAddress ?? undefined,
      contractAddress.cw20.ANC,
      queryClient,
    ],
    queryFn,
    {
      refetchInterval: !!walletAddress && 1000 * 60 * 2,
      enabled: !!walletAddress,
      keepPreviousData: true,
      onError: queryErrorReporter,
    },
  );

  return walletAddress ? result : EMPTY_QUERY_RESULT;
}
Example #7
Source File: Form.tsx    From frontend with MIT License 5 votes vote down vote up
export default function EditForm() {
  const router = useRouter()
  const queryClient = useQueryClient()
  const { t } = useTranslation()

  let id = router.query.id

  let initialValues: VaultInput = {
    name: '',
    currency: '',
    campaignId: '',
  }

  if (id) {
    id = String(id)
    const { data }: UseQueryResult<VaultResponse> = useVault(id)

    initialValues = {
      name: data?.name,
      currency: data?.currency,
      campaignId: data?.campaignId,
    }
  }

  const mutationFn = id ? useEditVault(id) : useCreateVault()

  const mutation = useMutation<AxiosResponse<VaultResponse>, AxiosError<ApiErrors>, VaultInput>({
    mutationFn,
    onError: () => AlertStore.show(t('vaults:alerts:error'), 'error'),
    onSuccess: () => {
      if (id) queryClient.invalidateQueries(endpoints.vaults.getVault(String(id)).url)
      AlertStore.show(id ? t('vaults:alerts:edit') : t('vaults:alerts:create'), 'success')
      router.push(routes.admin.vaults.index)
    },
  })

  async function onSubmit(data: VaultInput) {
    mutation.mutate(data)
  }

  return (
    <GenericForm
      onSubmit={onSubmit}
      initialValues={initialValues}
      validationSchema={validationSchema}>
      <Box sx={{ marginTop: '5%', height: '62.6vh' }}>
        <Typography variant="h5" component="h2" sx={{ marginBottom: 2, textAlign: 'center' }}>
          {id ? t('vaults:edit-form-heading') : t('vaults:form-heading')}
        </Typography>
        <Grid container spacing={2} sx={{ width: 600, margin: '0 auto' }}>
          <Grid item xs={6}>
            <FormTextField type="text" label={t('vaults:name')} name="name" />
          </Grid>
          {id ? (
            <></>
          ) : (
            <>
              <Grid item xs={6}>
                <CurrencySelect />
              </Grid>
              <Grid item xs={6}>
                <FormTextField type="text" label={t('vaults:campaignId')} name="campaignId" />
              </Grid>
            </>
          )}
          <Grid item xs={6}>
            <SubmitButton fullWidth label={t('vaults:cta:submit')} />
          </Grid>
          <Grid item xs={6}>
            <Link href={routes.admin.vaults.index} passHref>
              <Button>{t('vaults:cta:cancel')}</Button>
            </Link>
          </Grid>
        </Grid>
      </Box>
    </GenericForm>
  )
}
Example #8
Source File: useQuery.ts    From react-starter-boilerplate with MIT License 5 votes vote down vote up
useQuery = <TData = unknown, TError = unknown>(
  queryKey: QueryKey,
  options?: UseQueryOptions<TData, TError>,
): UseQueryResult<TData, TError> => {
  const { queryFn } = useApiClient();
  const _queryFn = useMemo(() => queryFn<TData>(), [queryFn]);
  return useRqQuery<TData, TError, TData, QueryKey>(queryKey, _queryFn, options);
}
Example #9
Source File: EditForm.tsx    From frontend with MIT License 5 votes vote down vote up
export default function EditForm() {
  const router = useRouter()
  const id = String(router.query.id)
  const { t } = useTranslation()
  const { data }: UseQueryResult<CityResponse> = useCity(String(id))

  const initialValues: CityInput = {
    name: data?.name,
    postalCode: data?.postalCode,
    countryId: data?.countryId,
  }

  const mutationFn = id ? useEditCity(id) : useCreateCity()

  const mutation = useMutation<AxiosResponse<CityResponse>, AxiosError<ApiErrors>, CityInput>({
    mutationFn,
    onError: () => AlertStore.show(t('cities:alerts:error'), 'error'),
    onSuccess: () => {
      AlertStore.show(t('cities:alerts:edit'), 'success')
      router.push(routes.admin.cities.home)
    },
  })

  async function onSubmit(values: CityInput) {
    const data = {
      name: values.name,
      postalCode: values.postalCode,
      countryId: values.countryId,
    }
    mutation.mutate(data)
  }

  return (
    <GenericForm
      onSubmit={onSubmit}
      initialValues={initialValues}
      validationSchema={validationSchema}>
      <Box sx={{ marginTop: '5%', height: '62.6vh' }}>
        <Typography variant="h5" component="h2" sx={{ marginBottom: 2, textAlign: 'center' }}>
          {id ? t('cities:edit-form-heading') : t('cities:form-heading')}
        </Typography>
        <Grid container spacing={2} sx={{ width: 600, margin: '0 auto' }}>
          <Grid item xs={12}>
            <FormTextField type="text" label="Cities: Име" name="name" autoComplete="name" />
          </Grid>
          <Grid item xs={12}>
            <FormTextField
              type="string"
              label="Cities:Пощенски код"
              name="postalCode"
              autoComplete="postal-code"
            />
          </Grid>
          <Grid item xs={12}>
            <SelectCountry />
          </Grid>
          <Grid item xs={6}>
            <SubmitButton fullWidth label={t('cities:cta:submit')} />
          </Grid>
          <Grid item xs={6}>
            <Link href={routes.admin.cities.home} passHref>
              <Button fullWidth>{t('cities:cta:cancel')}</Button>
            </Link>
          </Grid>
        </Grid>
      </Box>
    </GenericForm>
  )
}
Example #10
Source File: use-get-vaults.tsx    From interbtc-ui with Apache License 2.0 5 votes vote down vote up
parseVaults = (vaults: Array<UseQueryResult<unknown, unknown>>): Array<VaultExt<BitcoinUnit>> =>
  vaults.filter(vault => !vault.isLoading && vault.isSuccess).map(vault => vault.data as VaultExt<BitcoinUnit>)
Example #11
Source File: useEthersNetworkQuery.ts    From crust-apps with Apache License 2.0 5 votes vote down vote up
useEthersNetworkQuery = (): UseQueryResult<ethers.providers.Network> => {
  const { instance, provider } = useEthers();

  return useQuery(
    [EthersNetworkQueryKey, provider?.network, instance],
    async () => await provider?.getNetwork()
  );
}
Example #12
Source File: Grid.tsx    From frontend with MIT License 4 votes vote down vote up
export default function Grid() {
  const { t } = useTranslation('recurring-donation')
  const { data }: UseQueryResult<RecurringDonationResponse[]> = useRecurringDonationList()
  const [pageSize, setPageSize] = useState(5)

  const commonProps: Partial<GridColDef> = {
    align: 'left',
    width: 150,
    headerAlign: 'left',
  }

  const columns: GridColumns = [
    {
      field: 'status',
      headerName: t('recurring-donation:status'),
      flex: 1.5,
      ...commonProps,
    },
    {
      field: 'currency',
      headerName: t('currency'),
      flex: 1.5,
      ...commonProps,
    },
    {
      field: 'amount',
      headerName: t('amount'),
      flex: 1.5,
      ...commonProps,
    },
    {
      field: 'extSubscriptionId',
      headerName: t('extSubscriptionId'),
      ...commonProps,
      width: 300,
    },
    {
      field: 'extCustomerId',
      headerName: t('extCustomerId'),
      ...commonProps,
      width: 300,
    },
    {
      field: 'personId',
      headerName: t('personId'),
      ...commonProps,
      width: 300,
    },
    {
      field: 'vaultId',
      headerName: t('vaultId'),
      ...commonProps,
      width: 300,
    },
    {
      field: 'actions',
      headerName: t('actions'),
      width: 120,
      type: 'actions',
      headerAlign: 'center',
      renderCell: (params: GridRenderCellParams): React.ReactNode => {
        return (
          <GridActions
            modalStore={ModalStore}
            id={params.row.id}
            name={params.row.name}
            editLink={routes.admin.recurringDonation.view(params.row.id)}
          />
        )
      },
    },
  ]

  return (
    <>
      <Box sx={{ marginTop: '2%', mx: 'auto', width: 700 }}>
        <DataGrid
          style={{
            background: 'white',
            position: 'absolute',
            height: 'calc(100vh - 300px)',
            border: 'none',
            width: 'calc(100% - 48px)',
            left: '24px',
            overflowY: 'auto',
            overflowX: 'hidden',
            borderRadius: '0 0 13px 13px',
          }}
          rows={data || []}
          columns={columns}
          rowsPerPageOptions={[5, 10]}
          pageSize={pageSize}
          onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
          disableSelectionOnClick
        />
      </Box>
      <DetailsModal />
      <DeleteModal />
    </>
  )
}
Example #13
Source File: client.tsx    From mui-toolpad with MIT License 4 votes vote down vote up
function QueryEditor({
  appId,
  connectionId,
  value,
  onChange,
}: QueryEditorProps<GoogleSheetsApiQuery>) {
  const [spreadsheetQuery, setSpreadsheetQuery] = React.useState<string | null>(null);

  const debouncedSpreadsheetQuery = useDebounced(spreadsheetQuery, 300);

  const fetchedFiles: UseQueryResult<GoogleDriveFiles> = client.useQuery('dataSourceFetchPrivate', [
    appId,
    connectionId,
    {
      type: GoogleSheetsPrivateQueryType.FILES_LIST,
      spreadsheetQuery: debouncedSpreadsheetQuery,
    },
  ]);

  const fetchedFile: UseQueryResult<GoogleDriveFile> = client.useQuery(
    'dataSourceFetchPrivate',
    value.spreadsheetId
      ? [
          appId,
          connectionId,
          {
            type: GoogleSheetsPrivateQueryType.FILE_GET,
            spreadsheetId: value.spreadsheetId,
          },
        ]
      : null,
  );

  const fetchedSpreadsheet: UseQueryResult<GoogleSpreadsheet> = client.useQuery(
    'dataSourceFetchPrivate',
    value.spreadsheetId
      ? [
          appId,
          connectionId,
          {
            type: GoogleSheetsPrivateQueryType.FETCH_SPREADSHEET,
            spreadsheetId: value.spreadsheetId,
          },
        ]
      : null,
  );

  const selectedSheet = React.useMemo(
    () =>
      fetchedSpreadsheet.data?.sheets?.find(
        (sheet) => sheet.properties?.title === value.sheetName,
      ) ?? null,
    [fetchedSpreadsheet, value],
  );

  const handleSpreadsheetChange = React.useCallback(
    (event, newValue: GoogleDriveFile | null) => {
      onChange({
        ...value,
        sheetName: null,
        spreadsheetId: newValue?.id ?? null,
      });
    },
    [onChange, value],
  );

  const handleSheetChange = React.useCallback(
    (event, newValue: GoogleSheet | null) => {
      onChange({
        ...value,
        sheetName: newValue?.properties?.title ?? null,
      });
    },
    [onChange, value],
  );

  const handleRangeChange = React.useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      onChange({
        ...value,
        ranges: event.target.value,
      });
    },
    [onChange, value],
  );

  const handleTransformChange = React.useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      onChange({
        ...value,
        headerRow: event.target.checked,
      });
    },
    [onChange, value],
  );

  const handleSpreadsheetInput = React.useCallback(
    (event: React.SyntheticEvent, input: string, reason: string) => {
      if (reason === 'input') {
        setSpreadsheetQuery(input);
      }
    },
    [],
  );

  return (
    <Stack direction="column" gap={2}>
      <Autocomplete
        fullWidth
        value={fetchedFile.data ?? null}
        loading={fetchedFiles.isLoading}
        loadingText={'Loading...'}
        options={fetchedFiles.data?.files ?? []}
        getOptionLabel={(option: GoogleDriveFile) => option.name ?? ''}
        onInputChange={handleSpreadsheetInput}
        onChange={handleSpreadsheetChange}
        isOptionEqualToValue={(option: GoogleDriveFile, val: GoogleDriveFile) =>
          option.id === val.id
        }
        renderInput={(params) => <TextField {...params} label="Select spreadsheet" />}
        renderOption={(props, option) => {
          return (
            <li {...props} key={option.id}>
              {option.name}
            </li>
          );
        }}
      />
      <Autocomplete
        fullWidth
        loading={fetchedSpreadsheet.isLoading}
        value={selectedSheet}
        loadingText={'Loading...'}
        options={fetchedSpreadsheet.data?.sheets ?? []}
        getOptionLabel={(option: GoogleSheet) => option.properties?.title ?? ''}
        onChange={handleSheetChange}
        renderInput={(params) => <TextField {...params} label="Select sheet" />}
        renderOption={(props, option) => {
          return (
            <li {...props} key={option?.properties?.sheetId}>
              {option?.properties?.title}
            </li>
          );
        }}
      />
      <TextField
        label="Range"
        helperText={`In the form of A1:Z999`}
        value={value.ranges}
        disabled={!value.sheetName}
        onChange={handleRangeChange}
      />
      <FormControlLabel
        label="First row contains column headers"
        control={
          <Checkbox
            checked={value.headerRow}
            onChange={handleTransformChange}
            inputProps={{ 'aria-label': 'controlled' }}
          />
        }
      />
    </Stack>
  );
}
Example #14
Source File: AmountSelect.tsx    From rari-dApp with GNU Affero General Public License v3.0 4 votes vote down vote up
StatsColumn = ({
  color,
  mode,
  assets,
  index,
  amount,
  symbol,
  enableAsCollateral,
}: {
  color: string;
  mode: Mode;
  assets: USDPricedFuseAsset[];
  index: number;
  amount: number;
  symbol: string;
  enableAsCollateral: boolean;
}) => {
  const { t } = useTranslation();

  const { rari, fuse } = useRari();

  const { data: updatedAssets }: UseQueryResult<USDPricedFuseAsset[]> =
    useQuery(
      mode + " " + index + " " + JSON.stringify(assets) + " " + amount,
      async () => {
        const ethPrice: number = fuse.web3.utils.fromWei(
          await rari.getEthUsdPriceBN()
        ) as any;

        const assetToBeUpdated = assets[index];

        const interestRateModel = await fuse.getInterestRateModel(
          assetToBeUpdated.cToken
        );

        let updatedAsset: USDPricedFuseAsset;
        if (mode === Mode.SUPPLY) {
          const supplyBalance =
            parseInt(assetToBeUpdated.supplyBalance as any) + amount;

          const totalSupply =
            parseInt(assetToBeUpdated.totalSupply as any) + amount;

          updatedAsset = {
            ...assetToBeUpdated,

            supplyBalance,
            supplyBalanceUSD:
              ((supplyBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
              ethPrice,

            totalSupply,
            supplyRatePerBlock: interestRateModel.getSupplyRate(
              fuse.web3.utils.toBN(
                totalSupply > 0
                  ? new BigNumber(assetToBeUpdated.totalBorrow)
                    .dividedBy(totalSupply.toString())
                    .multipliedBy(1e18)
                    .toFixed(0)
                  : 0
              )
            ),
          };
        } else if (mode === Mode.WITHDRAW) {
          const supplyBalance =
            parseInt(assetToBeUpdated.supplyBalance as any) - amount;

          const totalSupply =
            parseInt(assetToBeUpdated.totalSupply as any) - amount;

          updatedAsset = {
            ...assetToBeUpdated,

            supplyBalance,
            supplyBalanceUSD:
              ((supplyBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
              ethPrice,

            totalSupply,
            supplyRatePerBlock: interestRateModel.getSupplyRate(
              fuse.web3.utils.toBN(
                totalSupply > 0
                  ? new BigNumber(assetToBeUpdated.totalBorrow)
                    .dividedBy(totalSupply.toString())
                    .multipliedBy(1e18)
                    .toFixed(0)
                  : 0
              )
            ),
          };
        } else if (mode === Mode.BORROW) {
          const borrowBalance =
            parseInt(assetToBeUpdated.borrowBalance as any) + amount;

          const totalBorrow =
            parseInt(assetToBeUpdated.totalBorrow as any) + amount;

          updatedAsset = {
            ...assetToBeUpdated,

            borrowBalance,
            borrowBalanceUSD:
              ((borrowBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
              ethPrice,

            totalBorrow,
            borrowRatePerBlock: interestRateModel.getBorrowRate(
              fuse.web3.utils.toBN(
                assetToBeUpdated.totalSupply > 0
                  ? new BigNumber(totalBorrow.toString())
                    .dividedBy(assetToBeUpdated.totalSupply)
                    .multipliedBy(1e18)
                    .toFixed(0)
                  : 0
              )
            ),
          };
        } else if (mode === Mode.REPAY) {
          const borrowBalance =
            parseInt(assetToBeUpdated.borrowBalance as any) - amount;

          const totalBorrow =
            parseInt(assetToBeUpdated.totalBorrow as any) - amount;

          updatedAsset = {
            ...assetToBeUpdated,

            borrowBalance,
            borrowBalanceUSD:
              ((borrowBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
              ethPrice,

            totalBorrow,
            borrowRatePerBlock: interestRateModel.getBorrowRate(
              fuse.web3.utils.toBN(
                assetToBeUpdated.totalSupply > 0
                  ? new BigNumber(totalBorrow.toString())
                    .dividedBy(assetToBeUpdated.totalSupply)
                    .multipliedBy(1e18)
                    .toFixed(0)
                  : 0
              )
            ),
          };
        }

        return assets.map((value, _index) => {
          if (_index === index) {
            return updatedAsset;
          } else {
            return value;
          }
        });
      }
    );

  const asset = assets[index];
  const updatedAsset = updatedAssets ? updatedAssets[index] : null;

  const borrowLimit = useBorrowLimit(assets);
  const updatedBorrowLimit = useBorrowLimit(
    updatedAssets ?? [],
    enableAsCollateral
      ? {
        ignoreIsEnabledCheckFor: asset.cToken,
      }
      : undefined
  );

  const isSupplyingOrWithdrawing =
    mode === Mode.SUPPLY || mode === Mode.WITHDRAW;

  const supplyAPY = convertMantissaToAPY(asset.supplyRatePerBlock, 365);
  const borrowAPY = convertMantissaToAPY(asset.borrowRatePerBlock, 365);

  const updatedSupplyAPY = convertMantissaToAPY(
    updatedAsset?.supplyRatePerBlock ?? 0,
    365
  );
  const updatedBorrowAPY = convertMantissaToAPY(
    updatedAsset?.borrowRatePerBlock ?? 0,
    365
  );

  // If the difference is greater than a 0.1 percentage point change, alert the user
  const updatedAPYDiffIsLarge = isSupplyingOrWithdrawing
    ? Math.abs(updatedSupplyAPY - supplyAPY) > 0.1
    : Math.abs(updatedBorrowAPY - borrowAPY) > 0.1;

  return (
    <DashboardBox width="100%" height="190px" mt={4}>
      {updatedAsset ? (
        <Column
          mainAxisAlignment="space-between"
          crossAxisAlignment="flex-start"
          expand
          py={3}
          px={4}
          fontSize="lg"
        >
          <Row
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            width="100%"
            color={color}
          >
            <Text fontWeight="bold" flexShrink={0}>
              {t("Supply Balance")}:
            </Text>
            <Text
              fontWeight="bold"
              flexShrink={0}
              fontSize={isSupplyingOrWithdrawing ? "sm" : "lg"}
            >
              {smallUsdFormatter(
                asset.supplyBalance / 10 ** asset.underlyingDecimals
              ).replace("$", "")}
              {isSupplyingOrWithdrawing ? (
                <>
                  {" → "}
                  {smallUsdFormatter(
                    updatedAsset!.supplyBalance /
                    10 ** updatedAsset!.underlyingDecimals
                  ).replace("$", "")}
                </>
              ) : null}{" "}
              {symbol}
            </Text>
          </Row>

          <Row
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            width="100%"
          >
            <Text fontWeight="bold" flexShrink={0}>
              {isSupplyingOrWithdrawing ? t("Supply APY") : t("Borrow APY")}:
            </Text>
            <Text
              fontWeight="bold"
              fontSize={updatedAPYDiffIsLarge ? "sm" : "lg"}
            >
              {isSupplyingOrWithdrawing
                ? supplyAPY.toFixed(2)
                : borrowAPY.toFixed(2)}
              %
              {updatedAPYDiffIsLarge ? (
                <>
                  {" → "}
                  {isSupplyingOrWithdrawing
                    ? updatedSupplyAPY.toFixed(2)
                    : updatedBorrowAPY.toFixed(2)}
                  %
                </>
              ) : null}
            </Text>
          </Row>

          <Row
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            width="100%"
          >
            <Text fontWeight="bold" flexShrink={0}>
              {t("Borrow Limit")}:
            </Text>
            <Text
              fontWeight="bold"
              fontSize={isSupplyingOrWithdrawing ? "sm" : "lg"}
            >
              {smallUsdFormatter(borrowLimit)}
              {isSupplyingOrWithdrawing ? (
                <>
                  {" → "} {smallUsdFormatter(updatedBorrowLimit)}
                </>
              ) : null}{" "}
            </Text>
          </Row>

          <Row
            mainAxisAlignment="space-between"
            crossAxisAlignment="center"
            width="100%"
          >
            <Text fontWeight="bold">{t("Debt Balance")}:</Text>
            <Text
              fontWeight="bold"
              fontSize={!isSupplyingOrWithdrawing ? "sm" : "lg"}
            >
              {smallUsdFormatter(asset.borrowBalanceUSD)}
              {!isSupplyingOrWithdrawing ? (
                <>
                  {" → "}
                  {smallUsdFormatter(updatedAsset.borrowBalanceUSD)}
                </>
              ) : null}
            </Text>
          </Row>
        </Column>
      ) : (
        <Center expand>
          <Spinner />
        </Center>
      )}
    </DashboardBox>
  );
}