Commit 33f0cab3 authored by Max Alekseenko's avatar Max Alekseenko

improve api token logic

parent 4ff3e40e
import { useBoolean } from '@chakra-ui/react'; import { useBoolean } from '@chakra-ui/react';
import React, { createContext, useContext, useEffect, useMemo } from 'react'; import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react';
import type { RewardsUserBalancesResponse, RewardsUserDailyCheckResponse } from 'types/api/rewards'; import type { RewardsUserBalancesResponse, RewardsUserDailyCheckResponse } from 'types/api/rewards';
...@@ -19,7 +19,8 @@ type TRewardsContext = { ...@@ -19,7 +19,8 @@ type TRewardsContext = {
refetchBalance: () => void; refetchBalance: () => void;
dailyReward: RewardsUserDailyCheckResponse | undefined; dailyReward: RewardsUserDailyCheckResponse | undefined;
refetchDailyReward: () => void; refetchDailyReward: () => void;
isLogedIn: boolean; apiToken: string | undefined;
saveApiToken: (token: string) => void;
} }
const RewardsContext = createContext<TRewardsContext>({ const RewardsContext = createContext<TRewardsContext>({
...@@ -30,11 +31,14 @@ const RewardsContext = createContext<TRewardsContext>({ ...@@ -30,11 +31,14 @@ const RewardsContext = createContext<TRewardsContext>({
refetchBalance: () => {}, refetchBalance: () => {},
dailyReward: undefined, dailyReward: undefined,
refetchDailyReward: () => {}, refetchDailyReward: () => {},
isLogedIn: false, apiToken: undefined,
saveApiToken: () => {},
}); });
export function RewardsContextProvider({ children }: Props) { export function RewardsContextProvider({ children }: Props) {
const apiToken = cookies.get(cookies.NAMES.REWARDS_API_TOKEN); const [ isLoginModalOpen, setIsLoginModalOpen ] = useBoolean(false);
const [ apiToken, setApiToken ] = React.useState<string | undefined>(cookies.get(cookies.NAMES.REWARDS_API_TOKEN));
const apiQueryOptions = { const apiQueryOptions = {
queryOptions: { queryOptions: {
enabled: Boolean(apiToken) && config.features.rewards.isEnabled, enabled: Boolean(apiToken) && config.features.rewards.isEnabled,
...@@ -45,17 +49,19 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -45,17 +49,19 @@ export function RewardsContextProvider({ children }: Props) {
}, },
}, },
}; };
const [ isLoginModalOpen, setIsLoginModalOpen ] = useBoolean(false);
const balancesQuery = useApiQuery('rewards_user_balances', apiQueryOptions); const balancesQuery = useApiQuery('rewards_user_balances', apiQueryOptions);
const dailyRewardQuery = useApiQuery('rewards_user_daily_check', apiQueryOptions); const dailyRewardQuery = useApiQuery('rewards_user_daily_check', apiQueryOptions);
const saveApiToken = useCallback((token: string) => {
cookies.set(cookies.NAMES.REWARDS_API_TOKEN, token);
setApiToken(token);
}, []);
useEffect(() => { useEffect(() => {
if (apiToken && balancesQuery.error?.status === 401) { if (apiToken && balancesQuery.error?.status === 401) {
cookies.set(cookies.NAMES.REWARDS_API_TOKEN, ''); saveApiToken('');
} }
}, [ balancesQuery.error, apiToken ]); }, [ balancesQuery.error, apiToken, saveApiToken ]);
const value = useMemo(() => ({ const value = useMemo(() => ({
isLoginModalOpen, isLoginModalOpen,
...@@ -65,8 +71,9 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -65,8 +71,9 @@ export function RewardsContextProvider({ children }: Props) {
refetchBalance: balancesQuery.refetch, refetchBalance: balancesQuery.refetch,
dailyReward: dailyRewardQuery.data, dailyReward: dailyRewardQuery.data,
refetchDailyReward: dailyRewardQuery.refetch, refetchDailyReward: dailyRewardQuery.refetch,
isLogedIn: Boolean(apiToken), apiToken,
}), [ isLoginModalOpen, setIsLoginModalOpen, balancesQuery, dailyRewardQuery, apiToken ]); saveApiToken,
}), [ isLoginModalOpen, setIsLoginModalOpen, balancesQuery, dailyRewardQuery, apiToken, saveApiToken ]);
return ( return (
<RewardsContext.Provider value={ value }> <RewardsContext.Provider value={ value }>
......
...@@ -28,7 +28,7 @@ export default function useNavItems(): ReturnType { ...@@ -28,7 +28,7 @@ export default function useNavItems(): ReturnType {
const { const {
openLoginModal: openRewardsLoginModal, openLoginModal: openRewardsLoginModal,
balance: rewardsBalance, balance: rewardsBalance,
isLogedIn: isLoggedInToRewards, apiToken: rewardsApiToken,
} = useRewardsContext(); } = useRewardsContext();
return React.useMemo(() => { return React.useMemo(() => {
...@@ -273,10 +273,10 @@ export default function useNavItems(): ReturnType { ...@@ -273,10 +273,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: rewardsBalance?.total ? `${ rewardsBalance?.total } Merits` : 'Merits',
nextRoute: isLoggedInToRewards ? { pathname: '/account/rewards' as const } : undefined, nextRoute: rewardsApiToken ? { pathname: '/account/rewards' as const } : undefined,
onClick: isLoggedInToRewards ? undefined : openRewardsLoginModal, onClick: rewardsApiToken ? undefined : openRewardsLoginModal,
icon: 'merits', icon: 'merits',
isActive: isLoggedInToRewards && pathname === '/account/rewards', isActive: Boolean(rewardsApiToken) && pathname === '/account/rewards',
} : null, } : null,
{ {
text: 'Watch list', text: 'Watch list',
...@@ -318,5 +318,5 @@ export default function useNavItems(): ReturnType { ...@@ -318,5 +318,5 @@ export default function useNavItems(): ReturnType {
}; };
return { mainNavItems, accountNavItems, profileItem }; return { mainNavItems, accountNavItems, profileItem };
}, [ pathname, openRewardsLoginModal, rewardsBalance, isLoggedInToRewards ]); }, [ pathname, openRewardsLoginModal, rewardsBalance, rewardsApiToken ]);
} }
...@@ -15,14 +15,14 @@ import PageTitle from 'ui/shared/Page/PageTitle'; ...@@ -15,14 +15,14 @@ import PageTitle from 'ui/shared/Page/PageTitle';
const RewardsDashboard = () => { const RewardsDashboard = () => {
const router = useRouter(); const router = useRouter();
const { balance, refetchBalance, dailyReward, refetchDailyReward, isLogedIn } = useRewardsContext(); const { balance, refetchBalance, dailyReward, refetchDailyReward, apiToken } = useRewardsContext();
const referralsQuery = useReferrals(); const referralsQuery = useReferrals();
const rewardsConfigQuery = useRewardsConfig(); const rewardsConfigQuery = useRewardsConfig();
const claim = useClaim(); const claim = useClaim();
const [ isClaiming, setIsClaiming ] = useBoolean(false); const [ isClaiming, setIsClaiming ] = useBoolean(false);
const [ timeLeft, setTimeLeft ] = React.useState<string>(''); const [ timeLeft, setTimeLeft ] = React.useState<string>('');
if (!isLogedIn) { if (!apiToken) {
router.replace({ pathname: '/' }, undefined, { shallow: true }); router.replace({ pathname: '/' }, undefined, { shallow: true });
} }
......
...@@ -4,12 +4,13 @@ import type { RewardsUserDailyClaimResponse } from 'types/api/rewards'; ...@@ -4,12 +4,13 @@ import type { RewardsUserDailyClaimResponse } from 'types/api/rewards';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import * as cookies from 'lib/cookies'; import { useRewardsContext } from 'lib/contexts/rewards';
import useToast from 'lib/hooks/useToast'; import useToast from 'lib/hooks/useToast';
export default function useClaim() { export default function useClaim() {
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const toast = useToast(); const toast = useToast();
const { apiToken } = useRewardsContext();
return useCallback(async() => { return useCallback(async() => {
try { try {
...@@ -17,7 +18,7 @@ export default function useClaim() { ...@@ -17,7 +18,7 @@ export default function useClaim() {
fetchParams: { fetchParams: {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: `Bearer ${ cookies.get(cookies.NAMES.REWARDS_API_TOKEN) }`, Authorization: `Bearer ${ apiToken }`,
}, },
}, },
}); });
...@@ -35,5 +36,5 @@ export default function useClaim() { ...@@ -35,5 +36,5 @@ export default function useClaim() {
}); });
throw _error; throw _error;
} }
}, [ apiFetch, toast ]); }, [ apiFetch, toast, apiToken ]);
} }
...@@ -9,7 +9,7 @@ import type { ...@@ -9,7 +9,7 @@ import type {
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import * as cookies from 'lib/cookies'; import { useRewardsContext } from 'lib/contexts/rewards';
import useToast from 'lib/hooks/useToast'; import useToast from 'lib/hooks/useToast';
function getMessageToSign(address: string, nonce: string, isLogin?: boolean, refCode?: string) { function getMessageToSign(address: string, nonce: string, isLogin?: boolean, refCode?: string) {
...@@ -36,6 +36,7 @@ export default function useLogin() { ...@@ -36,6 +36,7 @@ export default function useLogin() {
const toast = useToast(); const toast = useToast();
const { address } = useAccount(); const { address } = useAccount();
const { signMessageAsync } = useSignMessage(); const { signMessageAsync } = useSignMessage();
const { saveApiToken } = useRewardsContext();
return useCallback(async(refCode: string) => { return useCallback(async(refCode: string) => {
try { try {
...@@ -67,7 +68,7 @@ export default function useLogin() { ...@@ -67,7 +68,7 @@ export default function useLogin() {
if (!('created' in loginResponse)) { if (!('created' in loginResponse)) {
throw loginResponse; throw loginResponse;
} }
cookies.set(cookies.NAMES.REWARDS_API_TOKEN, loginResponse.token); saveApiToken(loginResponse.token);
return { isNewUser: loginResponse.created }; return { isNewUser: loginResponse.created };
} catch (_error) { } catch (_error) {
toast({ toast({
...@@ -80,5 +81,5 @@ export default function useLogin() { ...@@ -80,5 +81,5 @@ export default function useLogin() {
}); });
throw _error; throw _error;
} }
}, [ apiFetch, address, signMessageAsync, toast ]); }, [ apiFetch, address, signMessageAsync, toast, saveApiToken ]);
} }
import config from 'configs/app'; import config from 'configs/app';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import * as cookies from 'lib/cookies'; import { useRewardsContext } from 'lib/contexts/rewards';
export default function useReferrals() { export default function useReferrals() {
const apiToken = cookies.get(cookies.NAMES.REWARDS_API_TOKEN); const { apiToken } = useRewardsContext();
return useApiQuery('rewards_user_referrals', { return useApiQuery('rewards_user_referrals', {
queryOptions: { queryOptions: {
enabled: Boolean(apiToken) && config.features.rewards.isEnabled, enabled: Boolean(apiToken) && config.features.rewards.isEnabled,
......
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