Commit bb0b5f12 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Broken flow for adding an email on the `Watch list` page (#2677)

* Broken flow for adding an email on the `Watch list` page

Fixes #2605

* Token test: remove total supply update via socket as it is flaky in the CI

* show alert on watchlist page instead of modal
parent 5e808067
......@@ -12,6 +12,7 @@ import { Tooltip } from 'toolkit/chakra/tooltip';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import IconSvg from 'ui/shared/IconSvg';
import AuthGuard from 'ui/snippets/auth/AuthGuard';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import WatchlistAddModal from 'ui/watchlist/AddressModal/AddressModal';
import DeleteAddressModal from 'ui/watchlist/DeleteAddressModal';
......@@ -27,6 +28,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
const queryClient = useQueryClient();
const router = useRouter();
const onFocusCapture = usePreventFocusAfterModalClosing();
const profileQuery = useProfileQuery();
const handleAddToFavorite = React.useCallback(() => {
watchListId ? deleteModalProps.onOpen() : addModalProps.onOpen();
......@@ -78,6 +80,8 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
isAdd
onSuccess={ handleAddOrDeleteSuccess }
data={ formData }
hasEmail={ Boolean(profileQuery.data?.email) }
showEmailAlert
/>
{ formData.id && (
<DeleteAddressModal
......
......@@ -34,13 +34,10 @@ test.beforeEach(async({ mockApiResponse, mockTextAd }) => {
});
test('base view', async({ render, page, createSocket }) => {
test.slow();
const component = await render(<Token/>, { hooksConfig }, { withSocket: true });
const socket = await createSocket();
const channel = await socketServer.joinChannel(socket, `tokens:${ hash }`);
socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 });
await component.getByText('100 ARIA').waitFor({ state: 'visible', timeout: 10_000 });
await socketServer.joinChannel(socket, `tokens:${ hash }`);
await expect(component).toHaveScreenshot({
mask: [ page.locator(pwConfig.adsBannerSelector) ],
......
......@@ -20,6 +20,7 @@ import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken';
import AddressModal from 'ui/watchlist/AddressModal/AddressModal';
import DeleteAddressModal from 'ui/watchlist/DeleteAddressModal';
import WatchlistEmailAlert from 'ui/watchlist/WatchlistEmailAlert';
import WatchListItem from 'ui/watchlist/WatchlistTable/WatchListItem';
import WatchlistTable from 'ui/watchlist/WatchlistTable/WatchlistTable';
......@@ -41,6 +42,8 @@ const WatchList: React.FC = () => {
const [ addressModalData, setAddressModalData ] = useState<WatchlistAddress>();
const [ deleteModalData, setDeleteModalData ] = useState<WatchlistAddress>();
const hasEmail = Boolean(profileQuery.data?.email);
const onEditClick = useCallback((data: WatchlistAddress) => {
setAddressModalData(data);
addressModalProps.onOpen();
......@@ -75,12 +78,6 @@ const WatchList: React.FC = () => {
);
}, [ deleteModalData?.id, queryClient ]);
const description = (
<AccountPageDescription>
An email notification can be sent to you when an address on your watch list sends or receives any transactions.
</AccountPageDescription>
);
const content = (() => {
const actionBar = pagination.isVisible ? (
<ActionBar mt={ -6 }>
......@@ -90,7 +87,10 @@ const WatchList: React.FC = () => {
return (
<>
{ description }
{ !hasEmail && <WatchlistEmailAlert/> }
<AccountPageDescription>
An email notification can be sent to you when an address on your watch list sends or receives any transactions.
</AccountPageDescription>
<DataListDisplay
isError={ isError }
itemsNum={ data?.items.length }
......@@ -105,7 +105,7 @@ const WatchList: React.FC = () => {
isLoading={ isPlaceholderData }
onDeleteClick={ onDeleteClick }
onEditClick={ onEditClick }
hasEmail={ Boolean(profileQuery.data?.email) }
hasEmail={ hasEmail }
/>
)) }
</Box>
......@@ -116,7 +116,7 @@ const WatchList: React.FC = () => {
onDeleteClick={ onDeleteClick }
onEditClick={ onEditClick }
top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
hasEmail={ Boolean(profileQuery.data?.email) }
hasEmail={ hasEmail }
/>
</Box>
</DataListDisplay>
......@@ -133,6 +133,7 @@ const WatchList: React.FC = () => {
onSuccess={ onAddOrEditSuccess }
data={ addressModalData }
isAdd={ !addressModalData }
hasEmail={ hasEmail }
/>
{ deleteModalData && (
<DeleteAddressModal
......
import type { DialogRootProps } from '@chakra-ui/react';
import { Box, Text } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import { DialogBody, DialogContent, DialogHeader, DialogRoot } from 'toolkit/chakra/dialog';
import FormSubmitAlert from 'ui/shared/FormSubmitAlert';
interface Props<TData> {
open: boolean;
onOpenChange: ({ open }: { open: boolean }) => void;
interface Props<TData> extends Omit<DialogRootProps, 'children'> {
data?: TData;
title: string;
text?: string;
......@@ -23,15 +22,16 @@ export default function FormModal<TData>({
renderForm,
isAlertVisible,
setAlertVisible,
...rest
}: Props<TData>) {
const handleOpenChange = useCallback(({ open }: { open: boolean }) => {
!open && setAlertVisible?.(false);
onOpenChange({ open });
onOpenChange?.({ open });
}, [ onOpenChange, setAlertVisible ]);
return (
<DialogRoot open={ open } onOpenChange={ handleOpenChange } size={{ lgDown: 'full', lg: 'md' }}>
<DialogRoot open={ open } onOpenChange={ handleOpenChange } size={{ lgDown: 'full', lg: 'md' }} { ...rest }>
<DialogContent>
<DialogHeader>{ title }</DialogHeader>
<DialogBody>
......
......@@ -14,9 +14,6 @@ import { Button } from 'toolkit/chakra/button';
import { FormFieldAddress } from 'toolkit/components/forms/fields/FormFieldAddress';
import { FormFieldCheckbox } from 'toolkit/components/forms/fields/FormFieldCheckbox';
import { FormFieldText } from 'toolkit/components/forms/fields/FormFieldText';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import AuthModal from 'ui/snippets/auth/AuthModal';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import AddressFormNotifications from './AddressFormNotifications';
......@@ -30,6 +27,8 @@ type Props = {
onSuccess: () => Promise<void>;
setAlertVisible: (isAlertVisible: boolean) => void;
isAdd: boolean;
hasEmail: boolean;
showEmailAlert?: boolean;
};
export type Inputs = {
......@@ -56,16 +55,12 @@ export type Inputs = {
};
};
const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd }) => {
const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd, hasEmail, showEmailAlert }) => {
const [ pending, setPending ] = useState(false);
const profileQuery = useProfileQuery();
const userWithoutEmail = profileQuery.data && !profileQuery.data.email;
const authModal = useDisclosure();
let notificationsDefault = {} as Inputs['notification_settings'];
if (!data?.notification_settings) {
NOTIFICATIONS.forEach(n => notificationsDefault[n] = { incoming: !userWithoutEmail, outcoming: !userWithoutEmail });
NOTIFICATIONS.forEach(n => notificationsDefault[n] = { incoming: hasEmail, outcoming: hasEmail });
} else {
notificationsDefault = data.notification_settings;
}
......@@ -74,7 +69,7 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
defaultValues: {
address: data?.address_hash || '',
tag: data?.name || '',
notification: data?.notification_methods ? data.notification_methods.email : !userWithoutEmail,
notification: data?.notification_methods ? data.notification_methods.email : hasEmail,
notification_settings: notificationsDefault,
},
mode: 'onTouched',
......@@ -149,23 +144,7 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
bgColor="dialog.bg"
mb={ 8 }
/>
{ userWithoutEmail ? (
<>
<Alert
status="info"
display="flex"
flexDirection={{ base: 'column', md: 'row' }}
alignItems={{ base: 'flex-start', lg: 'center' }}
columnGap={ 2 }
rowGap={ 2 }
w="fit-content"
>
To receive notifications you need to add an email to your profile.
<Button variant="outline" size="sm" onClick={ authModal.onOpen }>Add email</Button>
</Alert>
{ authModal.open && <AuthModal initialScreen={{ type: 'email', isAuth: true }} onClose={ authModal.onClose }/> }
</>
) : (
{ hasEmail ? (
<>
<Text color="text.secondary" fontSize="sm" marginBottom={ 5 }>
Please select what types of notifications you will receive
......@@ -179,7 +158,17 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
label="Email notifications"
/>
</>
) }
) : null }
{ !hasEmail && showEmailAlert ? (
<Alert
status="info"
descriptionProps={{ alignItems: 'center', gap: 2 }}
w="fit-content"
mb={ 6 }
>
To receive notifications you need to add an email to your profile.
</Alert>
) : null }
<Button
type="submit"
loading={ pending }
......@@ -190,6 +179,7 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
</Button>
</form>
</FormProvider>
);
};
......
......@@ -12,17 +12,28 @@ type Props = {
onOpenChange: ({ open }: { open: boolean }) => void;
onSuccess: () => Promise<void>;
data?: Partial<WatchlistAddress>;
hasEmail: boolean;
showEmailAlert?: boolean;
};
const AddressModal: React.FC<Props> = ({ open, onOpenChange, onSuccess, data, isAdd }) => {
const AddressModal: React.FC<Props> = ({ open, onOpenChange, onSuccess, data, isAdd, hasEmail, showEmailAlert }) => {
const title = !isAdd ? 'Edit watch list address' : 'New address to watch list';
const text = isAdd ? 'An email notification can be sent to you when an address on your watch list sends or receives any transactions.' : '';
const [ isAlertVisible, setAlertVisible ] = useState(false);
const renderForm = useCallback(() => {
return <AddressForm data={ data } onSuccess={ onSuccess } setAlertVisible={ setAlertVisible } isAdd={ isAdd }/>;
}, [ data, isAdd, onSuccess ]);
return (
<AddressForm
data={ data }
onSuccess={ onSuccess }
setAlertVisible={ setAlertVisible }
isAdd={ isAdd }
hasEmail={ hasEmail }
showEmailAlert={ showEmailAlert }
/>
);
}, [ data, isAdd, onSuccess, hasEmail, showEmailAlert ]);
return (
<FormModal<WatchlistAddress>
......
import React from 'react';
import { Alert } from 'toolkit/chakra/alert';
import { Button } from 'toolkit/chakra/button';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import AuthModal from 'ui/snippets/auth/AuthModal';
const WatchlistEmailAlert = () => {
const authModal = useDisclosure();
return (
<>
<Alert
status="info"
descriptionProps={{ alignItems: 'center', gap: 2 }}
w="fit-content"
mb={ 6 }
>
To receive notifications you need to add an email to your profile.
<Button variant="outline" size="sm" onClick={ authModal.onOpen }>Add email</Button>
</Alert>
{ authModal.open && <AuthModal initialScreen={{ type: 'email', isAuth: true }} onClose={ authModal.onClose }/> }
</>
);
};
export default React.memo(WatchlistEmailAlert);
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