Commit 748f0233 authored by Max Alekseenko's avatar Max Alekseenko

rewards dashboard updates and refactoring

parent de239116
import { Button, Flex, Skeleton, Text, useBoolean, useColorModeValue } from '@chakra-ui/react'; import { Button, Flex, Skeleton, useBoolean } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { useRewardsContext } from 'lib/contexts/rewards'; import { useRewardsContext } from 'lib/contexts/rewards';
import { apos } from 'lib/html-entities';
import splitSecondsInPeriods from 'ui/blockCountdown/splitSecondsInPeriods'; import splitSecondsInPeriods from 'ui/blockCountdown/splitSecondsInPeriods';
import CopyField from 'ui/rewards/CopyField'; import CopyField from 'ui/rewards/CopyField';
import RewardsDashboardCard from 'ui/rewards/RewardsDashboardCard'; import RewardsDashboardCard from 'ui/rewards/RewardsDashboardCard';
import HintPopover from 'ui/shared/HintPopover'; import RewardsDashboardCardValue from 'ui/rewards/RewardsDashboardCardValue';
import LinkExternal from 'ui/shared/links/LinkExternal'; import LinkExternal from 'ui/shared/links/LinkExternal';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
...@@ -57,6 +58,8 @@ const RewardsDashboard = () => { ...@@ -57,6 +58,8 @@ const RewardsDashboard = () => {
return () => clearInterval(interval); return () => clearInterval(interval);
}, [ dailyRewardQuery ]); }, [ dailyRewardQuery ]);
const numberOfReferrals = Number(referralsQuery.data?.referrals || 0);
return ( return (
<> <>
<PageTitle <PageTitle
...@@ -75,20 +78,7 @@ const RewardsDashboard = () => { ...@@ -75,20 +78,7 @@ const RewardsDashboard = () => {
<Flex gap={ 6 }> <Flex gap={ 6 }>
<RewardsDashboardCard <RewardsDashboardCard
description="Claim your daily merits and any merits received from referrals." description="Claim your daily merits and any merits received from referrals."
values={ [ direction="column-reverse"
{
label: 'Total balance',
value: balancesQuery.data?.total,
hint: (
<>
Total number of merits earned from all activities.{ ' ' }
<LinkExternal href="https://docs.blockscout.com/using-blockscout/my-account/merits">
More info on merits
</LinkExternal>
</>
),
},
] }
contentAfter={ ( contentAfter={ (
<Button isDisabled={ !dailyRewardQuery.data?.available } onClick={ handleClaim } isLoading={ isClaiming }> <Button isDisabled={ !dailyRewardQuery.data?.available } onClick={ handleClaim } isLoading={ isClaiming }>
{ dailyRewardQuery.data?.available ? { dailyRewardQuery.data?.available ?
...@@ -97,49 +87,55 @@ const RewardsDashboard = () => { ...@@ -97,49 +87,55 @@ const RewardsDashboard = () => {
} }
</Button> </Button>
) } ) }
/> >
<RewardsDashboardCardValue
label="Total balance"
value={ balancesQuery.data?.total }
withIcon
hint={ (
<>
Total number of merits earned from all activities.{ ' ' }
<LinkExternal href="https://docs.blockscout.com/using-blockscout/my-account/merits">
More info on merits
</LinkExternal>
</>
) }
/>
</RewardsDashboardCard>
<RewardsDashboardCard <RewardsDashboardCard
title="Title" title="Referrals"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do." description="Total number of users who joined the program through your referral link."
values={ [ { label: 'Staked amount', value: 0 } ] } direction="column-reverse"
availableSoon >
/> <RewardsDashboardCardValue
label="Referrals"
value={ `${ numberOfReferrals } user${ numberOfReferrals === 1 ? '' : 's' }` }
hint="The number of referrals who registered with your code."
/>
</RewardsDashboardCard>
<RewardsDashboardCard <RewardsDashboardCard
title="Title" title="Steaks"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do." description={ `Current number of consecutive days you${ apos }ve claimed your daily Merits.` }
values={ [ { label: 'Staking rewards', value: 0 } ] } direction="column-reverse"
availableSoon availableSoon
/> >
<RewardsDashboardCardValue label="Steaks" value="5 days"/>
</RewardsDashboardCard>
</Flex> </Flex>
<Flex <RewardsDashboardCard
gap={ 10 } title="Referral program"
w="full" description={ (
border="1px solid" <>
borderColor={ useColorModeValue('gray.200', 'whiteAlpha.200') }
borderRadius="lg"
p={ 2 }
>
<Flex flexDirection="column" gap={ 2 } p={ 3 } w="340px">
<Text fontSize="lg" fontWeight="500">
Referral program
</Text>
<Text fontSize="sm">
Refer friends and boost your merits! You receive a{ ' ' } Refer friends and boost your merits! You receive a{ ' ' }
<Skeleton as="span" isLoaded={ !rewardsConfigQuery.isLoading }> <Skeleton as="span" isLoaded={ !rewardsConfigQuery.isLoading }>
{ Number(rewardsConfigQuery.data?.rewards.referral_share || 0) * 100 }% { Number(rewardsConfigQuery.data?.rewards.referral_share || 0) * 100 }%
</Skeleton> </Skeleton>
{ ' ' }bonus on all merits earned by your referrals. { ' ' }bonus on all merits earned by your referrals.
</Text> </>
</Flex> ) }
<Flex direction="row"
flex={ 1 } >
alignItems="center" <Flex flex={ 1 } gap={ 6 } px={ 6 }>
gap={ 6 }
borderRadius="8px"
backgroundColor={ useColorModeValue('gray.50', 'whiteAlpha.50') }
px={ 6 }
flexShrink={ 0 }
>
<CopyField <CopyField
label="Referral link" label="Referral link"
value={ `https://eth.blockscout.com?ref=${ referralsQuery.data?.code }` } value={ `https://eth.blockscout.com?ref=${ referralsQuery.data?.code }` }
...@@ -150,38 +146,25 @@ const RewardsDashboard = () => { ...@@ -150,38 +146,25 @@ const RewardsDashboard = () => {
value={ referralsQuery.data?.code || '' } value={ referralsQuery.data?.code || '' }
isLoading={ referralsQuery.isLoading } isLoading={ referralsQuery.isLoading }
/> />
<Flex flexDirection="column">
<Flex alignItems="center" gap={ 1 } w="120px">
<HintPopover
label="The number of referrals who registered with your code."
popoverContentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '210px' } }}
popoverBodyProps={{ textAlign: 'center' }}
/>
<Text fontSize="xs" fontWeight="500" variant="secondary">
Referrals
</Text>
</Flex>
<Skeleton isLoaded={ !referralsQuery.isLoading }>
<Text fontSize="32px" fontWeight="500">
{ referralsQuery.data?.referrals || 0 }
</Text>
</Skeleton>
</Flex>
</Flex> </Flex>
</Flex> </RewardsDashboardCard>
<Flex gap={ 6 }> <Flex gap={ 6 }>
<RewardsDashboardCard <RewardsDashboardCard
title="Activity" title="Activity"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
values={ [ { label: 'Activity', value: 0, type: 'percentages' }, { label: 'Received', value: 0 } ] }
availableSoon availableSoon
/> >
<RewardsDashboardCardValue label="Activity" value="0%"/>
<RewardsDashboardCardValue label="Received" value="0" withIcon/>
</RewardsDashboardCard>
<RewardsDashboardCard <RewardsDashboardCard
title="Verify contracts" title="Verify contracts"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
values={ [ { label: 'Activity', value: 0, type: 'percentages' }, { label: 'Received', value: 0 } ] }
availableSoon availableSoon
/> >
<RewardsDashboardCardValue label="Activity" value="0%"/>
<RewardsDashboardCardValue label="Received" value="0" withIcon/>
</RewardsDashboardCard>
</Flex> </Flex>
</Flex> </Flex>
</> </>
......
import { Flex, Text, useColorModeValue } from '@chakra-ui/react'; import { Flex, Text, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import HintPopover from 'ui/shared/HintPopover';
import IconSvg from 'ui/shared/IconSvg';
import AvailableSoonLabel from './AvailableSoonLabel'; import AvailableSoonLabel from './AvailableSoonLabel';
type Value = {
label: string;
value: number | string | undefined;
type?: 'percentages';
hint?: string | React.ReactNode;
}
type Props = { type Props = {
title?: string; title?: string;
description: string; description: string | React.ReactNode;
values: Array<Value>;
availableSoon?: boolean; availableSoon?: boolean;
contentAfter?: React.ReactNode; contentAfter?: React.ReactNode;
direction?: 'column' | 'column-reverse' | 'row';
reverse?: boolean;
children?: React.ReactNode;
}; };
const RewardsDashboardCard = ({ title, description, values, availableSoon, contentAfter }: Props) => { const RewardsDashboardCard = ({ title, description, availableSoon, contentAfter, direction = 'column', children }: Props) => {
return ( return (
<Flex <Flex
flexDirection="column" flexDirection={ direction }
justifyContent={ direction === 'column-reverse' ? 'flex-end' : 'flex-start' }
p={ 2 } p={ 2 }
border="1px solid" border="1px solid"
borderColor={ useColorModeValue('gray.200', 'whiteAlpha.200') } borderColor={ useColorModeValue('gray.200', 'whiteAlpha.200') }
borderRadius="lg" borderRadius="lg"
gap={ 1 } gap={ direction === 'row' ? 10 : 1 }
w={ direction === 'row' ? 'full' : 'auto' }
> >
<Flex <Flex flexDirection="column" gap={ 2 } p={ 3 } w={ direction === 'row' ? '340px' : 'full' }>
alignItems="center"
justifyContent="space-around"
borderRadius="8px"
backgroundColor={ useColorModeValue('gray.50', 'whiteAlpha.50') }
h="128px"
filter="auto"
blur={ availableSoon ? '4px' : '0' }
>
{ values.map(({ label, value, type, hint }) => (
<Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }>
<Flex alignItems="center" gap={ 1 }>
{ hint && (
<HintPopover
label={ hint }
popoverContentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '210px' } }}
popoverBodyProps={{ textAlign: 'center' }}
/>
) }
<Text fontSize="xs" fontWeight="500" variant="secondary">
{ label }
</Text>
</Flex>
<Flex alignItems="center">
{ !type && <IconSvg name="merits_colored" boxSize={ 12 }/> }
<Text fontSize="32px" fontWeight="500">
{ type === 'percentages' ? `${ value }%` : value }
</Text>
</Flex>
</Flex>
)) }
</Flex>
<Flex flexDirection="column" gap={ 2 } p={ 3 }>
{ title && ( { title && (
<Flex alignItems="center" gap={ 2 }> <Flex alignItems="center" gap={ 2 }>
<Text fontSize="lg" fontWeight="500">{ title }</Text> <Text fontSize="lg" fontWeight="500">{ title }</Text>
...@@ -75,6 +37,18 @@ const RewardsDashboardCard = ({ title, description, values, availableSoon, conte ...@@ -75,6 +37,18 @@ const RewardsDashboardCard = ({ title, description, values, availableSoon, conte
</Text> </Text>
{ contentAfter } { contentAfter }
</Flex> </Flex>
<Flex
alignItems="center"
justifyContent="space-around"
borderRadius="8px"
backgroundColor={ useColorModeValue('gray.50', 'whiteAlpha.50') }
h="128px"
filter="auto"
blur={ availableSoon ? '4px' : '0' }
flex={ direction === 'row' ? 1 : '0 1 auto' }
>
{ children }
</Flex>
</Flex> </Flex>
); );
}; };
......
import { Flex, Text } from '@chakra-ui/react';
import React from 'react';
import HintPopover from 'ui/shared/HintPopover';
import IconSvg from 'ui/shared/IconSvg';
type Props = {
label: string;
value: number | string | undefined;
withIcon?: boolean;
hint?: string | React.ReactNode;
}
const RewardsDashboardCard = ({ label, value, withIcon, hint }: Props) => {
return (
<Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }>
<Flex alignItems="center" gap={ 1 }>
{ hint && (
<HintPopover
label={ hint }
popoverContentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '210px' } }}
popoverBodyProps={{ textAlign: 'center' }}
/>
) }
<Text fontSize="xs" fontWeight="500" variant="secondary">
{ label }
</Text>
</Flex>
<Flex alignItems="center">
{ withIcon && <IconSvg name="merits_colored" boxSize={ 12 }/> }
<Text fontSize="32px" fontWeight="500">
{ value }
</Text>
</Flex>
</Flex>
);
};
export default RewardsDashboardCard;
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