Commit 4fb75da4 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #26 from blockscout/redesign-w

watchlist redesign
parents c457a938 50b93e4a
......@@ -19,7 +19,8 @@
"next": "12.1.6",
"next-react-svg": "1.1.3",
"react": "18.1.0",
"react-dom": "18.1.0"
"react-dom": "18.1.0",
"react-jazzicon": "^1.0.4"
},
"devDependencies": {
"@types/node": "17.0.36",
......
......@@ -21,7 +21,7 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
return {
field: {
border: '1px solid',
border: '2px solid',
borderColor: 'inherit',
bg: 'inherit',
_hover: {
......@@ -46,7 +46,7 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
},
},
addon: {
border: '1px solid',
border: '2px solid',
borderColor: mode('inherit', 'whiteAlpha.50')(props),
bg: mode('gray.100', 'whiteAlpha.300')(props),
},
......
......@@ -11,17 +11,17 @@ const Modal: ComponentMultiStyleConfig = {
},
baseStyle: {
dialog: {
padding: '40px',
borderRadius: '30px',
padding: 8,
borderRadius: 'lg',
},
header: {
padding: 0,
marginBottom: '20px',
marginBottom: 8,
fontSize: '2xl',
},
body: {
padding: 0,
marginBottom: '40px',
marginBottom: 8,
},
footer: {
padding: 0,
......
import type { ComponentMultiStyleConfig } from '@chakra-ui/theme';
import { cssVar } from '@chakra-ui/theme-tools';
const $width = cssVar('switch-track-width');
const $height = cssVar('switch-track-height');
const Switch: ComponentMultiStyleConfig = {
parts: [ ],
sizes: {
md: {
container: {
[$width.variable]: '38px',
[$height.variable]: '18px',
},
},
},
baseStyle: {
track: {
p: '1px',
},
},
}
export default Switch;
import type { ComponentMultiStyleConfig } from '@chakra-ui/theme';
const firstLastStyle = {
_first: { paddingLeft: 0 },
_last: { paddingRight: 0 },
}
const Table: ComponentMultiStyleConfig = {
parts: [ 'th', 'td', 'table' ],
baseStyle: {
thead: {
backgroundColor: 'gray.50',
},
th: {
...firstLastStyle,
textTransform: 'none',
fontWeight: 'normal',
overflow: 'hidden',
color: 'gray.500',
},
td: {
...firstLastStyle,
fontSize: 'md',
verticalAlign: 'top',
},
table: {
tableLayout: 'fixed',
borderTopLeftRadius: 'md',
borderTopRightRadius: 'md',
overflow: 'hidden',
},
},
sizes: {
md: {
th: {
px: 4,
fontSize: 'sm',
},
td: {
px: 4,
py: 6,
},
},
},
variants: {
simple: {
th: {
border: 0,
},
},
},
}
......
......@@ -6,6 +6,15 @@ const Tag: ComponentStyleConfig = {
display: 'inline-block',
overflow: 'hidden',
textOverflow: 'ellipsis',
borderRadius: 'md',
},
},
variants: {
gray: {
container: {
bg: 'gray.200',
color: 'gray.600',
},
},
},
}
......
import Switch from './Switch';
import Button from './Button';
import Modal from './Modal';
import Table from './Table';
......@@ -7,7 +6,6 @@ import Input from './Input';
import Tag from './Tag';
const components = {
Switch,
Button,
Modal,
Table,
......
......@@ -2,8 +2,9 @@ const borders = {
radii: {
none: '0',
sm: '4px',
base: '10px',
lg: '30px',
md: '8px',
base: '12px',
lg: '24px',
full: '9999px',
},
}
......
......@@ -8,8 +8,15 @@ const typography = {
textStyles: {
h2: {
fontSize: [ '32px' ],
fontWeight: 'semibold',
fontWeight: '500',
lineHeight: '40px',
fontFamily: 'heading',
},
h3: {
fontSize: '24px',
fontWeight: '500',
lineHeight: '32px',
fontFamily: 'heading',
},
},
}
......
......@@ -79,15 +79,15 @@ const AddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
<Modal isOpen={ isOpen } onClose={ onClose } size="md">
<ModalOverlay/>
<ModalContent>
<ModalHeader fontWeight="500">{ title }</ModalHeader>
<ModalHeader fontWeight="500" textStyle="h3">{ title }</ModalHeader>
<ModalCloseButton/>
<ModalBody>
{ !data && (
<Text lineHeight="30px" marginBottom="40px">
<Text lineHeight="30px" marginBottom={ 12 }>
An Email notification can be sent to you when an address on your watch list sends or receives any transactions.
</Text>
) }
<FormControl variant="floating" id="address" marginBottom="20px" isRequired>
<FormControl variant="floating" id="address" marginBottom={ 5 } isRequired>
<Input
placeholder=" "
onChange={ onAddressChange }
......@@ -98,31 +98,32 @@ const AddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
/>
<FormLabel>Address (0x...)</FormLabel>
</FormControl>
<FormControl variant="floating" id="tag" marginBottom="30px" isRequired>
<FormControl variant="floating" id="tag" marginBottom={ 8 } isRequired>
<Input placeholder=" " onChange={ onTagChange } value={ tag || '' } maxLength={ 35 }/>
<FormLabel>Private tag (max 35 characters)</FormLabel>
</FormControl>
<Text color="gray.600" fontSize="sm" marginBottom="32px">
<Text color="gray.500" fontSize="sm" marginBottom={ 8 }>
Please select what types of notifications you will receive:
</Text>
<Box marginBottom="32px">
<Box marginBottom={ 8 }>
<Grid templateColumns="repeat(3, max-content)" gap="20px 24px">
{ NOTIFICATIONS.map((notification: string) => {
return (
<>
<GridItem>{ notification }</GridItem>
<GridItem><Checkbox colorScheme="green">Incoming</Checkbox></GridItem>
<GridItem><Checkbox colorScheme="green">Outgoing</Checkbox></GridItem>
<GridItem><Checkbox colorScheme="blue" size="lg">Incoming</Checkbox></GridItem>
<GridItem><Checkbox colorScheme="blue" size="lg">Outgoing</Checkbox></GridItem>
</>
)
}) }
</Grid>
</Box>
<Text color="gray.600" fontSize="sm" marginBottom="20px">Notification methods:</Text>
<Text color="gray.500" fontSize="sm" marginBottom={ 5 }>Notification methods:</Text>
<Checkbox
isChecked={ notification }
colorScheme="green"
colorScheme="blue"
onChange={ onNotificationChange }
size="lg"
>
Email notifications
</Checkbox>
......
import React from 'react';
import Jazzicon, { jsNumberForAddress } from 'react-jazzicon';
import { Link, HStack, VStack, Image, Text, Icon } from '@chakra-ui/react';
import { Box, Link, HStack, VStack, Image, Text, Icon } from '@chakra-ui/react';
import CopyToClipboard from '../CopyToClipboard/CopyToClipboard';
import type { TWatchlistItem } from '../../data/watchlist';
......@@ -9,32 +10,42 @@ import TokensIcon from '../../icons/tokens.svg';
import WalletIcon from '../../icons/wallet.svg';
const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
const image = <Jazzicon diameter={ 50 } seed={ jsNumberForAddress(item.address) }/>
return (
<HStack spacing={ 3 } align="top">
<Image src="/acc.png" alt="Account Image" w="50px" h="50px"/>
<VStack align="stretch" overflow="hidden">
<Box width="50px">{ image }</Box>
<VStack spacing={ 2 } align="stretch" overflow="hidden">
<HStack spacing={ 2 } alignContent="center">
<Link href="#" color="blue.500" title={ item.address } overflow="hidden" textOverflow="ellipsis">
<Link
href="#"
color="blue.500"
title={ item.address }
overflow="hidden"
textOverflow="ellipsis"
fontWeight={ 600 }
lineHeight="24px"
>
{ item.address }
</Link>
<CopyToClipboard text={ item.address }/>
</HStack>
{ item.tokenBalance && (
<HStack spacing={ 0 } fontSize="xs">
<HStack spacing={ 0 } fontSize="sm" h={ 6 }>
<Image src="./xdai.png" alt="chain-logo" marginRight="10px" w="16px" h="16px"/>
<Text>{ item.tokenBalance + ' xDAI' }</Text>
<Text color="gray.500">{ `${ nbsp }($${ item.tokenBalanceUSD } USD)` }</Text>
</HStack>
) }
{ item.tokensAmount && (
<HStack spacing={ 0 } fontSize="xs">
<HStack spacing={ 0 } fontSize="sm">
<Icon as={ TokensIcon } marginRight="10px" w="17px" h="16px"/>
<Text>{ item.tokensAmount + ' tokens' }</Text>
<Text color="gray.500">{ `${ nbsp }($${ item.tokensUSD } USD)` }</Text>
</HStack>
) }
{ item.totalUSD && (
<HStack spacing={ 0 } fontSize="xs">
<HStack spacing={ 0 } fontSize="sm">
<Icon as={ WalletIcon } marginRight="10px" w="16px" h="16px"/>
<Text>{ `Total balance:${ nbsp }` }</Text>
<Link href="#" color="blue.500">{ `$${ item.totalUSD } USD` }</Link>
......
......@@ -35,15 +35,15 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
<Tr alignItems="top" key={ item.address }>
<Td><WatchListAddressItem item={ item }/></Td>
<Td>
<Tag lineHeight="24px" title={ item.tag }>
<Tag variant="gray" lineHeight="24px" title={ item.tag }>
{ item.tag }
</Tag>
</Td>
<Td><Switch colorScheme="green" size="md" isChecked={ item.notification }/></Td>
<Td><Switch colorScheme="blue" size="md" isChecked={ item.notification }/></Td>
<Td>
<HStack spacing="30px">
<Icon as={ EditIcon } w="20px" h="20px" cursor="pointer" color="blue.500" onClick={ onItemEditClick }/>
<Icon as={ DeleteIcon } w="20px" h="20px" cursor="pointer" color="red.200" onClick={ onItemDeleteClick }/>
<HStack spacing={ 6 }>
<Icon as={ EditIcon } w="20px" h="20px" cursor="pointer" color="blue.600" onClick={ onItemEditClick }/>
<Icon as={ DeleteIcon } w="20px" h="20px" cursor="pointer" color="blue.600" onClick={ onItemDeleteClick }/>
</HStack>
</Td>
</Tr>
......
......@@ -25,10 +25,10 @@ const WatchlistTable = ({ data, onDeleteClick, onEditClick }: Props) => {
<Table variant="simple" minWidth="600px">
<Thead>
<Tr>
<Th width="70%" overflow="hidden">Address</Th>
<Th width="30%" overflow="hidden">Private tag</Th>
<Th width="108px" overflow="hidden">Notification</Th>
<Th width="108px" overflow="hidden"></Th>
<Th width="70%">Address</Th>
<Th width="30%">Private tag</Th>
<Th width="108px">Notification</Th>
<Th width="108px"></Th>
</Tr>
</Thead>
<Tbody>
......
......@@ -42,7 +42,7 @@ const WatchList: React.FC = () => {
<Page>
<Box h="100%">
<Box as="h1" textStyle="h2" marginBottom={ 8 }>Watch list</Box>
<Text marginBottom="40px">An Email notification can be sent to you when an address on your watch list sends or receives any transactions.</Text>
<Text marginBottom={ 12 }>An Email notification can be sent to you when an address on your watch list sends or receives any transactions.</Text>
{ Boolean(watchlist.length) && (
<WatchlistTable
data={ watchlist }
......@@ -50,7 +50,7 @@ const WatchList: React.FC = () => {
onEditClick={ onEditClick }
/>
) }
<Box marginTop="32px">
<Box marginTop={ 8 }>
<Button
variant="primary"
onClick={ addressModalProps.onOpen }
......
......@@ -2446,6 +2446,11 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
mersenne-twister@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==
micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
......@@ -2792,6 +2797,13 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-jazzicon@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/react-jazzicon/-/react-jazzicon-1.0.4.tgz#31e5f6908e042786ba93a9093b852dea1870e7a0"
integrity sha512-/3kWv5vtAhI18GBFoqjpxRTtL+EImuB73PAC02r/zJQ6E+PAUmoBx8edYvTCIYHwS01uFf6N3elTDqSrVPwg4w==
dependencies:
mersenne-twister "^1.1.0"
react-remove-scroll-bar@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.1.tgz#9f13b05b249eaa57c8d646c1ebb83006b3581f5f"
......
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