refactor: UI improvements (#67)
* feat: add pointer on SiteCard * fix: don`t show ens when it`s empty * style: add icons on wallet button * styles: align home button on same splace in all views * style: add tooltip on attributes card * chore: install react-icons * feat: add paste feature on owner address field * style: add icon of connected wallet * style: add icon metamask * fix: fix error message on owner address field * chore: remove console.log * style: add colors theme * refactor: refactor icons. Create icon component * refactor: remove function from component * fix: fix husky precommit to add jsx and tsx files * refactor: add metamask icon * fix: fix import * chore: remove metamask svg from assets
This commit is contained in:
parent
482203529c
commit
66e041f63f
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"*.{js,json,sol,ts}": "prettier --write"
|
"*.{js,jsx,json,sol,ts,tsx}": "prettier --write"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
"eslint-plugin-react": "^7.31.11",
|
"eslint-plugin-react": "^7.31.11",
|
||||||
"ethers": "^5.7.2",
|
"ethers": "^5.7.2",
|
||||||
"prettier": "^2.8.0",
|
"prettier": "^2.8.0",
|
||||||
|
"react-icons": "^4.7.1",
|
||||||
"react-query": "^3.39.2",
|
"react-query": "^3.39.2",
|
||||||
"ts-loader": "^9.4.1",
|
"ts-loader": "^9.4.1",
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.3",
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@ export const AttributesDetail = ({
|
||||||
return (
|
return (
|
||||||
<HStack shouldWrapChildren display="inline" spacing="0px">
|
<HStack shouldWrapChildren display="inline" spacing="0px">
|
||||||
<CardAttributes heading="Owner" info={owner} />
|
<CardAttributes heading="Owner" info={owner} />
|
||||||
{attributes.map((attribute) => (
|
{attributes.map(
|
||||||
<CardAttributes
|
(attribute) =>
|
||||||
key={attribute.trait_type}
|
attribute.value !== '' && (
|
||||||
heading={attribute.trait_type}
|
<CardAttributes
|
||||||
info={attribute.value}
|
key={attribute.trait_type}
|
||||||
/>
|
heading={attribute.trait_type}
|
||||||
))}
|
info={attribute.value}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
<CardAttributes heading="Token ID" info={tokendId} />
|
<CardAttributes heading="Token ID" info={tokendId} />
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Card, CardBody } from '@chakra-ui/react';
|
import { Card, CardBody, Tooltip } from '@chakra-ui/react';
|
||||||
import { TileInfo } from '../tile-info';
|
import { TileInfo } from '../tile-info';
|
||||||
|
|
||||||
type CardAttributesProps = {
|
type CardAttributesProps = {
|
||||||
|
|
@ -15,9 +15,11 @@ export const CardAttributes = ({ heading, info }: CardAttributesProps) => (
|
||||||
variant="outline"
|
variant="outline"
|
||||||
width="200px"
|
width="200px"
|
||||||
>
|
>
|
||||||
<CardBody width="200px">
|
<Tooltip label={info} bg="gray">
|
||||||
<TileInfo size="sm" heading={heading} info={info} widthText={160} />
|
<CardBody width="200px">
|
||||||
</CardBody>
|
<TileInfo size="sm" heading={heading} info={info} widthText={160} />
|
||||||
|
</CardBody>
|
||||||
|
</Tooltip>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@ export const SiteCard: React.FC<CardSiteProps> = ({ tokenId }) => {
|
||||||
const { name, owner, image, external_url: externalUrl } = data as any;
|
const { name, owner, image, external_url: externalUrl } = data as any;
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
borderColor="#f3f3f36b !important"
|
_hover={{ cursor: 'pointer' }}
|
||||||
|
borderColor="custom.white.100 !important"
|
||||||
boxShadow="1px 10px 24px -2px #85848480"
|
boxShadow="1px 10px 24px -2px #85848480"
|
||||||
backgroundColor="#c5c5c50a"
|
backgroundColor="custom.white.50"
|
||||||
border="1px"
|
border="1px"
|
||||||
borderRadius="10px"
|
borderRadius="10px"
|
||||||
width="350px"
|
width="350px"
|
||||||
|
|
@ -67,7 +68,7 @@ export const SiteCard: React.FC<CardSiteProps> = ({ tokenId }) => {
|
||||||
>
|
>
|
||||||
<Box height="180px">
|
<Box height="180px">
|
||||||
<ImagePreview
|
<ImagePreview
|
||||||
backgroundColor="#161616"
|
backgroundColor="custom.black"
|
||||||
display="block"
|
display="block"
|
||||||
marginLeft="auto"
|
marginLeft="auto"
|
||||||
marginRight="auto"
|
marginRight="auto"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './metamask-icon';
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
import { Icon, IconProps } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
export const MetamaskIcon: React.FC<IconProps> = (props) => {
|
||||||
|
const { width = '1.5em', height = '1.5em' } = props;
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
{...props}
|
||||||
|
viewBox="0 0 256 240"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
preserveAspectRatio="xMidYMid"
|
||||||
|
>
|
||||||
|
<title>MetaMask</title>
|
||||||
|
<g>
|
||||||
|
<polygon
|
||||||
|
fill="#E17726"
|
||||||
|
points="250.066018 -8.89651791e-15 140.218553 81.2793133 160.645643 33.3787726"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="6.19062016 0.0955267053 95.3715526 33.38465 114.767923 81.9132784"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="205.859986 172.858026 254.410647 173.782023 237.442988 231.424252 178.200429 215.112736"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="50.1391619 172.857971 77.6964289 215.11288 18.5530579 231.425317 1.68846828 173.782036"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="112.130724 69.5516472 114.115388 133.635085 54.744344 130.933905 71.6319541 105.456448 71.8456974 105.210668"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="143.254237 68.8369186 184.153999 105.213392 184.365514 105.45719 201.253537 130.934656 141.89632 133.635226"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="79.4347776 173.043957 111.853145 198.302774 74.1951401 216.484384"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27625"
|
||||||
|
points="176.57078 173.040009 181.701672 216.484523 144.149363 198.301203"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#D5BFB2"
|
||||||
|
points="144.977922 195.921642 183.084879 214.373531 147.637779 231.220354 148.005818 220.085704"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#D5BFB2"
|
||||||
|
points="111.01133 195.929982 108.102093 219.90359 108.340838 231.207237 72.8105145 214.373665"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#233447"
|
||||||
|
points="100.007166 141.998856 109.965172 162.926822 76.0615945 152.995277"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#233447"
|
||||||
|
points="155.991579 142.000941 180.049716 152.994594 146.03608 162.923638"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#CC6228"
|
||||||
|
points="82.0263962 172.830401 76.5459821 217.870023 47.1731221 173.814952"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#CC6228"
|
||||||
|
points="173.976111 172.8305 208.830462 173.815081 179.347016 217.871514"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#CC6228"
|
||||||
|
points="202.112267 128.387342 176.746779 154.238424 157.190334 145.301352 147.82685 164.985265 141.688645 131.136429"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#CC6228"
|
||||||
|
points="53.8753865 128.386879 114.309585 131.136429 108.17138 164.985265 98.8061425 145.303856 79.3525107 154.238823"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27525"
|
||||||
|
points="52.165606 123.082486 80.8639084 152.203386 81.8584812 180.952278"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27525"
|
||||||
|
points="203.863346 123.029784 174.117491 181.003017 175.237428 152.202737"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27525"
|
||||||
|
points="112.906762 124.855691 114.061658 132.125682 116.915771 150.236518 115.080954 205.861884 106.405804 161.177486 106.402953 160.71542"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#E27525"
|
||||||
|
points="143.077997 124.755417 149.599051 160.715451 149.596194 161.177486 140.899333 205.973714 140.55515 194.76913 139.198167 149.907127"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#F5841F"
|
||||||
|
points="177.788479 151.045975 176.81718 176.023897 146.543342 199.61119 140.4233 195.28712 147.283427 159.951634"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#F5841F"
|
||||||
|
points="78.3167053 151.046455 108.716464 159.952427 115.576437 195.28712 109.456385 199.611197 79.1807344 176.021881"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#C0AC9D"
|
||||||
|
points="67.0180978 208.857597 105.750143 227.209502 105.586194 219.372868 108.826835 216.528328 147.160694 216.528328 150.518758 219.363342 150.271375 227.194477 188.757733 208.903978 170.030292 224.379509 147.384611 239.933315 108.516484 239.933315 85.8855503 224.315941"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#161616"
|
||||||
|
points="142.203502 193.479367 147.679764 197.347701 150.888964 222.952494 146.244706 219.030957 109.769299 219.030957 105.213447 223.031398 108.317268 197.349663 113.795429 193.479367"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#763E1A"
|
||||||
|
points="242.814251 2.24978946 256 41.8072765 247.765337 81.803692 253.629038 86.3274221 245.694407 92.3812097 251.657525 96.9865879 243.761206 104.178247 248.609106 107.688972 235.743366 122.714803 182.973386 107.350364 182.516079 107.105244 144.488982 75.0267414"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#763E1A"
|
||||||
|
points="13.1860054 2.24978557 111.51151 75.0267402 73.4844118 107.105244 73.0271023 107.350365 20.2567388 122.714804 7.39121291 107.688927 12.2352706 104.180751 4.34251001 96.9865923 10.2945566 92.3862179 2.24133703 86.315099 8.32629691 81.7886671 -8.89651791e-15 41.8087534"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#F5841F"
|
||||||
|
points="180.391638 103.990363 236.304873 120.269177 254.470245 176.254719 206.546445 176.25462 173.525532 176.671282 197.539657 129.863284"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#F5841F"
|
||||||
|
points="75.6080363 103.990376 58.4568191 129.863284 82.4741865 176.671282 49.4693913 176.254719 1.63053271 176.254719 19.6938968 120.269548"
|
||||||
|
></polygon>
|
||||||
|
<polygon
|
||||||
|
fill="#F5841F"
|
||||||
|
points="163.383898 33.1117385 147.744691 75.3505047 144.425852 132.411352 143.155934 150.295986 143.055195 195.983514 112.943788 195.983514 112.846176 150.381702 111.572114 132.395585 108.251786 75.3505047 92.6150854 33.1117385"
|
||||||
|
></polygon>
|
||||||
|
</g>
|
||||||
|
</Icon>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { FaWallet } from 'react-icons/fa';
|
||||||
|
import { IoExitOutline } from 'react-icons/io5';
|
||||||
|
import { AiOutlineCopy } from 'react-icons/ai';
|
||||||
|
import { MetamaskIcon } from './custom';
|
||||||
|
|
||||||
|
export const IconLibrary = Object.freeze({
|
||||||
|
copy: AiOutlineCopy,
|
||||||
|
'log-out': IoExitOutline,
|
||||||
|
metamask: MetamaskIcon,
|
||||||
|
wallet: FaWallet,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type IconName = keyof typeof IconLibrary;
|
||||||
|
|
||||||
|
export type IconType<Name extends IconName> = typeof IconLibrary[Name];
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import {
|
||||||
|
forwardRef,
|
||||||
|
IconProps as IconPropsChakra,
|
||||||
|
Icon as IconChakra,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { IconLibrary, IconName, IconType } from './icon-types';
|
||||||
|
|
||||||
|
export type IconComponentProps = IconPropsChakra & { name: IconName };
|
||||||
|
|
||||||
|
export const Icon = forwardRef<IconComponentProps, 'svg'>(
|
||||||
|
({ name, ...iconProps }, ref) => {
|
||||||
|
const IconElement: IconType<typeof name> = IconLibrary[name];
|
||||||
|
return <IconChakra as={IconElement} {...iconProps} ref={ref} />;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './icon';
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
export * from './wallet-button';
|
export * from './wallet-button';
|
||||||
|
export * from './wallet.utils';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,16 @@
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useAppDispatch, useWalletStore, walletActions } from '@/store';
|
import { useAppDispatch, useWalletStore, walletActions } from '@/store';
|
||||||
import { contractAddress } from '@/utils';
|
import { contractAddress } from '@/utils';
|
||||||
import { Menu, MenuButton, MenuList, MenuItem, Button } from '@chakra-ui/react';
|
import {
|
||||||
|
Menu,
|
||||||
|
MenuButton,
|
||||||
|
MenuList,
|
||||||
|
MenuItem,
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { Icon } from '../icon';
|
||||||
|
import { WalletType } from './wallet.utils';
|
||||||
|
|
||||||
const WalletMenu: React.FC = () => {
|
const WalletMenu: React.FC = () => {
|
||||||
const { account = '', provider } = useWalletStore();
|
const { account = '', provider } = useWalletStore();
|
||||||
|
|
@ -17,13 +26,33 @@ const WalletMenu: React.FC = () => {
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu colorScheme={'custom.gray.200'}>
|
||||||
<MenuButton as={Button}>
|
<Button borderRadius="50px" as={MenuButton}>
|
||||||
{`${provider} (${contractAddress(account)})`}
|
<Flex alignItems={'center'}>
|
||||||
</MenuButton>
|
<Icon
|
||||||
<MenuList>
|
name={WalletType[provider?.toString() as keyof typeof WalletType]}
|
||||||
<MenuItem onClick={handleCopyAccount}>Copy Account</MenuItem>
|
mr="0.5em"
|
||||||
<MenuItem onClick={handleDisconnect}>Disconnect</MenuItem>
|
/>
|
||||||
|
{contractAddress(account)}
|
||||||
|
</Flex>
|
||||||
|
</Button>
|
||||||
|
<MenuList bg={'custom.gray.200'}>
|
||||||
|
<MenuItem
|
||||||
|
_hover={{ bg: 'custom.gray.100' }}
|
||||||
|
bg={'custom.gray.200'}
|
||||||
|
onClick={handleCopyAccount}
|
||||||
|
icon={<Icon name="copy" />}
|
||||||
|
>
|
||||||
|
Copy Account
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
_hover={{ bg: 'custom.gray.100' }}
|
||||||
|
bg={'custom.gray.200'}
|
||||||
|
onClick={handleDisconnect}
|
||||||
|
icon={<Icon name="log-out" />}
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|
@ -40,15 +69,24 @@ const ConnectionMenu: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<Button
|
||||||
as={Button}
|
borderRadius="50px"
|
||||||
|
as={MenuButton}
|
||||||
|
leftIcon={<Icon name="wallet" />}
|
||||||
isLoading={state === 'loading'}
|
isLoading={state === 'loading'}
|
||||||
disabled={state === 'loading'}
|
disabled={state === 'loading'}
|
||||||
>
|
>
|
||||||
Connect Wallet
|
Connect
|
||||||
</MenuButton>
|
</Button>
|
||||||
<MenuList>
|
<MenuList bg={'custom.gray.200'}>
|
||||||
<MenuItem onClick={handleConnectWallet}>Metamask</MenuItem>
|
<MenuItem
|
||||||
|
_hover={{ bg: 'custom.gray.100' }}
|
||||||
|
bg={'custom.gray.200'}
|
||||||
|
onClick={handleConnectWallet}
|
||||||
|
icon={<Icon name={WalletType.metamask} />}
|
||||||
|
>
|
||||||
|
Metamask
|
||||||
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export enum WalletType {
|
||||||
|
metamask = 'metamask',
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
export const colors = {
|
||||||
|
custom: {
|
||||||
|
gray: {
|
||||||
|
100: '#4e4e4e',
|
||||||
|
200: '#282824',
|
||||||
|
},
|
||||||
|
black: '#161616',
|
||||||
|
blue: {
|
||||||
|
100: '#1d4ed8',
|
||||||
|
},
|
||||||
|
white: {
|
||||||
|
50: '#c5c5c50a',
|
||||||
|
100: '#f3f3f36b',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './colors';
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import { extendTheme } from '@chakra-ui/react';
|
import { extendTheme } from '@chakra-ui/react';
|
||||||
|
import { colors } from './foundations';
|
||||||
|
|
||||||
const appTheme = {
|
const appTheme = {
|
||||||
styles: {
|
styles: {
|
||||||
global: {
|
global: {
|
||||||
body: {
|
body: {
|
||||||
color: 'rgba(255, 255, 255)',
|
color: 'rgba(255, 255, 255)',
|
||||||
bg: '#161616',
|
bg: 'custom.black',
|
||||||
margin: '50px',
|
margin: '25px 50px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -17,6 +18,7 @@ const appTheme = {
|
||||||
sizes: {
|
sizes: {
|
||||||
modalHeight: '345px',
|
modalHeight: '345px',
|
||||||
},
|
},
|
||||||
|
colors,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const theme = extendTheme(appTheme);
|
export const theme = extendTheme(appTheme);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export const MintedSiteDetail = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex width="full" align="center" justifyContent="center">
|
<Flex width="full" align="center" justifyContent="center" mt="30px">
|
||||||
<Box width={{ base: '100%' }}>
|
<Box width={{ base: '100%' }}>
|
||||||
<HomeButton />
|
<HomeButton />
|
||||||
<Box
|
<Box
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
Heading,
|
Heading,
|
||||||
Flex,
|
Flex,
|
||||||
|
|
@ -7,17 +7,19 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Button,
|
Button,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
IconButton,
|
|
||||||
Textarea,
|
Textarea,
|
||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
|
VStack,
|
||||||
|
InputGroup,
|
||||||
|
Input,
|
||||||
|
InputRightElement,
|
||||||
|
InputProps,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { Formik, Field } from 'formik';
|
import { Formik, Field, useFormikContext } from 'formik';
|
||||||
import { ArrowBackIcon } from '@chakra-ui/icons';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { getRepoAndCommit } from '@/utils';
|
import { getRepoAndCommit } from '@/utils';
|
||||||
import { validateFields } from './mint-site.utils';
|
import { validateFields } from './mint-site.utils';
|
||||||
import { InputFieldForm } from '@/components';
|
import { HomeButton, InputFieldForm } from '@/components';
|
||||||
import { FleekERC721 } from '@/integrations';
|
import { FleekERC721 } from '@/integrations';
|
||||||
import { useWalletStore } from '@/store';
|
import { useWalletStore } from '@/store';
|
||||||
import { useToast } from '@/hooks';
|
import { useToast } from '@/hooks';
|
||||||
|
|
@ -42,6 +44,29 @@ const initialValues = {
|
||||||
ens: '',
|
ens: '',
|
||||||
} as FormValues;
|
} as FormValues;
|
||||||
|
|
||||||
|
const OwnerAdress = (props: InputProps) => {
|
||||||
|
const { setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
const handlePasteAddress = () => {
|
||||||
|
if (setFieldValue && props.name) {
|
||||||
|
navigator.clipboard
|
||||||
|
.readText()
|
||||||
|
.then((text) => setFieldValue(props.name as string, text));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InputGroup size="md">
|
||||||
|
<Input {...props} pr="4.5rem" />
|
||||||
|
<InputRightElement width="4.5rem">
|
||||||
|
<Button h="1.75rem" size="sm" onClick={handlePasteAddress}>
|
||||||
|
Paste
|
||||||
|
</Button>
|
||||||
|
</InputRightElement>
|
||||||
|
</InputGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const MintSite = () => {
|
export const MintSite = () => {
|
||||||
const setToastInfo = useToast();
|
const setToastInfo = useToast();
|
||||||
const { provider } = useWalletStore();
|
const { provider } = useWalletStore();
|
||||||
|
|
@ -94,128 +119,141 @@ export const MintSite = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex width="full" align="center" justifyContent="center" mt="50px">
|
<Flex width="full" align="center" justifyContent="center" mt="30px">
|
||||||
<Box width={{ base: '100%', md: '80%' }}>
|
<Box width={{ base: '100%' }}>
|
||||||
<IconButton
|
<HomeButton />
|
||||||
as={Link}
|
<VStack spacing="10px">
|
||||||
to="/home"
|
<Box textAlign="center" mt={2}>
|
||||||
aria-label="back home"
|
<Heading>Mint your Site</Heading>
|
||||||
icon={<ArrowBackIcon />}
|
</Box>
|
||||||
variant="link"
|
<Box textAlign="left" width="80%" justifyContent="center">
|
||||||
size={'xl'}
|
<Formik
|
||||||
textDecoration={'none'}
|
validate={validateFields}
|
||||||
/>
|
initialValues={initialValues}
|
||||||
<Box textAlign="center" mt={2}>
|
onSubmit={handleSubmitForm}
|
||||||
<Heading>Mint your Site</Heading>
|
>
|
||||||
</Box>
|
{({ values, touched, handleSubmit, isSubmitting, errors }) => (
|
||||||
<Box my={4} textAlign="left">
|
<form onSubmit={handleSubmit}>
|
||||||
<Formik
|
<Box
|
||||||
validate={validateFields}
|
display="flex"
|
||||||
initialValues={initialValues}
|
flexDirection={{ base: 'column', md: 'row' }}
|
||||||
onSubmit={handleSubmitForm}
|
>
|
||||||
>
|
|
||||||
{({ values, touched, handleSubmit, isSubmitting, errors }) => (
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<Box
|
|
||||||
display="flex"
|
|
||||||
flexDirection={{ base: 'column', md: 'row' }}
|
|
||||||
>
|
|
||||||
<InputFieldForm
|
|
||||||
label="Name"
|
|
||||||
fieldName="name"
|
|
||||||
mr={5}
|
|
||||||
error={errors.name}
|
|
||||||
isInvalid={!!errors.name && touched.name}
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
<InputFieldForm
|
|
||||||
label="Owner address"
|
|
||||||
fieldName="ownerAddress"
|
|
||||||
error={errors.ownerAddress}
|
|
||||||
isInvalid={!!errors.ownerAddress && touched.ownerAddress}
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<FormControl
|
|
||||||
mt={6}
|
|
||||||
isRequired
|
|
||||||
isInvalid={!!errors.description && touched.description}
|
|
||||||
>
|
|
||||||
<FormLabel htmlFor="description">Description</FormLabel>
|
|
||||||
<Field as={Textarea} name="description" id="description" />
|
|
||||||
{errors.description && (
|
|
||||||
<FormErrorMessage>{errors.description}</FormErrorMessage>
|
|
||||||
)}
|
|
||||||
</FormControl>
|
|
||||||
<Box
|
|
||||||
display="flex"
|
|
||||||
flexDirection={{ base: 'column', md: 'row' }}
|
|
||||||
mt={6}
|
|
||||||
>
|
|
||||||
<InputFieldForm
|
|
||||||
label="Image (IPFS Link)"
|
|
||||||
fieldName="image"
|
|
||||||
mr={5}
|
|
||||||
error={errors.image}
|
|
||||||
isInvalid={!!errors.image && touched.image}
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
<InputFieldForm
|
|
||||||
label="External url"
|
|
||||||
fieldName="externalUrl"
|
|
||||||
error={errors.externalUrl}
|
|
||||||
isInvalid={!!errors.externalUrl && touched.externalUrl}
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Grid
|
|
||||||
templateColumns={{
|
|
||||||
md: 'repeat(3, 1fr)',
|
|
||||||
}}
|
|
||||||
gap={4}
|
|
||||||
mt={6}
|
|
||||||
>
|
|
||||||
<GridItem colSpan={2}>
|
|
||||||
<InputFieldForm
|
<InputFieldForm
|
||||||
label="Github commit url"
|
label="Name"
|
||||||
fieldName="githubCommit"
|
fieldName="name"
|
||||||
mr={5}
|
mr={5}
|
||||||
error={errors.githubCommit}
|
error={errors.name}
|
||||||
isInvalid={
|
isInvalid={!!errors.name && touched.name}
|
||||||
!!errors.githubCommit && touched.githubCommit
|
|
||||||
}
|
|
||||||
isRequired
|
isRequired
|
||||||
/>
|
/>
|
||||||
</GridItem>
|
<FormControl
|
||||||
<GridItem colSpan={{ base: 2, md: 1 }}>
|
isRequired
|
||||||
<InputFieldForm label="ENS" fieldName="ens" />
|
isInvalid={
|
||||||
</GridItem>
|
!!errors.ownerAddress && touched.ownerAddress
|
||||||
</Grid>
|
}
|
||||||
<Button
|
>
|
||||||
colorScheme="blue"
|
<FormLabel htmlFor="ownerAddress">
|
||||||
backgroundColor="#1d4ed8"
|
Owner address
|
||||||
width="full"
|
</FormLabel>
|
||||||
mt={4}
|
<Field
|
||||||
type="submit"
|
as={OwnerAdress}
|
||||||
isLoading={isSubmitting}
|
name="ownerAddress"
|
||||||
loadingText="Minting..."
|
id="ownerAddress"
|
||||||
disabled={
|
/>
|
||||||
isSubmitting ||
|
{errors.ownerAddress && (
|
||||||
!values.name ||
|
<FormErrorMessage>
|
||||||
!values.description ||
|
{errors.ownerAddress}
|
||||||
!values.githubCommit ||
|
</FormErrorMessage>
|
||||||
!values.ownerAddress ||
|
)}
|
||||||
!values.image ||
|
</FormControl>
|
||||||
!values.externalUrl ||
|
</Box>
|
||||||
!provider
|
<FormControl
|
||||||
}
|
mt={6}
|
||||||
>
|
isRequired
|
||||||
Mint
|
isInvalid={!!errors.description && touched.description}
|
||||||
</Button>
|
>
|
||||||
</form>
|
<FormLabel htmlFor="description">Description</FormLabel>
|
||||||
)}
|
<Field
|
||||||
</Formik>
|
as={Textarea}
|
||||||
</Box>
|
name="description"
|
||||||
|
id="description"
|
||||||
|
/>
|
||||||
|
{errors.description && (
|
||||||
|
<FormErrorMessage>
|
||||||
|
{errors.description}
|
||||||
|
</FormErrorMessage>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
<Box
|
||||||
|
display="flex"
|
||||||
|
flexDirection={{ base: 'column', md: 'row' }}
|
||||||
|
mt={6}
|
||||||
|
>
|
||||||
|
<InputFieldForm
|
||||||
|
label="Image (IPFS Link)"
|
||||||
|
fieldName="image"
|
||||||
|
mr={5}
|
||||||
|
error={errors.image}
|
||||||
|
isInvalid={!!errors.image && touched.image}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputFieldForm
|
||||||
|
label="External url"
|
||||||
|
fieldName="externalUrl"
|
||||||
|
error={errors.externalUrl}
|
||||||
|
isInvalid={!!errors.externalUrl && touched.externalUrl}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Grid
|
||||||
|
templateColumns={{
|
||||||
|
md: 'repeat(3, 1fr)',
|
||||||
|
}}
|
||||||
|
gap={4}
|
||||||
|
mt={6}
|
||||||
|
>
|
||||||
|
<GridItem colSpan={2}>
|
||||||
|
<InputFieldForm
|
||||||
|
label="Github commit url"
|
||||||
|
fieldName="githubCommit"
|
||||||
|
mr={5}
|
||||||
|
error={errors.githubCommit}
|
||||||
|
isInvalid={
|
||||||
|
!!errors.githubCommit && touched.githubCommit
|
||||||
|
}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
<GridItem colSpan={{ base: 2, md: 1 }}>
|
||||||
|
<InputFieldForm label="ENS" fieldName="ens" />
|
||||||
|
</GridItem>
|
||||||
|
</Grid>
|
||||||
|
<Button
|
||||||
|
colorScheme="blue"
|
||||||
|
backgroundColor="custom.blue.100"
|
||||||
|
width="full"
|
||||||
|
mt={4}
|
||||||
|
type="submit"
|
||||||
|
isLoading={isSubmitting}
|
||||||
|
loadingText="Minting..."
|
||||||
|
disabled={
|
||||||
|
isSubmitting ||
|
||||||
|
!values.name ||
|
||||||
|
!values.description ||
|
||||||
|
!values.githubCommit ||
|
||||||
|
!values.ownerAddress ||
|
||||||
|
!values.image ||
|
||||||
|
!values.externalUrl ||
|
||||||
|
!provider
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Mint
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</Box>
|
||||||
|
</VStack>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -3717,6 +3717,11 @@ react-focus-lock@^2.9.1:
|
||||||
use-callback-ref "^1.3.0"
|
use-callback-ref "^1.3.0"
|
||||||
use-sidecar "^1.1.2"
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
|
react-icons@^4.7.1:
|
||||||
|
version "4.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.7.1.tgz#0f4b25a5694e6972677cb189d2a72eabea7a8345"
|
||||||
|
integrity sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==
|
||||||
|
|
||||||
react-is@^16.13.1, react-is@^16.7.0:
|
react-is@^16.13.1, react-is@^16.7.0:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue