feat: list minted sites (#42)
* feat: add mintes sites list view * wip: add card but need styles * style: add style to site card component * style: add style to site card * fix: fix onClick propagation * chore: remove unused param * Apply suggestions from code review Co-authored-by: Felipe Mendes <zo.fmendes@gmail.com> * Update list.tsx Co-authored-by: Felipe Mendes <zo.fmendes@gmail.com>
This commit is contained in:
parent
6451208871
commit
d96175fa3f
|
|
@ -16,7 +16,7 @@ export const CardAttributes = ({ heading, info }: CardAttributesProps) => (
|
|||
width="200px"
|
||||
>
|
||||
<CardBody width="200px">
|
||||
<TileInfo size="sm" heading={heading} info={info} width={160} />
|
||||
<TileInfo size="sm" heading={heading} info={info} widthText={160} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
import { ImagePreview, TileInfo } from '@/components';
|
||||
import { SiteNFTDetail } from '@/types';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
CardBody,
|
||||
Heading,
|
||||
LayoutProps,
|
||||
Link,
|
||||
Stack,
|
||||
} from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
interface CardSiteProps {
|
||||
site: SiteNFTDetail;
|
||||
tokenId?: string; // TODO add param and remove optional
|
||||
}
|
||||
|
||||
type InfoContainerProps = {
|
||||
heading: string;
|
||||
info: React.ReactNode;
|
||||
width: LayoutProps['width'];
|
||||
};
|
||||
|
||||
const InfoContainer = ({ heading, info, width }: InfoContainerProps) => (
|
||||
<TileInfo
|
||||
size="xs"
|
||||
direction="row"
|
||||
mr="5px"
|
||||
width={width}
|
||||
heading={heading}
|
||||
textAlignText="left"
|
||||
info={info}
|
||||
/>
|
||||
);
|
||||
|
||||
export const SiteCard: React.FC<CardSiteProps> = ({ site, tokenId }) => {
|
||||
const { name, owner, image, externalUrl } = site;
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<Card
|
||||
borderColor="#f3f3f36b !important"
|
||||
boxShadow="1px 10px 24px -2px #85848480"
|
||||
backgroundColor="#c5c5c50a"
|
||||
border="1px"
|
||||
borderRadius="10px"
|
||||
width="350px"
|
||||
height="350px"
|
||||
// TODO add token id param
|
||||
onClick={() => {
|
||||
navigate(`/detail?tokenId=${1}`);
|
||||
}}
|
||||
>
|
||||
<CardBody width="350px" height="350px" paddingTop="10px">
|
||||
<Heading size="md" textAlign="center" marginBottom="10px">
|
||||
{name}
|
||||
</Heading>
|
||||
<Link
|
||||
href={externalUrl}
|
||||
isExternal
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<Box height="180px">
|
||||
<ImagePreview
|
||||
backgroundColor="#161616"
|
||||
display="block"
|
||||
marginLeft="auto"
|
||||
marginRight="auto"
|
||||
image={image}
|
||||
objectFit="contain"
|
||||
width="100%"
|
||||
height="100%"
|
||||
borderRadius="20px"
|
||||
boxShadow="0px 12px 24px -5px #5a575761"
|
||||
/>
|
||||
</Box>
|
||||
</Link>
|
||||
<Stack mt="10px" spacing="3" overflowY="scroll">
|
||||
<InfoContainer heading="Owner" info={owner} width="auto" />
|
||||
{/* TODO add param */}
|
||||
<InfoContainer heading="Token ID" info="1" width="100px" />
|
||||
<InfoContainer
|
||||
heading="External url"
|
||||
width="100px"
|
||||
info={
|
||||
<Link
|
||||
href={externalUrl}
|
||||
isExternal
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<u>{externalUrl}</u>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
export * from './card-attributes';
|
||||
export * from './card-site';
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,36 @@ import {
|
|||
|
||||
type TileInfoProps = HeadingProps & {
|
||||
heading: string;
|
||||
info: string;
|
||||
width?: number;
|
||||
info: React.ReactNode;
|
||||
widthText?: number;
|
||||
textAlignText?: 'center' | 'left';
|
||||
direction?: 'column' | 'row';
|
||||
alignItems?: string;
|
||||
};
|
||||
|
||||
export const TileInfo = forwardRef<TileInfoProps, 'h2'>(
|
||||
({ heading, info, width = 250, ...headingProps }, ref) => (
|
||||
<Flex direction="column" alignItems="center">
|
||||
(
|
||||
{
|
||||
heading,
|
||||
info,
|
||||
widthText = 250,
|
||||
textAlignText = 'center',
|
||||
direction = 'column',
|
||||
alignItems = 'center',
|
||||
...headingProps
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<Flex direction={direction} alignItems={alignItems}>
|
||||
<Heading ref={ref} {...headingProps}>
|
||||
{heading}
|
||||
</Heading>
|
||||
<Text
|
||||
width={width}
|
||||
width={widthText}
|
||||
whiteSpace="nowrap"
|
||||
overflow="hidden"
|
||||
textOverflow="ellipsis"
|
||||
textAlign="center"
|
||||
textAlign={textAlignText}
|
||||
>
|
||||
{info}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export * from './mint-site';
|
||||
export * from './detail';
|
||||
|
||||
export * from './list';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
const listSites = [
|
||||
{
|
||||
tokenId: 1,
|
||||
name: 'Fleek Test App',
|
||||
owner: '0x1b5b3e8a7c245d0f2d2b2e29ba11c03ef086c06e',
|
||||
description:
|
||||
'Roronoa Zoro, also known as `Pirate Hunter` Zoro, is the combatant of the Straw Hat Pirates, one of their two swordsmen and one of the Senior Officers of the Straw Hat Grand Fleet. Formerly a bounty hunter, he is the second member of Luffy`s crew and the first to join it, doing so in the Romance Dawn Arc.',
|
||||
image:
|
||||
'https://i.seadn.io/gae/Z0t4BsFONk8ebFnTtog3ricAhEpW_ZPhyhxcjHpofCmslJUc5jQ0OjxUuJbU5-3XE0rJZFf6JVdPFZYqtqyg2ri4gAGRpfwkFcidpw4?auto=format&w=1000',
|
||||
externalUrl: 'https://onepiece.fandom.com/wiki/Roronoa_Zoro',
|
||||
ens: 'zoro.eth',
|
||||
commitHash: '6ea6ad16c46ae85faced7e50555ff7368422f57',
|
||||
githubRepo: 'https://github.com/fleekxyz/contracts',
|
||||
},
|
||||
{
|
||||
tokenId: 2,
|
||||
name: 'Fleek Test App',
|
||||
owner: '0x1b5b3e8a7c245d0f2d2b2e29ba11c03ef086c06e',
|
||||
description:
|
||||
' Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
|
||||
image: 'https://storageapi.fleek.co/fleek-team-bucket/site/fleek-logo.png',
|
||||
externalUrl: 'https://fleek.co',
|
||||
ens: 'fleek.eth',
|
||||
commitHash: '6ea6ad16c46ae85faced7e50555ff7368422f57',
|
||||
githubRepo: 'https://github.com/fleekxyz/contracts',
|
||||
},
|
||||
];
|
||||
|
||||
export const fetchMintedSites = async () => {
|
||||
//TODO get minted sites from api
|
||||
return new Promise((resolved) => {
|
||||
setTimeout(() => {
|
||||
resolved({
|
||||
listSites,
|
||||
});
|
||||
}, 2500);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -2,15 +2,16 @@ import React from 'react';
|
|||
import { Heading, Button } from '@chakra-ui/react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { ListSites } from './list';
|
||||
|
||||
export const Home = () => {
|
||||
return (
|
||||
<Flex flexDirection="column" alignItems="center">
|
||||
<Heading>Welcome to Sites as NFTs by Fleek</Heading>
|
||||
{/* TODO add list sites */}
|
||||
<Button as={Link} to="/mint-site" mt={10}>
|
||||
<Heading marginTop="80px">Welcome to Sites as NFTs by Fleek</Heading>
|
||||
<Button as={Link} to="/mint-site" mt="20px" mb="50px">
|
||||
Mint your site
|
||||
</Button>
|
||||
<ListSites />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
import React from 'react';
|
||||
import { Loading } from '@/components';
|
||||
import { fetchMintedSites } from '@/mocks';
|
||||
import { SiteNFTDetails } from '@/types';
|
||||
import { Grid, GridItem } from '@chakra-ui/react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { SiteCard } from '@/components';
|
||||
|
||||
export const ListSites = () => {
|
||||
const { data, isLoading } = useQuery<Array<SiteNFTDetails>, Error>(
|
||||
'fetchSites',
|
||||
fetchMintedSites
|
||||
);
|
||||
|
||||
if (isLoading) return <Loading />;
|
||||
return (
|
||||
<Grid
|
||||
templateColumns={{ base: 'repeat(4, 1fr)', md: 'repeat(5, 1fr)' }}
|
||||
gap={10}
|
||||
mt="40px"
|
||||
>
|
||||
{data &&
|
||||
data.listSites.map((site: SiteNFTDetails) => (
|
||||
<GridItem key={site.tokenId}>
|
||||
<SiteCard site={site} />
|
||||
</GridItem>
|
||||
))}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue