Commit 712cbb23 authored by tom's avatar tom

profile data from server

parent 7c24b2e7
import type { UserInfo } from 'types/api/account';
import handler from 'lib/api/handler';
const profileHandler = handler<UserInfo>(() => '/account/v1/user/info', [ 'GET' ]);
export default profileHandler;
...@@ -51,7 +51,8 @@ export type Transactions = Array<Transaction> ...@@ -51,7 +51,8 @@ export type Transactions = Array<Transaction>
export interface UserInfo { export interface UserInfo {
name?: string; name?: string;
nickname?: string; nickname?: string;
email?: string; email: string;
avatar?: string;
} }
export interface WatchlistAddress { export interface WatchlistAddress {
......
...@@ -2,11 +2,15 @@ import { Box, Button, Text, VStack, useColorModeValue } from '@chakra-ui/react'; ...@@ -2,11 +2,15 @@ import { Box, Button, Text, VStack, useColorModeValue } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { UserInfo } from 'types/api/account';
import useNavItems from 'lib/hooks/useNavItems'; import useNavItems from 'lib/hooks/useNavItems';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NavLink from 'ui/blocks/navigation/NavLink'; import NavLink from 'ui/blocks/navigation/NavLink';
const ProfileMenuContent = () => { type Props = UserInfo;
const ProfileMenuContent = ({ name, nickname, email }: Props) => {
const { accountNavItems, profileItem } = useNavItems(); const { accountNavItems, profileItem } = useNavItems();
const router = useRouter(); const router = useRouter();
const borderColor = useColorModeValue('gray.200', 'whiteAlpha.200'); const borderColor = useColorModeValue('gray.200', 'whiteAlpha.200');
...@@ -20,7 +24,7 @@ const ProfileMenuContent = () => { ...@@ -20,7 +24,7 @@ const ProfileMenuContent = () => {
color={ primaryTextColor } color={ primaryTextColor }
{ ...getDefaultTransitionProps() } { ...getDefaultTransitionProps() }
> >
Signed in as tgladilina Signed in as { name || nickname }
</Text> </Text>
<Text <Text
fontSize="sm" fontSize="sm"
...@@ -29,7 +33,7 @@ const ProfileMenuContent = () => { ...@@ -29,7 +33,7 @@ const ProfileMenuContent = () => {
color="gray.500" color="gray.500"
{ ...getDefaultTransitionProps() } { ...getDefaultTransitionProps() }
> >
tatyana@blockscout.com { email }
</Text> </Text>
<NavLink { ...profileItem } isActive={ router.asPath === profileItem.pathname } px="0px"/> <NavLink { ...profileItem } isActive={ router.asPath === profileItem.pathname } px="0px"/>
<Box as="nav" mt={ 2 } pt={ 2 } borderTopColor={ borderColor } borderTopWidth="1px" { ...getDefaultTransitionProps() }> <Box as="nav" mt={ 2 } pt={ 2 } borderTopColor={ borderColor } borderTopWidth="1px" { ...getDefaultTransitionProps() }>
......
import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button } from '@chakra-ui/react'; import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
import type { UserInfo } from 'types/api/account';
import ProfileMenuContent from 'ui/blocks/profileMenu/ProfileMenuContent'; import ProfileMenuContent from 'ui/blocks/profileMenu/ProfileMenuContent';
import UserAvatar from 'ui/shared/UserAvatar'; import UserAvatar from 'ui/shared/UserAvatar';
const ProfileMenuDesktop = () => { const ProfileMenuDesktop = () => {
const { data } = useQuery<unknown, unknown, UserInfo>([ 'profile' ], async() => {
const response = await fetch('/api/account/profile');
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
});
return ( return (
<Popover openDelay={ 300 } placement="bottom-end" gutter={ 10 } isLazy> <Popover openDelay={ 300 } placement="bottom-end" gutter={ 10 } isLazy>
<PopoverTrigger> <PopoverTrigger>
<Button variant="unstyled" display="inline-flex" height="auto"> <Button variant="unstyled" display="inline-flex" height="auto">
<UserAvatar size={ 50 }/> <UserAvatar size={ 50 } data={ data }/>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent w="212px"> { data && (
<PopoverBody padding="24px 16px 16px 16px"> <PopoverContent w="212px">
<ProfileMenuContent/> <PopoverBody padding="24px 16px 16px 16px">
</PopoverBody> <ProfileMenuContent { ...data }/>
</PopoverContent> </PopoverBody>
</PopoverContent>
) }
</Popover> </Popover>
); );
}; };
......
import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure } from '@chakra-ui/react'; import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
import type { UserInfo } from 'types/api/account';
import ColorModeToggler from 'ui/blocks/header/ColorModeToggler'; import ColorModeToggler from 'ui/blocks/header/ColorModeToggler';
import ProfileMenuContent from 'ui/blocks/profileMenu/ProfileMenuContent'; import ProfileMenuContent from 'ui/blocks/profileMenu/ProfileMenuContent';
import UserAvatar from 'ui/shared/UserAvatar'; import UserAvatar from 'ui/shared/UserAvatar';
...@@ -8,34 +11,44 @@ import UserAvatar from 'ui/shared/UserAvatar'; ...@@ -8,34 +11,44 @@ import UserAvatar from 'ui/shared/UserAvatar';
const ProfileMenuMobile = () => { const ProfileMenuMobile = () => {
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const { data } = useQuery<unknown, unknown, UserInfo>([ 'profile' ], async() => {
const response = await fetch('/api/account/profile');
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
});
return ( return (
<> <>
<Box padding={ 2 } onClick={ onOpen }> <Box padding={ 2 } onClick={ onOpen }>
<UserAvatar size={ 24 }/> <UserAvatar size={ 24 } { ...data }/>
</Box> </Box>
<Drawer { data && (
isOpen={ isOpen } <Drawer
placement="right" isOpen={ isOpen }
onClose={ onClose } placement="right"
autoFocus={ false } onClose={ onClose }
> autoFocus={ false }
<DrawerOverlay/> >
<DrawerContent maxWidth="260px"> <DrawerOverlay/>
<DrawerBody p={ 6 }> <DrawerContent maxWidth="260px">
<Flex <DrawerBody p={ 6 }>
justifyContent="space-between" <Flex
alignItems="center" justifyContent="space-between"
mb={ 6 } alignItems="center"
> mb={ 6 }
<ColorModeToggler/> >
<Box onClick={ onClose }> <ColorModeToggler/>
<UserAvatar size={ 24 }/> <Box onClick={ onClose }>
</Box> <UserAvatar size={ 24 } data={ data }/>
</Flex> </Box>
<ProfileMenuContent/> </Flex>
</DrawerBody> <ProfileMenuContent { ...data }/>
</DrawerContent> </DrawerBody>
</Drawer> </DrawerContent>
</Drawer>
) }
</> </>
); );
}; };
......
import { useColorModeValue, chakra } from '@chakra-ui/react'; import { useColorModeValue, chakra, Image } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import Identicon from 'react-identicons'; import Identicon from 'react-identicons';
import type { UserInfo } from 'types/api/account';
const ProfileIcon = chakra(Identicon); const ProfileIcon = chakra(Identicon);
interface Props { interface Props {
size: number; size: number;
data?: UserInfo;
} }
const UserAvatar = ({ size }: Props) => { const UserAvatar = ({ size, data }: Props) => {
const sizeString = `${ size }px`; const sizeString = `${ size }px`;
const bgColor = useColorModeValue('blackAlpha.100', 'white');
if (data?.avatar) {
return (
<Image
flexShrink={ 0 }
src={ data.avatar }
alt={ `Profile picture of ${ data.name || data.nickname || '' }` }
w={ sizeString }
minW={ sizeString }
h={ sizeString }
minH={ sizeString }
borderRadius="full"
overflow="hidden"
/>
);
}
return ( return (
<ProfileIcon <ProfileIcon
flexShrink={ 0 } flexShrink={ 0 }
maxWidth={ sizeString } maxWidth={ sizeString }
maxHeight={ sizeString } maxHeight={ sizeString }
string="randomness" string={ data?.email || 'randomness' }
// the displayed size is doubled for retina displays // the displayed size is doubled for retina displays
size={ size * 2 } size={ size * 2 }
bg={ useColorModeValue('blackAlpha.100', 'white') } bg={ bgColor }
borderRadius="50%" borderRadius="full"
overflow="hidden" overflow="hidden"
/> />
); );
......
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