Skip to content

Commit

Permalink
Adding an email when logging into merits (#2369)
Browse files Browse the repository at this point in the history
* add email step

* fix preset

* update text

* fix login with wallet

* update button text and var names

* update mixpanel events
  • Loading branch information
maxaleks authored Nov 7, 2024
1 parent 151dfef commit a0deeab
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 45 deletions.
2 changes: 1 addition & 1 deletion configs/envs/.env.eth_sepolia
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=noves
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://points.k8s-dev.blockscout.com
NEXT_PUBLIC_XSTAR_SCORE_URL='https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address'
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address
2 changes: 1 addition & 1 deletion lib/mixpanel/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Type extends EventTypes.LOGIN ? (
}
) :
Type extends EventTypes.ACCOUNT_LINK_INFO ? {
'Source': 'Profile' | 'Login modal' | 'Profile dropdown';
'Source': 'Profile' | 'Login modal' | 'Profile dropdown' | 'Merits';
'Status': 'Started' | 'OTP sent' | 'Finished';
'Type': 'Email' | 'Wallet';
} :
Expand Down
74 changes: 53 additions & 21 deletions ui/rewards/login/RewardsLoginModal.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, useBoolean } from '@chakra-ui/react';
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, useBoolean, useDisclosure } from '@chakra-ui/react';
import React, { useCallback, useEffect } from 'react';

import { useRewardsContext } from 'lib/contexts/rewards';
import useIsMobile from 'lib/hooks/useIsMobile';
import useWallet from 'lib/web3/useWallet';
import AuthModal from 'ui/snippets/auth/AuthModal';

import CongratsStepContent from './steps/CongratsStepContent';
import LoginStepContent from './steps/LoginStepContent';

const MIXPANEL_CONFIG = {
account_link_info: {
source: 'Merits' as const,
},
wallet_connect: {
source: 'Merits' as const,
},
};

const RewardsLoginModal = () => {
const { isOpen: isWalletModalOpen } = useWallet({ source: 'Merits' });
const isMobile = useIsMobile();
const { isLoginModalOpen, closeLoginModal } = useRewardsContext();

const [ isLoginStep, setIsLoginStep ] = useBoolean(true);
const [ isReferral, setIsReferral ] = useBoolean(false);
const [ isAuth, setIsAuth ] = useBoolean(false);
const authModal = useDisclosure();

useEffect(() => {
if (!isLoginModalOpen) {
Expand All @@ -30,27 +42,47 @@ const RewardsLoginModal = () => {
setIsLoginStep.off();
}, [ setIsLoginStep, setIsReferral ]);

const handleAuthModalOpen = useCallback((isAuth: boolean) => {
setIsAuth[isAuth ? 'on' : 'off']();
authModal.onOpen();
}, [ authModal, setIsAuth ]);

const handleAuthModalClose = useCallback(() => {
setIsAuth.off();
authModal.onClose();
}, [ authModal, setIsAuth ]);

return (
<Modal
isOpen={ isLoginModalOpen && !isWalletModalOpen }
onClose={ closeLoginModal }
size={ isMobile ? 'full' : 'sm' }
isCentered
>
<ModalOverlay/>
<ModalContent width={ isLoginStep ? '400px' : '560px' } p={ 6 }>
<ModalHeader fontWeight="500" textStyle="h3" mb={ 3 }>
{ isLoginStep ? 'Login' : 'Congratulations' }
</ModalHeader>
<ModalCloseButton top={ 6 } right={ 6 }/>
<ModalBody mb={ 0 }>
{ isLoginStep ?
<LoginStepContent goNext={ goNext } closeModal={ closeLoginModal }/> :
<CongratsStepContent isReferral={ isReferral }/>
}
</ModalBody>
</ModalContent>
</Modal>
<>
<Modal
isOpen={ isLoginModalOpen && !isWalletModalOpen && !authModal.isOpen }
onClose={ closeLoginModal }
size={ isMobile ? 'full' : 'sm' }
isCentered
>
<ModalOverlay/>
<ModalContent width={ isLoginStep ? '400px' : '560px' } p={ 6 }>
<ModalHeader fontWeight="500" textStyle="h3" mb={ 3 }>
{ isLoginStep ? 'Login' : 'Congratulations' }
</ModalHeader>
<ModalCloseButton top={ 6 } right={ 6 }/>
<ModalBody mb={ 0 }>
{ isLoginStep ?
<LoginStepContent goNext={ goNext } openAuthModal={ handleAuthModalOpen } closeModal={ closeLoginModal }/> :
<CongratsStepContent isReferral={ isReferral }/>
}
</ModalBody>
</ModalContent>
</Modal>
{ authModal.isOpen && (
<AuthModal
onClose={ handleAuthModalClose }
initialScreen={{ type: 'connect_wallet', isAuth }}
mixpanelConfig={ MIXPANEL_CONFIG }
closeOnError
/>
) }
</>
);
};

Expand Down
39 changes: 23 additions & 16 deletions ui/rewards/login/steps/LoginStepContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import useWallet from 'lib/web3/useWallet';
import FormInputPlaceholder from 'ui/shared/forms/inputs/FormInputPlaceholder';
import LinkExternal from 'ui/shared/links/LinkExternal';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import useSignInWithWallet from 'ui/snippets/auth/useSignInWithWallet';

type Props = {
goNext: (isReferral: boolean) => void;
closeModal: () => void;
openAuthModal: (isAuth: boolean) => void;
};

const LoginStepContent = ({ goNext, closeModal }: Props) => {
const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
const router = useRouter();
const { connect, isConnected, address } = useWallet({ source: 'Merits' });
const savedRefCode = cookies.get(cookies.NAMES.REWARDS_REFERRAL_CODE);
Expand All @@ -34,6 +34,10 @@ const LoginStepContent = ({ goNext, closeModal }: Props) => {
profileQuery.data?.address_hash !== address,
[ address, profileQuery.data ]);

const isLoggedIntoAccountWithWallet = useMemo(() =>
!profileQuery.isLoading && profileQuery.data?.address_hash,
[ profileQuery ]);

const isSignUp = useMemo(() =>
isConnected && !isAddressMismatch && !checkUserQuery.isFetching && !checkUserQuery.data?.exists,
[ isConnected, isAddressMismatch, checkUserQuery ]);
Expand Down Expand Up @@ -69,20 +73,23 @@ const LoginStepContent = ({ goNext, closeModal }: Props) => {
}
}, [ refCode, isRefCodeUsed, isSignUp ]); // eslint-disable-line react-hooks/exhaustive-deps

const { start: loginToAccount } = useSignInWithWallet({
isAuth: Boolean(!profileQuery.isLoading && profileQuery.data?.email),
onSuccess: loginToRewardsProgram,
onError: setIsLoading.off,
});

const handleLogin = useCallback(async() => {
if (!profileQuery.isLoading && !profileQuery.data?.address_hash) {
setIsLoading.on();
loginToAccount();
return;
if (isLoggedIntoAccountWithWallet) {
loginToRewardsProgram();
} else {
openAuthModal(Boolean(profileQuery.data?.email));
}
}, [ loginToRewardsProgram, openAuthModal, isLoggedIntoAccountWithWallet, profileQuery ]);

const buttonText = useMemo(() => {
if (!isConnected) {
return 'Connect wallet';
}
if (isLoggedIntoAccountWithWallet) {
return 'Get started';
}
loginToRewardsProgram();
}, [ loginToAccount, loginToRewardsProgram, profileQuery, setIsLoading ]);
return profileQuery.data?.email ? 'Add wallet to account' : 'Log in to account';
}, [ isConnected, isLoggedIntoAccountWithWallet, profileQuery.data ]);

