Commit aebc6296 authored by isstuev's avatar isstuev

qr code modal

parent a4dfabcf
...@@ -72,6 +72,14 @@ const baseStyle = definePartsStyle((props) => ({ ...@@ -72,6 +72,14 @@ const baseStyle = definePartsStyle((props) => ({
})); }));
const sizes = { const sizes = {
sm: definePartsStyle({
dialogContainer: {
height: '100%',
},
dialog: {
maxW: '536px',
},
}),
md: definePartsStyle({ md: definePartsStyle({
dialogContainer: { dialogContainer: {
height: '100%', height: '100%',
......
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as addressMock from 'mocks/address/address';
import TestApp from 'playwright/TestApp'; import TestApp from 'playwright/TestApp';
import AddressQrCode from './AddressQrCode'; import AddressQrCode from './AddressQrCode';
...@@ -8,7 +9,7 @@ import AddressQrCode from './AddressQrCode'; ...@@ -8,7 +9,7 @@ import AddressQrCode from './AddressQrCode';
test('default view +@mobile +@dark-mode', async({ mount, page }) => { test('default view +@mobile +@dark-mode', async({ mount, page }) => {
await mount( await mount(
<TestApp> <TestApp>
<AddressQrCode hash="0x363574E6C5C71c343d7348093D84320c76d5Dd29"/> <AddressQrCode address={ addressMock.withoutName }/>
</TestApp>, </TestApp>,
); );
await page.getByRole('button', { name: /qr code/i }).click(); await page.getByRole('button', { name: /qr code/i }).click();
......
...@@ -6,7 +6,9 @@ import { ...@@ -6,7 +6,9 @@ import {
ModalBody, ModalBody,
ModalContent, ModalContent,
ModalCloseButton, ModalCloseButton,
ModalHeader,
ModalOverlay, ModalOverlay,
LightMode,
Box, Box,
useDisclosure, useDisclosure,
Tooltip, Tooltip,
...@@ -18,8 +20,9 @@ import { useRouter } from 'next/router'; ...@@ -18,8 +20,9 @@ import { useRouter } from 'next/router';
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import React from 'react'; import React from 'react';
import type { Address as AddressType } from 'types/api/address';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import qrCodeIcon from 'icons/qr_code.svg'; import qrCodeIcon from 'icons/qr_code.svg';
import useIsMobile from 'lib/hooks/useIsMobile';
import getPageType from 'lib/mixpanel/getPageType'; import getPageType from 'lib/mixpanel/getPageType';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
...@@ -29,13 +32,13 @@ const SVG_OPTIONS = { ...@@ -29,13 +32,13 @@ const SVG_OPTIONS = {
interface Props { interface Props {
className?: string; className?: string;
hash: string; address: AddressType;
isLoading?: boolean; isLoading?: boolean;
} }
const AddressQrCode = ({ hash, className, isLoading }: Props) => { const AddressQrCode = ({ address, className, isLoading }: Props) => {
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const isMobile = useIsMobile();
const router = useRouter(); const router = useRouter();
const [ qr, setQr ] = React.useState(''); const [ qr, setQr ] = React.useState('');
...@@ -45,7 +48,7 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => { ...@@ -45,7 +48,7 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => {
React.useEffect(() => { React.useEffect(() => {
if (isOpen) { if (isOpen) {
QRCode.toString(hash, SVG_OPTIONS, (error: Error | null | undefined, svg: string) => { QRCode.toString(address.hash, SVG_OPTIONS, (error: Error | null | undefined, svg: string) => {
if (error) { if (error) {
setError('We were unable to generate QR code.'); setError('We were unable to generate QR code.');
Sentry.captureException(error, { tags: { source: 'qr_code' } }); Sentry.captureException(error, { tags: { source: 'qr_code' } });
...@@ -57,7 +60,7 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => { ...@@ -57,7 +60,7 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => {
mixpanel.logEvent(mixpanel.EventTypes.QR_CODE, { 'Page type': pageType }); mixpanel.logEvent(mixpanel.EventTypes.QR_CODE, { 'Page type': pageType });
}); });
} }
}, [ hash, isOpen, onClose, pageType ]); }, [ address.hash, isOpen, onClose, pageType ]);
if (isLoading) { if (isLoading) {
return <Skeleton className={ className } w="36px" h="32px" borderRadius="base"/>; return <Skeleton className={ className } w="36px" h="32px" borderRadius="base"/>;
...@@ -77,15 +80,39 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => { ...@@ -77,15 +80,39 @@ const AddressQrCode = ({ hash, className, isLoading }: Props) => {
icon={ <Icon as={ qrCodeIcon } boxSize={ 5 }/> } icon={ <Icon as={ qrCodeIcon } boxSize={ 5 }/> }
/> />
</Tooltip> </Tooltip>
<Modal isOpen={ isOpen } onClose={ onClose } size={{ base: 'full', lg: 'sm' }}>
<ModalOverlay/> { error && (
<ModalContent bgColor={ error ? undefined : 'white' }> <Modal isOpen={ isOpen } onClose={ onClose } size={{ base: 'full', lg: 'sm' }}>
{ isMobile && <ModalCloseButton/> } <ModalOverlay/>
<ModalBody mb={ 0 }> <ModalContent>
{ error ? <Alert status="warning">{ error }</Alert> : <Box dangerouslySetInnerHTML={{ __html: qr }}/> } <ModalBody mb={ 0 }>
</ModalBody> <Alert status="warning">{ error }</Alert>
</ModalContent> </ModalBody>
</Modal> </ModalContent>
</Modal>
) }
{ !error && (
<LightMode>
<Modal isOpen={ isOpen } onClose={ onClose } size={{ base: 'full', lg: 'sm' }}>
<ModalOverlay/>
<ModalContent>
<ModalHeader fontWeight="500" textStyle="h3" mb={ 4 }>Address QR code</ModalHeader>
<ModalCloseButton/>
<ModalBody mb={ 0 }>
<AddressEntity
mb={ 3 }
fontSize="md"
fontWeight={ 500 }
color="text"
address={ address }
noLink
/>
<Box p={ 4 } dangerouslySetInnerHTML={{ __html: qr }}/>
</ModalBody>
</ModalContent>
</Modal>
</LightMode>
) }
</> </>
); );
}; };
......
...@@ -37,7 +37,7 @@ const AddressHeadingInfo = ({ address, token, isLinkDisabled, isLoading }: Props ...@@ -37,7 +37,7 @@ const AddressHeadingInfo = ({ address, token, isLinkDisabled, isLoading }: Props
{ !isLoading && !address.is_contract && config.features.account.isEnabled && ( { !isLoading && !address.is_contract && config.features.account.isEnabled && (
<AddressFavoriteButton hash={ address.hash } watchListId={ address.watchlist_address_id } ml={ 3 }/> <AddressFavoriteButton hash={ address.hash } watchListId={ address.watchlist_address_id } ml={ 3 }/>
) } ) }
<AddressQrCode hash={ address.hash } ml={ 2 } isLoading={ isLoading } flexShrink={ 0 }/> <AddressQrCode address={ address } ml={ 2 } isLoading={ isLoading } flexShrink={ 0 }/>
{ config.features.account.isEnabled && <AddressActionsMenu isLoading={ isLoading }/> } { config.features.account.isEnabled && <AddressActionsMenu isLoading={ isLoading }/> }
</Flex> </Flex>
); );
......
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