Commit 03b64ae5 authored by tom's avatar tom

fix address action behaviour

parent 3521bf77
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import type { Route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { UserInfo } from 'types/api/account'; import type { UserInfo } from 'types/api/account';
import type { ResourceError } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources'; import { resourceKey } from 'lib/api/resources';
import useLoginUrl from 'lib/hooks/useLoginUrl'; import useLoginUrl from 'lib/hooks/useLoginUrl';
export default function useRedirectIfNotAuth() { export default function useIsAccountActionAllowed() {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const profileData = queryClient.getQueryData<UserInfo>([ resourceKey('user_info') ]); const profileData = queryClient.getQueryData<UserInfo>([ resourceKey('user_info') ]);
const profileState = queryClient.getQueryState<unknown, ResourceError<{ message: string }>>([ resourceKey('user_info') ]);
const isAuth = Boolean(profileData); const isAuth = Boolean(profileData);
const loginUrl = useLoginUrl(); const loginUrl = useLoginUrl();
const router = useRouter();
return React.useCallback((accountRoute: Route) => {
if (profileState?.error?.status === 403) {
router.push(accountRoute);
return false;
}
return React.useCallback(() => {
if (!isAuth) { if (!isAuth) {
window.location.assign(loginUrl); window.location.assign(loginUrl);
return true; return false;
} }
return false; return true;
}, [ isAuth, loginUrl ]); }, [ isAuth, loginUrl, profileState?.error?.status, router ]);
} }
...@@ -5,12 +5,9 @@ import React from 'react'; ...@@ -5,12 +5,9 @@ import React from 'react';
import starFilledIcon from 'icons/star_filled.svg'; import starFilledIcon from 'icons/star_filled.svg';
import starOutlineIcon from 'icons/star_outline.svg'; import starOutlineIcon from 'icons/star_outline.svg';
import type { ResourceError } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import useIsAccountActionAllowed from 'lib/hooks/useIsAccountActionAllowed';
import usePreventFocusAfterModalClosing from 'lib/hooks/usePreventFocusAfterModalClosing'; import usePreventFocusAfterModalClosing from 'lib/hooks/usePreventFocusAfterModalClosing';
import useRedirectIfNotAuth from 'lib/hooks/useRedirectIfNotAuth';
import useToast from 'lib/hooks/useToast';
import WatchlistAddModal from 'ui/watchlist/AddressModal/AddressModal'; import WatchlistAddModal from 'ui/watchlist/AddressModal/AddressModal';
import DeleteAddressModal from 'ui/watchlist/DeleteAddressModal'; import DeleteAddressModal from 'ui/watchlist/DeleteAddressModal';
...@@ -25,33 +22,14 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => { ...@@ -25,33 +22,14 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
const deleteModalProps = useDisclosure(); const deleteModalProps = useDisclosure();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const router = useRouter(); const router = useRouter();
const toast = useToast(); const isAccountActionAllowed = useIsAccountActionAllowed();
const redirectIfNotAuth = useRedirectIfNotAuth();
const profileState = queryClient.getQueryState<unknown, ResourceError<{ message: string }>>([ resourceKey('user_info') ]);
const handleClick = React.useCallback(() => { const handleClick = React.useCallback(() => {
if (profileState?.error?.status === 403) { if (!isAccountActionAllowed({ pathname: '/account/watchlist' })) {
const isUnverifiedEmail = profileState.error.payload?.message.includes('Unverified email');
if (isUnverifiedEmail) {
toast({
position: 'top-right',
title: 'Error',
description: 'Unable to add address to watch list. Please go to the watch list page instead.',
status: 'error',
variant: 'subtle',
isClosable: true,
});
return;
}
}
if (redirectIfNotAuth()) {
return; return;
} }
watchListId ? deleteModalProps.onOpen() : addModalProps.onOpen(); watchListId ? deleteModalProps.onOpen() : addModalProps.onOpen();
}, [ profileState, redirectIfNotAuth, watchListId, deleteModalProps, addModalProps, toast ]); }, [ isAccountActionAllowed, watchListId, deleteModalProps, addModalProps ]);
const handleAddOrDeleteSuccess = React.useCallback(async() => { const handleAddOrDeleteSuccess = React.useCallback(async() => {
const queryKey = getResourceKey('address', { pathParams: { hash: router.query.hash?.toString() } }); const queryKey = getResourceKey('address', { pathParams: { hash: router.query.hash?.toString() } });
......
...@@ -4,6 +4,7 @@ import React from 'react'; ...@@ -4,6 +4,7 @@ import React from 'react';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import iconArrow from 'icons/arrows/east-mini.svg'; import iconArrow from 'icons/arrows/east-mini.svg';
import useIsAccountActionAllowed from 'lib/hooks/useIsAccountActionAllowed';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import PrivateTagMenuItem from './PrivateTagMenuItem'; import PrivateTagMenuItem from './PrivateTagMenuItem';
...@@ -19,6 +20,7 @@ const AddressActions = ({ isLoading }: Props) => { ...@@ -19,6 +20,7 @@ const AddressActions = ({ isLoading }: Props) => {
const hash = getQueryParamString(router.query.hash); const hash = getQueryParamString(router.query.hash);
const isTokenPage = router.pathname === '/token/[hash]'; const isTokenPage = router.pathname === '/token/[hash]';
const isAccountActionAllowed = useIsAccountActionAllowed();
return ( return (
<Menu> <Menu>
...@@ -36,9 +38,9 @@ const AddressActions = ({ isLoading }: Props) => { ...@@ -36,9 +38,9 @@ const AddressActions = ({ isLoading }: Props) => {
</Skeleton> </Skeleton>
<MenuList minWidth="180px" zIndex="popover"> <MenuList minWidth="180px" zIndex="popover">
{ isTokenPage && appConfig.contractInfoApi.endpoint && appConfig.adminServiceApi.endpoint && appConfig.isAccountSupported && { isTokenPage && appConfig.contractInfoApi.endpoint && appConfig.adminServiceApi.endpoint && appConfig.isAccountSupported &&
<TokenInfoMenuItem py={ 2 } px={ 4 } hash={ hash }/> } <TokenInfoMenuItem py={ 2 } px={ 4 } hash={ hash } onBeforeClick={ isAccountActionAllowed }/> }
<PrivateTagMenuItem py={ 2 } px={ 4 } hash={ hash }/> <PrivateTagMenuItem py={ 2 } px={ 4 } hash={ hash } onBeforeClick={ isAccountActionAllowed }/>
<PublicTagMenuItem py={ 2 } px={ 4 } hash={ hash }/> <PublicTagMenuItem py={ 2 } px={ 4 } hash={ hash } onBeforeClick={ isAccountActionAllowed }/>
</MenuList> </MenuList>
</Menu> </Menu>
); );
......
import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react'; import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import type { Route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { Address } from 'types/api/address'; import type { Address } from 'types/api/address';
import iconPrivateTags from 'icons/privattags.svg'; import iconPrivateTags from 'icons/privattags.svg';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import useRedirectIfNotAuth from 'lib/hooks/useRedirectIfNotAuth';
import PrivateTagModal from 'ui/privateTags/AddressModal/AddressModal'; import PrivateTagModal from 'ui/privateTags/AddressModal/AddressModal';
interface Props { interface Props {
className?: string; className?: string;
hash: string; hash: string;
onBeforeClick: (route: Route) => boolean;
} }
const PrivateTagMenuItem = ({ className, hash }: Props) => { const PrivateTagMenuItem = ({ className, hash, onBeforeClick }: Props) => {
const modal = useDisclosure(); const modal = useDisclosure();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const redirectIfNotAuth = useRedirectIfNotAuth();
const queryKey = getResourceKey('address', { pathParams: { hash } }); const queryKey = getResourceKey('address', { pathParams: { hash } });
const addressData = queryClient.getQueryData<Address>(queryKey); const addressData = queryClient.getQueryData<Address>(queryKey);
const handleClick = React.useCallback(() => { const handleClick = React.useCallback(() => {
if (redirectIfNotAuth()) { if (!onBeforeClick({ pathname: '/account/tag_address' })) {
return; return;
} }
modal.onOpen(); modal.onOpen();
}, [ modal, redirectIfNotAuth ]); }, [ modal, onBeforeClick ]);
const handleAddPrivateTag = React.useCallback(async() => { const handleAddPrivateTag = React.useCallback(async() => {
await queryClient.refetchQueries({ queryKey }); await queryClient.refetchQueries({ queryKey });
......
import { MenuItem, Icon, chakra } from '@chakra-ui/react'; import { MenuItem, Icon, chakra } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type { Route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import iconPublicTags from 'icons/publictags.svg'; import iconPublicTags from 'icons/publictags.svg';
import useRedirectIfNotAuth from 'lib/hooks/useRedirectIfNotAuth';
interface Props { interface Props {
className?: string; className?: string;
hash: string; hash: string;
onBeforeClick: (route: Route) => boolean;
} }
const PublicTagMenuItem = ({ className, hash }: Props) => { const PublicTagMenuItem = ({ className, hash, onBeforeClick }: Props) => {
const router = useRouter(); const router = useRouter();
const redirectIfNotAuth = useRedirectIfNotAuth();
const handleClick = React.useCallback(() => { const handleClick = React.useCallback(() => {
if (redirectIfNotAuth()) { if (!onBeforeClick({ pathname: '/account/public_tags_request' })) {
return; return;
} }
router.push({ pathname: '/account/public_tags_request', query: { address: hash } }); router.push({ pathname: '/account/public_tags_request', query: { address: hash } });
}, [ hash, redirectIfNotAuth, router ]); }, [ hash, onBeforeClick, router ]);
return ( return (
<MenuItem className={ className }onClick={ handleClick }> <MenuItem className={ className }onClick={ handleClick }>
......
import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react'; import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type { Route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import iconEdit from 'icons/edit.svg'; import iconEdit from 'icons/edit.svg';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import useHasAccount from 'lib/hooks/useHasAccount'; import useHasAccount from 'lib/hooks/useHasAccount';
import useRedirectIfNotAuth from 'lib/hooks/useRedirectIfNotAuth';
import AddressVerificationModal from 'ui/addressVerification/AddressVerificationModal'; import AddressVerificationModal from 'ui/addressVerification/AddressVerificationModal';
interface Props { interface Props {
className?: string; className?: string;
hash: string; hash: string;
onBeforeClick: (route: Route) => boolean;
} }
const TokenInfoMenuItem = ({ className, hash }: Props) => { const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => {
const router = useRouter(); const router = useRouter();
const modal = useDisclosure(); const modal = useDisclosure();
const redirectIfNotAuth = useRedirectIfNotAuth();
const isAuth = useHasAccount(); const isAuth = useHasAccount();
const verifiedAddressesQuery = useApiQuery('verified_addresses', { const verifiedAddressesQuery = useApiQuery('verified_addresses', {
...@@ -40,12 +40,12 @@ const TokenInfoMenuItem = ({ className, hash }: Props) => { ...@@ -40,12 +40,12 @@ const TokenInfoMenuItem = ({ className, hash }: Props) => {
}); });
const handleAddAddressClick = React.useCallback(() => { const handleAddAddressClick = React.useCallback(() => {
if (redirectIfNotAuth()) { if (!onBeforeClick({ pathname: '/account/verified_addresses' })) {
return; return;
} }
modal.onOpen(); modal.onOpen();
}, [ modal, redirectIfNotAuth ]); }, [ modal, onBeforeClick ]);
const handleAddApplicationClick = React.useCallback(async() => { const handleAddApplicationClick = React.useCallback(async() => {
router.push({ pathname: '/account/verified_addresses', query: { address: hash } }); router.push({ pathname: '/account/verified_addresses', query: { address: hash } });
......
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