return (
<>
Expand All @@ -98,7 +105,7 @@ const LoginStepContent = ({ goNext, closeModal }: Props) => {
More about Blockscout Merits
</LinkExternal>
</Box>
{ isSignUp && (
{ isSignUp && isLoggedIntoAccountWithWallet && (
<Box mb={ 6 }>
<Divider bgColor="divider" mb={ 6 }/>
<Flex w="full" alignItems="center" justifyContent="space-between">
Expand Down Expand Up @@ -145,7 +152,7 @@ const LoginStepContent = ({ goNext, closeModal }: Props) => {
loadingText={ isLoading ? 'Sign message in your wallet' : undefined }
isDisabled={ isAddressMismatch || refCodeError }
>
{ isConnected ? 'Get started' : 'Connect wallet' }
{ buttonText }
</Button>
<Text fontSize="sm" color={ useColorModeValue('blackAlpha.500', 'whiteAlpha.500') } textAlign="center">
Already registered for Blockscout Merits on another network or chain? Connect the same wallet here.
Expand Down
7 changes: 4 additions & 3 deletions ui/snippets/auth/AuthModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ interface Props {
source: mixpanel.EventPayload<mixpanel.EventTypes.ACCOUNT_LINK_INFO>['Source'];
};
};
closeOnError?: boolean;
}

const AuthModal = ({ initialScreen, onClose, mixpanelConfig }: Props) => {
const AuthModal = ({ initialScreen, onClose, mixpanelConfig, closeOnError }: Props) => {
const [ steps, setSteps ] = React.useState<Array<Screen>>([ initialScreen ]);
const [ isSuccess, setIsSuccess ] = React.useState(false);

Expand Down Expand Up @@ -66,8 +67,8 @@ const AuthModal = ({ initialScreen, onClose, mixpanelConfig }: Props) => {
}, []);

const onReset = React.useCallback((isAuth?: boolean) => {
isAuth ? onClose() : setSteps([ initialScreen ]);
}, [ initialScreen, onClose ]);
isAuth || closeOnError ? onClose() : setSteps([ initialScreen ]);
}, [ initialScreen, onClose, closeOnError ]);

const onAuthSuccess = React.useCallback(async(screen: ScreenSuccess) => {
setIsSuccess(true);
Expand Down
14 changes: 11 additions & 3 deletions ui/snippets/auth/screens/AuthModalScreenSuccessWallet.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { chakra, Box, Text, Button } from '@chakra-ui/react';
import { chakra, Box, Text, Button, Flex } from '@chakra-ui/react';
import React from 'react';

import type { Screen } from '../types';
import type { UserInfo } from 'types/api/account';

import config from 'configs/app';
import { apos } from 'lib/html-entities';
import shortenString from 'lib/shortenString';

interface Props {
Expand Down Expand Up @@ -47,8 +49,14 @@ const AuthModalScreenSuccessWallet = ({ address, onAddEmail, onClose, isAuth, pr
</Text>
{ !profile?.email ? (
<>
<Text mt={ 6 }>Add your email to receive notifications about addresses in your watch list.</Text>
<Button mt={ 6 } onClick={ handleAddEmailClick }>Add email</Button>
<Text mt={ 6 }>
Add your email to receive exclusive updates about Blockscout { config.features.rewards.isEnabled ? 'Merits ' : ' ' }
and notifications about addresses in your watch list.
</Text>
<Flex mt={ 6 } gap={ 2 }>
<Button onClick={ handleAddEmailClick }>Add email</Button>
<Button variant="simple" onClick={ onClose }>I{ apos }ll do it later</Button>
</Flex>
</>
) : (
<Button
Expand Down

0 comments on commit a0deeab

Please sign in to comment.