Commit 7531e24b authored by Max Alekseenko's avatar Max Alekseenko

refactoring

parent 0ea25439
...@@ -21,42 +21,33 @@ import useToast from 'lib/hooks/useToast'; ...@@ -21,42 +21,33 @@ import useToast from 'lib/hooks/useToast';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import removeQueryParam from 'lib/router/removeQueryParam'; import removeQueryParam from 'lib/router/removeQueryParam';
type Props = {
children: React.ReactNode;
}
type TRewardsContext = { type TRewardsContext = {
balancesQuery: UseQueryResult<RewardsUserBalancesResponse, ResourceError<unknown>>;
dailyRewardQuery: UseQueryResult<RewardsUserDailyCheckResponse, ResourceError<unknown>>;
referralsQuery: UseQueryResult<RewardsUserReferralsResponse, ResourceError<unknown>>;
rewardsConfigQuery: UseQueryResult<RewardsConfigResponse, ResourceError<unknown>>;
apiToken: string | undefined;
isLoginModalOpen: boolean; isLoginModalOpen: boolean;
openLoginModal: () => void; openLoginModal: () => void;
closeLoginModal: () => void; closeLoginModal: () => void;
balance: RewardsUserBalancesResponse | undefined;
isBalanceLoading: boolean;
refetchBalance: () => void;
dailyReward: RewardsUserDailyCheckResponse | undefined;
isDailyRewardLoading: boolean;
refetchDailyReward: () => void;
apiToken: string | undefined;
login: (refCode: string) => Promise<{ isNewUser?: boolean; invalidRefCodeError?: boolean }>; login: (refCode: string) => Promise<{ isNewUser?: boolean; invalidRefCodeError?: boolean }>;
claim: () => Promise<void>; claim: () => Promise<void>;
referralsQuery: UseQueryResult<RewardsUserReferralsResponse, ResourceError<unknown>>;
rewardsConfigQuery: UseQueryResult<RewardsConfigResponse, ResourceError<unknown>>;
} }
const createDefaultQueryResult = <TData, TError>() =>
({ data: undefined, isLoading: false, refetch: () => {} } as UseQueryResult<TData, TError>);
const RewardsContext = createContext<TRewardsContext>({ const RewardsContext = createContext<TRewardsContext>({
balancesQuery: createDefaultQueryResult<RewardsUserBalancesResponse, ResourceError<unknown>>(),
dailyRewardQuery: createDefaultQueryResult<RewardsUserDailyCheckResponse, ResourceError<unknown>>(),
referralsQuery: createDefaultQueryResult<RewardsUserReferralsResponse, ResourceError<unknown>>(),
rewardsConfigQuery: createDefaultQueryResult<RewardsConfigResponse, ResourceError<unknown>>(),
apiToken: undefined,
isLoginModalOpen: false, isLoginModalOpen: false,
openLoginModal: () => {}, openLoginModal: () => {},
closeLoginModal: () => {}, closeLoginModal: () => {},
balance: undefined,
isBalanceLoading: false,
refetchBalance: () => {},
dailyReward: undefined,
isDailyRewardLoading: false,
refetchDailyReward: () => {},
apiToken: undefined,
login: async() => ({}), login: async() => ({}),
claim: async() => {}, claim: async() => {},
referralsQuery: { data: undefined, isLoading: false, refetch: () => {} } as UseQueryResult<RewardsUserReferralsResponse, ResourceError<unknown>>,
rewardsConfigQuery: { data: undefined, isLoading: false, refetch: () => {} } as UseQueryResult<RewardsConfigResponse, ResourceError<unknown>>,
}); });
function getMessageToSign(address: string, nonce: string, isLogin?: boolean, refCode?: string) { function getMessageToSign(address: string, nonce: string, isLogin?: boolean, refCode?: string) {
...@@ -79,6 +70,10 @@ function getMessageToSign(address: string, nonce: string, isLogin?: boolean, ref ...@@ -79,6 +70,10 @@ function getMessageToSign(address: string, nonce: string, isLogin?: boolean, ref
].join('\n'); ].join('\n');
} }
type Props = {
children: React.ReactNode;
}
export function RewardsContextProvider({ children }: Props) { export function RewardsContextProvider({ children }: Props) {
const router = useRouter(); const router = useRouter();
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
...@@ -196,18 +191,14 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -196,18 +191,14 @@ export function RewardsContextProvider({ children }: Props) {
}, [ apiFetch, errorToast, apiToken ]); }, [ apiFetch, errorToast, apiToken ]);
const value = useMemo(() => ({ const value = useMemo(() => ({
isLoginModalOpen, balancesQuery,
openLoginModal: setIsLoginModalOpen.on, dailyRewardQuery,
closeLoginModal: setIsLoginModalOpen.off,
balance: balancesQuery.data,
isBalanceLoading: balancesQuery.isLoading,
refetchBalance: balancesQuery.refetch,
dailyReward: dailyRewardQuery.data,
isDailyRewardLoading: dailyRewardQuery.isLoading,
refetchDailyReward: dailyRewardQuery.refetch,
referralsQuery, referralsQuery,
rewardsConfigQuery, rewardsConfigQuery,
apiToken, apiToken,
isLoginModalOpen,
openLoginModal: setIsLoginModalOpen.on,
closeLoginModal: setIsLoginModalOpen.off,
login, login,
claim, claim,
}), [ }), [
......
...@@ -25,8 +25,8 @@ export default function useNavItems(): ReturnType { ...@@ -25,8 +25,8 @@ export default function useNavItems(): ReturnType {
const pathname = router.pathname; const pathname = router.pathname;
const { const {
openLoginModal: openRewardsLoginModal, openLoginModal: openRewardsLoginModal,
balance: rewardsBalance, balancesQuery: rewardsBalancesQuery,
dailyReward, dailyRewardQuery,
apiToken: rewardsApiToken, apiToken: rewardsApiToken,
} = useRewardsContext(); } = useRewardsContext();
...@@ -271,10 +271,10 @@ export default function useNavItems(): ReturnType { ...@@ -271,10 +271,10 @@ export default function useNavItems(): ReturnType {
const accountNavItems: ReturnType['accountNavItems'] = [ const accountNavItems: ReturnType['accountNavItems'] = [
config.features.rewards.isEnabled ? { config.features.rewards.isEnabled ? {
text: rewardsBalance?.total ? `${ rewardsBalance?.total } Merits` : 'Merits', text: rewardsBalancesQuery.data?.total ? `${ rewardsBalancesQuery.data?.total } Merits` : 'Merits',
nextRoute: { pathname: '/account/rewards' as const }, nextRoute: { pathname: '/account/rewards' as const },
onClick: rewardsApiToken ? undefined : openRewardsLoginModal, onClick: rewardsApiToken ? undefined : openRewardsLoginModal,
icon: dailyReward?.available ? 'merits_with_dot' : 'merits', icon: dailyRewardQuery.data?.available ? 'merits_with_dot' : 'merits',
isActive: pathname === '/account/rewards', isActive: pathname === '/account/rewards',
} : null, } : null,
{ {
...@@ -310,5 +310,5 @@ export default function useNavItems(): ReturnType { ...@@ -310,5 +310,5 @@ export default function useNavItems(): ReturnType {
].filter(Boolean); ].filter(Boolean);
return { mainNavItems, accountNavItems }; return { mainNavItems, accountNavItems };
}, [ pathname, openRewardsLoginModal, rewardsBalance, dailyReward, rewardsApiToken ]); }, [ pathname, openRewardsLoginModal, rewardsBalancesQuery, dailyRewardQuery, rewardsApiToken ]);
} }
...@@ -12,7 +12,7 @@ import PageTitle from 'ui/shared/Page/PageTitle'; ...@@ -12,7 +12,7 @@ import PageTitle from 'ui/shared/Page/PageTitle';
const RewardsDashboard = () => { const RewardsDashboard = () => {
const router = useRouter(); const router = useRouter();
const { balance, refetchBalance, dailyReward, refetchDailyReward, apiToken, claim, referralsQuery, rewardsConfigQuery } = useRewardsContext(); const { balancesQuery, dailyRewardQuery, apiToken, claim, referralsQuery, rewardsConfigQuery } = useRewardsContext();
const [ isClaiming, setIsClaiming ] = useBoolean(false); const [ isClaiming, setIsClaiming ] = useBoolean(false);
const [ timeLeft, setTimeLeft ] = React.useState<string>(''); const [ timeLeft, setTimeLeft ] = React.useState<string>('');
...@@ -20,25 +20,25 @@ const RewardsDashboard = () => { ...@@ -20,25 +20,25 @@ const RewardsDashboard = () => {
router.replace({ pathname: '/' }, undefined, { shallow: true }); router.replace({ pathname: '/' }, undefined, { shallow: true });
} }
const dailyRewardValue = Number(dailyReward?.daily_reward || 0) + Number(dailyReward?.pending_referral_rewards || 0); const dailyRewardValue = Number(dailyRewardQuery.data?.daily_reward || 0) + Number(dailyRewardQuery.data?.pending_referral_rewards || 0);
const handleClaim = useCallback(async() => { const handleClaim = useCallback(async() => {
setIsClaiming.on(); setIsClaiming.on();
try { try {
await claim(); await claim();
refetchBalance(); balancesQuery.refetch();
refetchDailyReward(); dailyRewardQuery.refetch();
} catch (error) {} } catch (error) {}
setIsClaiming.off(); setIsClaiming.off();
}, [ claim, setIsClaiming, refetchBalance, refetchDailyReward ]); }, [ claim, setIsClaiming, balancesQuery, dailyRewardQuery ]);
useEffect(() => { useEffect(() => {
if (!dailyReward?.reset_at) { if (!dailyRewardQuery.data?.reset_at) {
return; return;
} }
const interval = setInterval(() => { const interval = setInterval(() => {
const now = new Date().getTime(); const now = new Date().getTime();
const target = new Date(dailyReward.reset_at).getTime(); const target = new Date(dailyRewardQuery.data.reset_at).getTime();
const difference = target - now; const difference = target - now;
if (difference > 0) { if (difference > 0) {
...@@ -46,13 +46,13 @@ const RewardsDashboard = () => { ...@@ -46,13 +46,13 @@ const RewardsDashboard = () => {
setTimeLeft(`${ hours }:${ minutes }:${ seconds }`); setTimeLeft(`${ hours }:${ minutes }:${ seconds }`);
} else { } else {
setTimeLeft('00:00:00'); setTimeLeft('00:00:00');
refetchDailyReward(); dailyRewardQuery.refetch();
clearInterval(interval); clearInterval(interval);
} }
}, 1000); }, 1000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [ dailyReward?.reset_at, refetchDailyReward ]); }, [ dailyRewardQuery ]);
return ( return (
<> <>
...@@ -75,7 +75,7 @@ const RewardsDashboard = () => { ...@@ -75,7 +75,7 @@ const RewardsDashboard = () => {
values={ [ values={ [
{ {
label: 'Total balance', label: 'Total balance',
value: balance?.total, value: balancesQuery.data?.total,
hint: ( hint: (
<> <>
Total number of merits earned from all activities.{ ' ' } Total number of merits earned from all activities.{ ' ' }
...@@ -87,8 +87,8 @@ const RewardsDashboard = () => { ...@@ -87,8 +87,8 @@ const RewardsDashboard = () => {
}, },
] } ] }
contentAfter={ ( contentAfter={ (
<Button isDisabled={ !dailyReward?.available } onClick={ handleClaim } isLoading={ isClaiming }> <Button isDisabled={ !dailyRewardQuery.data?.available } onClick={ handleClaim } isLoading={ isClaiming }>
{ dailyReward?.available ? { dailyRewardQuery.data?.available ?
`Claim ${ dailyRewardValue } Merits` : `Claim ${ dailyRewardValue } Merits` :
`Next claim in ${ timeLeft }` `Next claim in ${ timeLeft }`
} }
......
...@@ -15,7 +15,7 @@ type Props = { ...@@ -15,7 +15,7 @@ type Props = {
}; };
const RewardsButton = ({ variant = 'header', size }: Props) => { const RewardsButton = ({ variant = 'header', size }: Props) => {
const { apiToken, openLoginModal, dailyReward, balance, isDailyRewardLoading, isBalanceLoading } = useRewardsContext(); const { apiToken, openLoginModal, dailyRewardQuery, balancesQuery } = useRewardsContext();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return ( return (
<Tooltip <Tooltip
...@@ -36,18 +36,18 @@ const RewardsButton = ({ variant = 'header', size }: Props) => { ...@@ -36,18 +36,18 @@ const RewardsButton = ({ variant = 'header', size }: Props) => {
fontSize="sm" fontSize="sm"
size={ size } size={ size }
px={ 2.5 } px={ 2.5 }
isLoading={ isDailyRewardLoading || isBalanceLoading } isLoading={ dailyRewardQuery.isLoading || balancesQuery.isLoading }
loadingText={ isMobile ? undefined : 'Merits' } loadingText={ isMobile ? undefined : 'Merits' }
textDecoration="none !important" textDecoration="none !important"
> >
<IconSvg <IconSvg
name={ dailyReward?.available ? 'merits_with_dot' : 'merits' } name={ dailyRewardQuery.data?.available ? 'merits_with_dot' : 'merits' }
boxSize={ size === 'sm' ? '26px' : '28px' } boxSize={ size === 'sm' ? '26px' : '28px' }
flexShrink={ 0 } flexShrink={ 0 }
mx={ -1 } mx={ -1 }
/> />
<chakra.span display={{ base: 'none', md: 'inline' }} ml={ 2 }> <chakra.span display={{ base: 'none', md: 'inline' }} ml={ 2 }>
{ apiToken ? balance?.total : 'Merits' } { apiToken ? balancesQuery.data?.total : 'Merits' }
</chakra.span> </chakra.span>
</Button> </Button>
</Tooltip> </Tooltip>
......
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