Commit f9153184 authored by Max Alekseenko's avatar Max Alekseenko

add error handling

parent 650f0838
...@@ -28,7 +28,8 @@ import removeQueryParam from 'lib/router/removeQueryParam'; ...@@ -28,7 +28,8 @@ import removeQueryParam from 'lib/router/removeQueryParam';
import useAccount from 'lib/web3/useAccount'; import useAccount from 'lib/web3/useAccount';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery'; import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
type ContextQueryResult<Response> = Pick<UseQueryResult<Response, ResourceError<unknown>>, 'data' | 'isLoading' | 'refetch' | 'isPending' | 'isFetching'>; type ContextQueryResult<Response> =
Pick<UseQueryResult<Response, ResourceError<unknown>>, 'data' | 'isLoading' | 'refetch' | 'isPending' | 'isFetching' | 'isError'>;
type TRewardsContext = { type TRewardsContext = {
balancesQuery: ContextQueryResult<RewardsUserBalancesResponse>; balancesQuery: ContextQueryResult<RewardsUserBalancesResponse>;
...@@ -50,6 +51,7 @@ const defaultQueryResult = { ...@@ -50,6 +51,7 @@ const defaultQueryResult = {
isLoading: false, isLoading: false,
isPending: false, isPending: false,
isFetching: false, isFetching: false,
isError: false,
refetch: () => Promise.resolve({} as never), refetch: () => Promise.resolve({} as never),
}; };
......
import { Flex, Skeleton, Image } from '@chakra-ui/react'; import { Flex, Skeleton, Image, Alert } from '@chakra-ui/react';
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import config from 'configs/app'; import config from 'configs/app';
import { useRewardsContext } from 'lib/contexts/rewards'; import { useRewardsContext } from 'lib/contexts/rewards';
...@@ -13,7 +13,8 @@ import PageTitle from 'ui/shared/Page/PageTitle'; ...@@ -13,7 +13,8 @@ import PageTitle from 'ui/shared/Page/PageTitle';
import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken'; import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken';
const RewardsDashboard = () => { const RewardsDashboard = () => {
const { balancesQuery, apiToken, referralsQuery, rewardsConfigQuery, isInitialized } = useRewardsContext(); const { balancesQuery, apiToken, referralsQuery, rewardsConfigQuery, dailyRewardQuery, isInitialized } = useRewardsContext();
const [ isError, setIsError ] = useState(false);
useRedirectForInvalidAuthToken(); useRedirectForInvalidAuthToken();
...@@ -23,7 +24,9 @@ const RewardsDashboard = () => { ...@@ -23,7 +24,9 @@ const RewardsDashboard = () => {
} }
}, [ isInitialized, apiToken ]); }, [ isInitialized, apiToken ]);
const numberOfReferrals = Number(referralsQuery.data?.referrals || 0); useEffect(() => {
setIsError(balancesQuery.isError || referralsQuery.isError || rewardsConfigQuery.isError || dailyRewardQuery.isError);
}, [ balancesQuery.isError, referralsQuery.isError, rewardsConfigQuery.isError, dailyRewardQuery.isError ]);
if (!config.features.rewards.isEnabled) { if (!config.features.rewards.isEnabled) {
return null; return null;
...@@ -44,6 +47,7 @@ const RewardsDashboard = () => { ...@@ -44,6 +47,7 @@ const RewardsDashboard = () => {
) } ) }
/> />
<Flex flexDirection="column" alignItems="flex-start" w="full" gap={ 6 }> <Flex flexDirection="column" alignItems="flex-start" w="full" gap={ 6 }>
{ isError && <Alert status="error">Failed to load some data. Please try again later.</Alert> }
<Flex gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}> <Flex gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardCard <RewardsDashboardCard
description="Claim your daily Merits and any Merits received from referrals." description="Claim your daily Merits and any Merits received from referrals."
...@@ -52,7 +56,7 @@ const RewardsDashboard = () => { ...@@ -52,7 +56,7 @@ const RewardsDashboard = () => {
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
label="Total balance" label="Total balance"
value={ balancesQuery.data?.total || 0 } value={ balancesQuery.data?.total || 'N/A' }
isLoading={ balancesQuery.isPending } isLoading={ balancesQuery.isPending }
withIcon withIcon
hint={ ( hint={ (
...@@ -72,7 +76,10 @@ const RewardsDashboard = () => { ...@@ -72,7 +76,10 @@ const RewardsDashboard = () => {
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
label="Referrals" label="Referrals"
value={ `${ numberOfReferrals } user${ numberOfReferrals === 1 ? '' : 's' }` } value={ referralsQuery.data?.referrals ?
`${ referralsQuery.data?.referrals } user${ Number(referralsQuery.data?.referrals) === 1 ? '' : 's' }` :
'N/A'
}
isLoading={ referralsQuery.isPending } isLoading={ referralsQuery.isPending }
hint="The number of referrals who registered with your code/link." hint="The number of referrals who registered with your code/link."
/> />
...@@ -93,7 +100,10 @@ const RewardsDashboard = () => { ...@@ -93,7 +100,10 @@ const RewardsDashboard = () => {
<> <>
Refer friends and boost your Merits! You receive a{ ' ' } Refer friends and boost your Merits! You receive a{ ' ' }
<Skeleton as="span" isLoaded={ !rewardsConfigQuery.isPending }> <Skeleton as="span" isLoaded={ !rewardsConfigQuery.isPending }>
{ Number(rewardsConfigQuery.data?.rewards.referral_share || 0) * 100 }% { rewardsConfigQuery.data?.rewards.referral_share ?
`${ Number(rewardsConfigQuery.data?.rewards.referral_share) * 100 }%` :
'N/A'
}
</Skeleton> </Skeleton>
{ ' ' }bonus on all Merits earned by your referrals. { ' ' }bonus on all Merits earned by your referrals.
</> </>
...@@ -109,13 +119,13 @@ const RewardsDashboard = () => { ...@@ -109,13 +119,13 @@ const RewardsDashboard = () => {
> >
<RewardsReadOnlyInputWithCopy <RewardsReadOnlyInputWithCopy
label="Referral link" label="Referral link"
value={ referralsQuery.data?.link || '' } value={ referralsQuery.data?.link || 'N/A' }
isLoading={ referralsQuery.isPending } isLoading={ referralsQuery.isPending }
flex={ 2 } flex={ 2 }
/> />
<RewardsReadOnlyInputWithCopy <RewardsReadOnlyInputWithCopy
label="Referral code" label="Referral code"
value={ referralsQuery.data?.code || '' } value={ referralsQuery.data?.code || 'N/A' }
isLoading={ referralsQuery.isPending } isLoading={ referralsQuery.isPending }
flex={ 1 } flex={ 1 }
/> />
......
...@@ -59,7 +59,7 @@ const RewardsButton = ({ variant = 'header', size }: Props) => { ...@@ -59,7 +59,7 @@ const RewardsButton = ({ variant = 'header', size }: Props) => {
ml={ 2 } ml={ 2 }
fontWeight={ apiToken ? '700' : '600' } fontWeight={ apiToken ? '700' : '600' }
> >
{ apiToken ? balancesQuery.data?.total : 'Merits' } { apiToken ? (balancesQuery.data?.total || 'N/A') : 'Merits' }
</chakra.span> </chakra.span>
</Button> </Button>
</Tooltip> </Tooltip>
......
...@@ -77,7 +77,7 @@ const DailyRewardClaimButton = () => { ...@@ -77,7 +77,7 @@ const DailyRewardClaimButton = () => {
fontWeight="600" fontWeight="600"
cursor="default" cursor="default"
> >
Next claim in { timeLeft } Next claim in { timeLeft || 'N/A' }
</Flex> </Flex>
) : ( ) : (
<Button onClick={ handleClaim } isLoading={ isLoading }> <Button onClick={ handleClaim } isLoading={ isLoading }>
......
...@@ -16,12 +16,12 @@ type Props = { ...@@ -16,12 +16,12 @@ type Props = {
const CongratsStepContent = ({ isReferral }: Props) => { const CongratsStepContent = ({ isReferral }: Props) => {
const { referralsQuery, rewardsConfigQuery } = useRewardsContext(); const { referralsQuery, rewardsConfigQuery } = useRewardsContext();
const registrationReward = rewardsConfigQuery.data?.rewards.registration || 0; const registrationReward = rewardsConfigQuery.data?.rewards.registration;
const registrationWithReferralReward = rewardsConfigQuery.data?.rewards.registration_with_referral || 0; const registrationWithReferralReward = rewardsConfigQuery.data?.rewards.registration_with_referral;
const referralReward = Number(registrationWithReferralReward) - Number(registrationReward); const referralReward = Number(registrationWithReferralReward) - Number(registrationReward);
const refLink = referralsQuery.data?.link || ''; const refLink = referralsQuery.data?.link || 'N/A';
const shareText = `I joined the @blockscoutcom Merits Program and got my first ${ registrationReward } #Merits! Use this link for a sign-up bonus and start earning rewards with @blockscoutcom block explorer.\n\n${ refLink }`; // eslint-disable-line max-len const shareText = `I joined the @blockscoutcom Merits Program and got my first ${ registrationReward || 'N/A' } #Merits! Use this link for a sign-up bonus and start earning rewards with @blockscoutcom block explorer.\n\n${ refLink }`; // eslint-disable-line max-len
const textColor = useColorModeValue('blue.700', 'blue.100'); const textColor = useColorModeValue('blue.700', 'blue.100');
const dividerColor = useColorModeValue('whiteAlpha.800', 'whiteAlpha.100'); const dividerColor = useColorModeValue('whiteAlpha.800', 'whiteAlpha.100');
...@@ -40,7 +40,7 @@ const CongratsStepContent = ({ isReferral }: Props) => { ...@@ -40,7 +40,7 @@ const CongratsStepContent = ({ isReferral }: Props) => {
<MeritsIcon boxSize={{ base: isReferral ? 8 : 12, md: 12 }} mr={{ base: isReferral ? 1 : 2, md: 2 }}/> <MeritsIcon boxSize={{ base: isReferral ? 8 : 12, md: 12 }} mr={{ base: isReferral ? 1 : 2, md: 2 }}/>
<Skeleton isLoaded={ !rewardsConfigQuery.isLoading }> <Skeleton isLoaded={ !rewardsConfigQuery.isLoading }>
<Text fontSize={{ base: isReferral ? '24px' : '30px', md: '30px' }} fontWeight="700" color={ textColor }> <Text fontSize={{ base: isReferral ? '24px' : '30px', md: '30px' }} fontWeight="700" color={ textColor }>
+{ rewardsConfigQuery.data?.rewards[ isReferral ? 'registration_with_referral' : 'registration' ] } +{ rewardsConfigQuery.data?.rewards[ isReferral ? 'registration_with_referral' : 'registration' ] || 'N/A' }
</Text> </Text>
</Skeleton> </Skeleton>
{ isReferral && ( { isReferral && (
...@@ -50,11 +50,11 @@ const CongratsStepContent = ({ isReferral }: Props) => { ...@@ -50,11 +50,11 @@ const CongratsStepContent = ({ isReferral }: Props) => {
{ [ { [
{ {
title: 'Registration', title: 'Registration',
value: registrationReward, value: registrationReward || 'N/A',
}, },
{ {
title: 'Referral program', title: 'Referral program',
value: referralReward, value: referralReward || 'N/A',
}, },
].map(({ title, value }) => ( ].map(({ title, value }) => (
<Flex key={ title } alignItems="center" gap={{ base: 1, md: 2 }}> <Flex key={ title } alignItems="center" gap={{ base: 1, md: 2 }}>
...@@ -85,7 +85,10 @@ const CongratsStepContent = ({ isReferral }: Props) => { ...@@ -85,7 +85,10 @@ const CongratsStepContent = ({ isReferral }: Props) => {
<Text fontSize="md" mt={ 2 }> <Text fontSize="md" mt={ 2 }>
Receive a{ ' ' } Receive a{ ' ' }
<Skeleton as="span" isLoaded={ !rewardsConfigQuery.isLoading }> <Skeleton as="span" isLoaded={ !rewardsConfigQuery.isLoading }>
{ Number(rewardsConfigQuery.data?.rewards.referral_share || 0) * 100 }% { rewardsConfigQuery.data?.rewards.referral_share ?
`${ Number(rewardsConfigQuery.data?.rewards.referral_share) * 100 }%` :
'N/A'
}
</Skeleton> </Skeleton>
{ ' ' }bonus on all Merits earned by your referrals { ' ' }bonus on all Merits earned by your referrals
</Text> </Text>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment