Files
tom goriunovandGitHub 5e80806796 UI toolkit package (#2691)
* first version of the pack

* single entry point

* add custom components to the package

* move form components to toolkit

* add more utils and hooks to the package

* minor fixes

* add CI workflow

* update readme and package.json

* fix ts

* fix build of env-validator

* fix docker build

* fix icons size

* test fixes

* more test fixes
2025-04-21 19:44:22 +02:00

138 lines
4.3 KiB
TypeScript

import { Box, Separator, Flex, VStack } from '@chakra-ui/react';
import React from 'react';
import type { NavLink } from './types';
import type { UserInfo } from 'types/api/account';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import { useMarketplaceContext } from 'lib/contexts/marketplace';
import shortenString from 'lib/shortenString';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import { Hint } from 'toolkit/components/Hint/Hint';
import TruncatedValue from 'ui/shared/TruncatedValue';
import useLogout from 'ui/snippets/auth/useLogout';
import UserWalletAutoConnectAlert from '../UserWalletAutoConnectAlert';
import UserProfileContentNavLink from './UserProfileContentNavLink';
import UserProfileContentWallet from './UserProfileContentWallet';
const navLinks: Array<NavLink> = [
{
text: 'My profile',
href: route({ pathname: '/auth/profile' }),
icon: 'profile' as const,
},
{
text: 'Watch list',
href: route({ pathname: '/account/watchlist' }),
icon: 'star_outline' as const,
},
{
text: 'Private tags',
href: route({ pathname: '/account/tag-address' }),
icon: 'private_tags_slim' as const,
},
{
text: 'API keys',
href: route({ pathname: '/account/api-key' }),
icon: 'API_slim' as const,
},
{
text: 'Custom ABI',
href: route({ pathname: '/account/custom-abi' }),
icon: 'ABI_slim' as const,
},
config.features.addressVerification.isEnabled && {
text: 'Verified addrs',
href: route({ pathname: '/account/verified-addresses' }),
icon: 'verified_slim' as const,
},
].filter(Boolean);
interface Props {
data: UserInfo | undefined;
onClose: () => void;
onLogin: () => void;
onAddEmail: () => void;
onAddAddress: () => void;
}
const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress }: Props) => {
const { isAutoConnectDisabled } = useMarketplaceContext();
const logout = useLogout();
const handleLogoutClick = React.useCallback(() => {
logout();
onClose();
}, [ logout, onClose ]);
if (!data) {
return (
<Box>
{ isAutoConnectDisabled && <UserWalletAutoConnectAlert/> }
{ config.features.blockchainInteraction.isEnabled && <UserProfileContentWallet onClose={ onClose }/> }
<Button mt={ 3 } onClick={ onLogin } size="sm" w="100%">Log in</Button>
</Box>
);
}
return (
<Box>
{ isAutoConnectDisabled && <UserWalletAutoConnectAlert/> }
<Box textStyle="xs" fontWeight="500" px={ 1 } mb="1">Account</Box>
<Box
textStyle="xs"
fontWeight="500"
borderColor="border.divider"
borderWidth="1px"
borderRadius="base"
color={{ _light: 'gray.500', _dark: 'gray.300' }}
>
{ config.features.blockchainInteraction.isEnabled && (
<Flex p={ 2 } borderColor="border.divider" borderBottomWidth="1px">
<Box>Address</Box>
<Hint
label={ `This wallet address is linked to your Blockscout account. It can be used to login ${ config.features.rewards.isEnabled ? 'and is used for Merits Program participation' : '' }` } // eslint-disable-line max-len
boxSize={ 4 }
ml={ 1 }
/>
{ data?.address_hash ?
<Box ml="auto">{ shortenString(data?.address_hash) }</Box> : <Link ml="auto" onClick={ onAddAddress }>Add address</Link> }
</Flex>
) }
<Flex p={ 2 } columnGap={ 4 }>
<Box mr="auto">Email</Box>
{ data?.email ?
<TruncatedValue value={ data.email }/> : <Link onClick={ onAddEmail }>Add email</Link> }
</Flex>
</Box>
{ config.features.blockchainInteraction.isEnabled && <UserProfileContentWallet onClose={ onClose } mt={ 3 }/> }
<VStack as="ul" gap="0" alignItems="flex-start" overflow="hidden" mt={ 4 }>
{ navLinks.map((item) => (
<UserProfileContentNavLink
key={ item.text }
{ ...item }
onClick={ onClose }
/>
)) }
</VStack>
<Separator my={ 1 }/>
<UserProfileContentNavLink
text="Sign out"
icon="sign_out"
onClick={ handleLogoutClick }
/>
</Box>
);
};
export default React.memo(UserProfileContent);