mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-01-14 08:58:02 -05:00
161 lines
4.0 KiB
TypeScript
161 lines
4.0 KiB
TypeScript
import {
|
|
Box,
|
|
Flex,
|
|
Heading,
|
|
LoadingState,
|
|
Modal,
|
|
ModalBody,
|
|
ModalCloseButton,
|
|
ModalContent,
|
|
ModalHeader,
|
|
ModalOverlay,
|
|
SimpleGrid,
|
|
Text,
|
|
Tooltip,
|
|
useDisclosure,
|
|
ViewAllButton,
|
|
} from '@metafam/ds';
|
|
|
|
import { ProfileSection } from '#components/Section/ProfileSection';
|
|
import { Player } from '#graphql/autogen/hasura-sdk';
|
|
import { useNFTCollectibles } from '#lib/hooks/alchemy';
|
|
import { BoxTypes } from '#utils/boxTypes';
|
|
|
|
const GalleryItem: React.FC<{ nft: any }> = ({ nft }) => (
|
|
<Box display="flex">
|
|
<Box
|
|
bgImage={`url(${nft?.image?.cachedUrl})`}
|
|
backgroundSize="contain"
|
|
backgroundRepeat="no-repeat"
|
|
backgroundPosition="center"
|
|
minW={28}
|
|
minH={28}
|
|
/>
|
|
<Tooltip label={nft?.title} hasArrow>
|
|
<Flex
|
|
display="inline-grid"
|
|
direction="column"
|
|
ml={3}
|
|
h="full"
|
|
alignContent="center"
|
|
>
|
|
<Heading
|
|
fontSize="xs"
|
|
ml="1em"
|
|
sx={{
|
|
textIndent: '-1em',
|
|
wordBreak: 'break-word',
|
|
fontVariant: 'small-caps',
|
|
}}
|
|
>
|
|
{nft?.collection?.name || nft?.contract?.name || 'Unknown'}
|
|
</Heading>
|
|
<Text fontSize="sm">
|
|
Floor Price: {nft?.contract?.openSeaMetadata?.floorPrice || '0'} ETH
|
|
</Text>
|
|
</Flex>
|
|
</Tooltip>
|
|
</Box>
|
|
);
|
|
|
|
type GalleryModalProps = {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
nfts: Array<any>;
|
|
};
|
|
|
|
const GalleryModal: React.FC<GalleryModalProps> = ({
|
|
isOpen,
|
|
onClose,
|
|
nfts,
|
|
}) => (
|
|
<Modal {...{ isOpen, onClose }}>
|
|
<ModalOverlay>
|
|
<ModalContent>
|
|
<ModalHeader>NFT Gallery</ModalHeader>
|
|
<ModalCloseButton />
|
|
<ModalBody>
|
|
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} gap={4} p={4}>
|
|
{nfts?.map((nft) => (
|
|
<GalleryItem {...{ nft }} key={`${nft.tokenId}-${nft.address}`} />
|
|
))}
|
|
</SimpleGrid>
|
|
</ModalBody>
|
|
</ModalContent>
|
|
</ModalOverlay>
|
|
</Modal>
|
|
);
|
|
|
|
type Props = {
|
|
player: Player;
|
|
isOwnProfile?: boolean;
|
|
editing?: boolean;
|
|
};
|
|
|
|
export const PlayerGallery: React.FC<Props> = ({
|
|
player,
|
|
isOwnProfile,
|
|
editing,
|
|
}) => {
|
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
const { loading, error, data: nfts } = useNFTCollectibles({ player });
|
|
|
|
const processAllNfts = () => {
|
|
let nftData: any = [];
|
|
if (!nfts[0]) return [];
|
|
if (nfts[0]?.maticNfts?.ownedNfts)
|
|
nftData = [...nftData, ...nfts[0].maticNfts.ownedNfts];
|
|
if (nfts[0]?.mainnetNfts?.ownedNfts)
|
|
nftData = [...nftData, ...nfts[0].mainnetNfts.ownedNfts];
|
|
if (nfts[0]?.optimismNfts?.ownedNfts)
|
|
nftData = [...nftData, ...nfts[0].optimismNfts.ownedNfts];
|
|
return nftData;
|
|
};
|
|
const allNfts = processAllNfts().filter(
|
|
(nft: any) => nft.tokenType !== 'ERC1155',
|
|
);
|
|
|
|
return (
|
|
<ProfileSection
|
|
title="NFT Gallery"
|
|
{...{ isOwnProfile, editing }}
|
|
type={BoxTypes.PLAYER_NFT_GALLERY}
|
|
>
|
|
{(() => {
|
|
if (loading) {
|
|
return <LoadingState pb={6} />;
|
|
}
|
|
if (error) {
|
|
return (
|
|
<Text textAlign="center" fontStyle="italic" mb={4} color="red">
|
|
Error: {error}
|
|
</Text>
|
|
);
|
|
}
|
|
if (nfts.length === 0) {
|
|
return (
|
|
<Text textAlign="center" fontStyle="italic" mb={4}>
|
|
No NFTs found for {isOwnProfile ? 'you' : 'this player'}.
|
|
</Text>
|
|
);
|
|
}
|
|
return (
|
|
<>
|
|
<SimpleGrid columns={1} gap={4} px={2}>
|
|
{allNfts?.slice(0, 4).map((nft: any) => (
|
|
<GalleryItem {...{ nft }} key={nft.tokenId} />
|
|
))}
|
|
</SimpleGrid>
|
|
{allNfts?.length > 3 && (
|
|
<Box textAlign="end">
|
|
<GalleryModal {...{ isOpen, onClose, nfts: allNfts }} />
|
|
<ViewAllButton onClick={onOpen} size={allNfts.length} />
|
|
</Box>
|
|
)}
|
|
</>
|
|
);
|
|
})()}
|
|
</ProfileSection>
|
|
);
|
|
};
|