mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-02 03:00:32 -04:00
updated frontend to display nft gallery from 3box/opensea (#222)
* updated backend to read 3box collectiblesFavorite * removed unneccesary '?' * updated frontend to display nft gallery from 3box/opensea * prettier format * using theme colors/sizes * fixed nft price string
This commit is contained in:
@@ -10,7 +10,6 @@ If you're new to the MetaGame codebase, check out the following guides to learn
|
||||
|
||||
## Development
|
||||
|
||||
|
||||
### Bootstrap
|
||||
|
||||
Create your local .env file
|
||||
|
||||
@@ -58,7 +58,7 @@ CONTAINER ID IMAGE COMMAND CREATED
|
||||
38e3140ab632 postgres:12 "docker-entrypoint.s…" 51 minutes ago Up 2 minutes 0.0.0.0:5432->5432/tcp the-game_database_1
|
||||
```
|
||||
|
||||
You can also read the logs of the services by running `docker-compose logs -f $SERVICE` (replace $SERVICE by `backend` or `hasura`)
|
||||
You can also read the logs of the services by running `docker-compose logs -f $SERVICE` (replace \$SERVICE by `backend` or `hasura`)
|
||||
|
||||
```bash
|
||||
$ docker-compose logs -f backend
|
||||
@@ -83,11 +83,13 @@ Which populates it with testing data.
|
||||
If you want to run the NodeJS backend service out of docker to be able to debug with your IDE:
|
||||
|
||||
**Add environment variable** to tell hasura where to find the backend (may only work on MacOS)
|
||||
|
||||
```shell script
|
||||
echo 'BACKEND_HOST=host.docker.internal:4000' >> .env
|
||||
```
|
||||
|
||||
**Start the server**
|
||||
|
||||
```shell script
|
||||
yarn backend:dev
|
||||
```
|
||||
@@ -117,15 +119,15 @@ When creating a table, keep in mind a few things.
|
||||
|
||||
1. You should have an `id` for all table relationships and all datatypes should use snake_case.
|
||||
|
||||
- **Example 1:** Table Name: "hello" && Table ID: "hello_id" (as a UUID)
|
||||
- **Example 1:** Table Name: "hello" && Table ID: "hello_id" (as a UUID)
|
||||
|
||||
- **Example 2:** Table Name: "map" && Table ID: "map_id" (as a UUID)
|
||||
- **Example 2:** Table Name: "map" && Table ID: "map_id" (as a UUID)
|
||||
|
||||
2. You should be mapping objects as foreign keys to their respective UUID. For example if you made a new table that holds a player's messages, it would be something like:
|
||||
|
||||
- From: player_id
|
||||
|
||||
- To: Player.id
|
||||
- From: player_id
|
||||
|
||||
- To: Player.id
|
||||
|
||||
### Updating the GraphQL schemas
|
||||
|
||||
@@ -154,17 +156,16 @@ By default, only admins are allowed to change the permissions. In order to query
|
||||
|
||||
```json
|
||||
{
|
||||
"id": {
|
||||
"_eq":"X-Hasura-User-Id"
|
||||
}
|
||||
"id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. Furthermore, when selecting or updating data. You can add permissions for specific columns. You select which ones should be allowed via the provided checkboxes.
|
||||
|
||||
6. Finally, make sure that the changes for permissions are updated in `hasura/metadata/tables.yaml`.
|
||||
`Pre-update check`nsert and read data immediately. There are pre-generated functions that come with Hasura. For creating new entries. The following are example queries you could send immediately to `http://localhost:8080/v1/graphql`.
|
||||
|
||||
`Pre-update check`nsert and read data immediately. There are pre-generated functions that come with Hasura. For creating new entries. The following are example queries you could send immediately to `http://localhost:8080/v1/graphql`.
|
||||
|
||||
### Mutations and Querying
|
||||
|
||||
@@ -178,9 +179,7 @@ mutation insert {
|
||||
# Built in function with Hasura GraphQL
|
||||
insert_Item_one(
|
||||
# The respective columns
|
||||
object: {
|
||||
data: "..."
|
||||
}
|
||||
object: { data: "..." }
|
||||
) {
|
||||
# The keys to return on a successful insertion
|
||||
id
|
||||
@@ -195,20 +194,19 @@ As long as it fits the constraints of the table (ie: Foreign Key uniqueness, Dat
|
||||
|
||||
```graphql
|
||||
mutation update {
|
||||
# Built in Hasura function
|
||||
update_Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: {_eq: "[UUID]"}
|
||||
},
|
||||
# The columns you want to update
|
||||
_set: {
|
||||
data: "..."
|
||||
}) {
|
||||
# you can either supply `returning` or `affected_rows` for the response
|
||||
affected_rows
|
||||
# Built in Hasura function
|
||||
update_Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: { _eq: "[UUID]" }
|
||||
}
|
||||
# The columns you want to update
|
||||
_set: { data: "..." }
|
||||
) {
|
||||
# you can either supply `returning` or `affected_rows` for the response
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -231,15 +229,16 @@ mutation updateByKey {
|
||||
|
||||
```graphql
|
||||
mutation delete {
|
||||
delete_Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: {_eq: "[UUID]"}
|
||||
}) {
|
||||
# you can either supply `returning` or `affected_rows` for the response
|
||||
affected_rows
|
||||
delete_Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: { _eq: "[UUID]" }
|
||||
}
|
||||
) {
|
||||
# you can either supply `returning` or `affected_rows` for the response
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -247,11 +246,11 @@ You can also delete by `id` as well too.
|
||||
|
||||
```graphql
|
||||
mutation deleteByKey {
|
||||
delete_Item_by_pk(id: "[UUID]") {
|
||||
# Any columns that exist on the `Item` table
|
||||
id
|
||||
...data
|
||||
}
|
||||
delete_Item_by_pk(id: "[UUID]") {
|
||||
# Any columns that exist on the `Item` table
|
||||
id
|
||||
...data
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -259,27 +258,27 @@ mutation deleteByKey {
|
||||
|
||||
```graphql
|
||||
query get {
|
||||
Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: {_eq: "[UUID]"}
|
||||
},
|
||||
# Maximum number of results
|
||||
limit: 10,
|
||||
# Pagination
|
||||
offset: 0,
|
||||
# Sorting
|
||||
order_by: {
|
||||
# asc - ascending, desc - descending
|
||||
# Can also specify any column
|
||||
id: asc
|
||||
}
|
||||
) {
|
||||
# The keys to return on a successful query
|
||||
id
|
||||
data
|
||||
Item(
|
||||
where: {
|
||||
# Can also use _gt, _gte, _lt, _lte, _neq etc.
|
||||
# Can also specify any column
|
||||
id: { _eq: "[UUID]" }
|
||||
}
|
||||
# Maximum number of results
|
||||
limit: 10
|
||||
# Pagination
|
||||
offset: 0
|
||||
# Sorting
|
||||
order_by: {
|
||||
# asc - ascending, desc - descending
|
||||
# Can also specify any column
|
||||
id: asc
|
||||
}
|
||||
) {
|
||||
# The keys to return on a successful query
|
||||
id
|
||||
data
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -287,11 +286,11 @@ You can also query by `id` as well too.
|
||||
|
||||
```graphql
|
||||
query getByKey {
|
||||
Item_by_pk(id: "[UUID]") {
|
||||
# The keys to return on a successful query
|
||||
id,
|
||||
...data
|
||||
}
|
||||
Item_by_pk(id: "[UUID]") {
|
||||
# The keys to return on a successful query
|
||||
id
|
||||
...data
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ export {
|
||||
VStack,
|
||||
useTheme,
|
||||
useToast,
|
||||
Modal,
|
||||
ModalContent,
|
||||
ModalCloseButton,
|
||||
ModalOverlay,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/core';
|
||||
|
||||
export { theme as MetaTheme } from './theme';
|
||||
|
||||
@@ -14,6 +14,7 @@ interface MetaColors {
|
||||
gold: string;
|
||||
silver: string;
|
||||
bronze: string;
|
||||
purple80: string;
|
||||
}
|
||||
|
||||
interface MetaTheme {
|
||||
@@ -83,6 +84,7 @@ export const theme: Theme = {
|
||||
bronze: '#a97142',
|
||||
offwhite: '#F6F8F9',
|
||||
blue20: 'rgba(79, 105, 205, 0.2)',
|
||||
purple80: 'rgba(70, 20, 100, 0.8)',
|
||||
dark: '#1B0D2A',
|
||||
purpleBoxDark: '#261943',
|
||||
purpleBoxLight: '#392373',
|
||||
|
||||
@@ -29,7 +29,7 @@ export const PlayerBox: React.FC<PlayerBoxProps> = ({
|
||||
{title}
|
||||
</Text>
|
||||
<FaTimes
|
||||
color="#A5B9F6"
|
||||
color="blueLight"
|
||||
opacity="0.4"
|
||||
cursor="pointer"
|
||||
onClick={setRemoveBox}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const PlayerCollab: React.FC<Props> = ({ player }) => {
|
||||
timezone
|
||||
</Text>
|
||||
<HStack alignItems="baseline">
|
||||
<FaGlobe color="#A5B9F6" />
|
||||
<FaGlobe color="blueLight" />
|
||||
<Text fontSize="xl" mb="1">
|
||||
{player.box_profile?.location || '-'}
|
||||
</Text>
|
||||
@@ -49,7 +49,7 @@ export const PlayerCollab: React.FC<Props> = ({ player }) => {
|
||||
Availability
|
||||
</Text>
|
||||
<HStack alignItems="baseline">
|
||||
<FaClock color="#A5B9F6" />
|
||||
<FaClock color="blueLight" />
|
||||
<Text fontSize="xl" mb="1">
|
||||
{player.availability_hours || '0'}h/week
|
||||
</Text>
|
||||
|
||||
@@ -1,63 +1,138 @@
|
||||
import { Box, Flex, HStack, Text } from '@metafam/ds';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Heading,
|
||||
HStack,
|
||||
Modal,
|
||||
ModalContent,
|
||||
ModalOverlay,
|
||||
SimpleGrid,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@metafam/ds';
|
||||
import { MetaLink as Link } from 'components/Link';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import {
|
||||
Collectible,
|
||||
useOpenSeaCollectibles,
|
||||
} from 'lib/useOpenSeaCollectibles';
|
||||
import React from 'react';
|
||||
import { FaTimes } from 'react-icons/fa';
|
||||
|
||||
import nft1Image from '../../../assets/fake/nft1.png';
|
||||
import nft2Image from '../../../assets/fake/nft2.png';
|
||||
import { PlayerBox } from './PlayerBoxe';
|
||||
|
||||
// TODO Fake data
|
||||
type Props = { setRemoveBox: () => void };
|
||||
export const PlayerGallery: React.FC<Props> = ({ setRemoveBox }) => {
|
||||
const [show, setShow] = React.useState(false);
|
||||
const fakeEthPrice = 500;
|
||||
const fakeData = [
|
||||
{ title: 'CryptoMon Cards - Aave', priceInEth: 0.025, img: nft1Image },
|
||||
{ title: 'metagamer', priceInEth: 6.942, img: nft2Image },
|
||||
];
|
||||
type Props = { player: PlayerFragmentFragment; setRemoveBox: () => void };
|
||||
|
||||
const GalleryItem: React.FC<{ nft: Collectible; noMargin?: boolean }> = ({
|
||||
nft,
|
||||
noMargin = false,
|
||||
}) => (
|
||||
<Link
|
||||
href={nft.openseaLink}
|
||||
isExternal
|
||||
mb={noMargin ? undefined : 6}
|
||||
minW={0}
|
||||
display="flex"
|
||||
>
|
||||
<HStack spacing={6}>
|
||||
<Flex width="7.5rem" height="7.5rem">
|
||||
<Box
|
||||
bgImage={`url(${nft.imageUrl})`}
|
||||
backgroundSize="contain"
|
||||
backgroundRepeat="no-repeat"
|
||||
backgroundPosition="center"
|
||||
w="7.5rem"
|
||||
h="7.5rem"
|
||||
m="auto"
|
||||
/>
|
||||
</Flex>
|
||||
<Flex direction="column">
|
||||
<Heading
|
||||
fontSize="xs"
|
||||
mt={3}
|
||||
mb={3}
|
||||
textTransform="uppercase"
|
||||
display="inline-block"
|
||||
style={{ wordWrap: 'break-word', wordBreak: 'break-all' }}
|
||||
>
|
||||
{nft.title}
|
||||
</Heading>
|
||||
<Text fontSize="sm">{nft.priceString}</Text>
|
||||
</Flex>
|
||||
</HStack>
|
||||
</Link>
|
||||
);
|
||||
|
||||
export const PlayerGallery: React.FC<Props> = ({ player, setRemoveBox }) => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const { favorites, data, loading } = useOpenSeaCollectibles({ player });
|
||||
return (
|
||||
<PlayerBox title="Gallery" setRemoveBox={setRemoveBox}>
|
||||
{(fakeData || []).slice(0, show ? 999 : 3).map((nft) => (
|
||||
<HStack alignItems="end" mb={6}>
|
||||
<Flex width="126px" height="126px" mr={6}>
|
||||
<Box
|
||||
bgImage={`url(${nft.img})`}
|
||||
backgroundSize="contain"
|
||||
backgroundRepeat="no-repeat"
|
||||
backgroundPosition="center"
|
||||
width="124px"
|
||||
height="124px"
|
||||
m="auto"
|
||||
/>
|
||||
</Flex>
|
||||
<Box>
|
||||
<Text
|
||||
fontSize="xs"
|
||||
fontFamily="heading"
|
||||
mt={3}
|
||||
mb={3}
|
||||
casing="uppercase"
|
||||
>
|
||||
{nft.title}
|
||||
</Text>
|
||||
<Text fontSize="sm" mb="1">
|
||||
{nft.priceInEth}Ξ ($
|
||||
{parseFloat(`${nft.priceInEth * fakeEthPrice}`).toFixed(2)})
|
||||
</Text>
|
||||
</Box>
|
||||
</HStack>
|
||||
))}
|
||||
{(fakeData || []).length > 3 && (
|
||||
{!loading &&
|
||||
favorites?.map((nft) => <GalleryItem nft={nft} key={nft.tokenId} />)}
|
||||
{!loading && data?.length > 3 && (
|
||||
<Text
|
||||
as="span"
|
||||
fontFamily="body"
|
||||
fontSize="xs"
|
||||
color="cyanText"
|
||||
cursor="pointer"
|
||||
onClick={() => setShow(!show)}
|
||||
onClick={onOpen}
|
||||
>
|
||||
View {show ? 'less' : 'all'}
|
||||
View all
|
||||
</Text>
|
||||
)}
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
isCentered
|
||||
scrollBehavior="inside"
|
||||
>
|
||||
<ModalOverlay css={{ backdropFilter: 'blur(8px)' }}>
|
||||
<ModalContent maxW="6xl" bg="none">
|
||||
<Box bg="purple80" borderTopRadius="lg" p={4} w="100%">
|
||||
<HStack>
|
||||
<Text
|
||||
fontFamily="mono"
|
||||
fontSize="sm"
|
||||
fontWeight="bold"
|
||||
color="blueLight"
|
||||
as="div"
|
||||
mr="auto"
|
||||
>
|
||||
Gallery
|
||||
</Text>
|
||||
<FaTimes
|
||||
color="blueLight"
|
||||
opacity="0.4"
|
||||
cursor="pointer"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</HStack>
|
||||
</Box>
|
||||
<Box
|
||||
overflowY="scroll"
|
||||
overflowX="hidden"
|
||||
maxH="80vh"
|
||||
borderBottomRadius="lg"
|
||||
w="100%"
|
||||
>
|
||||
<SimpleGrid
|
||||
columns={{ base: 1, md: 2, lg: 3 }}
|
||||
gap={6}
|
||||
padding={6}
|
||||
boxShadow="md"
|
||||
bg="whiteAlpha.200"
|
||||
css={{ backdropFilter: 'blur(8px)' }}
|
||||
>
|
||||
{data?.map((nft) => (
|
||||
<GalleryItem nft={nft} key={nft.tokenId} noMargin />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
</ModalContent>
|
||||
</ModalOverlay>
|
||||
</Modal>
|
||||
</PlayerBox>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,4 +3,5 @@ export const CONFIG = {
|
||||
process.env.NEXT_PUBLIC_GRAPHQL_URL || 'http://localhost:8080/v1/graphql',
|
||||
infuraId:
|
||||
process.env.NEXT_PUBLIC_INFURA_ID || '781d8466252d47508e177b8637b1c2fd',
|
||||
openseaApiKey: process.env.NEXT_OPENSEA_API_KEY || undefined,
|
||||
};
|
||||
|
||||
@@ -38,6 +38,10 @@ export const PlayerFragment = gql`
|
||||
job
|
||||
location
|
||||
name
|
||||
collectiblesFavorites {
|
||||
tokenId
|
||||
address
|
||||
}
|
||||
}
|
||||
daohausMemberships {
|
||||
id
|
||||
|
||||
139
packages/web/lib/useOpenSeaCollectibles.ts
Normal file
139
packages/web/lib/useOpenSeaCollectibles.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
import { CONFIG } from 'config';
|
||||
import { utils } from 'ethers';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import { OpenSeaAPI } from 'opensea-js';
|
||||
import {
|
||||
AssetEvent,
|
||||
OpenSeaAsset,
|
||||
OpenSeaAssetQuery,
|
||||
} from 'opensea-js/lib/types';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
const opensea = new OpenSeaAPI({ apiKey: CONFIG.openseaApiKey });
|
||||
|
||||
type OpenSeaCollectiblesOpts = {
|
||||
player: PlayerFragmentFragment;
|
||||
};
|
||||
|
||||
export type Collectible = {
|
||||
address: string;
|
||||
tokenId: string;
|
||||
title: string;
|
||||
imageUrl: string;
|
||||
openseaLink: string;
|
||||
priceString: string;
|
||||
};
|
||||
|
||||
export const useOpenSeaCollectibles = ({
|
||||
player,
|
||||
}: OpenSeaCollectiblesOpts): {
|
||||
favorites: Array<Collectible>;
|
||||
data: Array<Collectible>;
|
||||
loading: boolean;
|
||||
} => {
|
||||
const [favorites, setFavorites] = useState<Array<Collectible>>([]);
|
||||
const [data, setData] = useState<Array<Collectible>>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const owner = player.ethereum_address;
|
||||
const collectiblesFavorites = useMemo(
|
||||
() =>
|
||||
player && player.box_profile && player.box_profile.collectiblesFavorites
|
||||
? player.box_profile.collectiblesFavorites
|
||||
: [],
|
||||
[player],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
setLoading(true);
|
||||
if (collectiblesFavorites.length > 0 && owner) {
|
||||
const favoritesQuery = {
|
||||
owner,
|
||||
token_ids: collectiblesFavorites.map(({ tokenId }) => tokenId || ''),
|
||||
};
|
||||
const [favoritesData, allData] = await Promise.all([
|
||||
fetchOpenSeaData(favoritesQuery),
|
||||
fetchAllOpenSeaData(owner),
|
||||
]);
|
||||
setFavorites(favoritesData);
|
||||
setData(allData);
|
||||
} else if (owner) {
|
||||
const allData = await fetchAllOpenSeaData(owner);
|
||||
setData(allData);
|
||||
setFavorites(allData.slice(0, 3));
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
load();
|
||||
}, [collectiblesFavorites, owner]);
|
||||
|
||||
return { favorites, data, loading };
|
||||
};
|
||||
|
||||
const fetchAllOpenSeaData = async (
|
||||
owner: string,
|
||||
): Promise<Array<Collectible>> => {
|
||||
let offset = 0;
|
||||
let data: Array<Collectible> = [];
|
||||
let lastData: Array<Collectible> = [];
|
||||
do {
|
||||
const query = { owner, offset, limit: 50 };
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
lastData = await fetchOpenSeaData(query);
|
||||
data = data.concat(lastData);
|
||||
offset += 50;
|
||||
} while (lastData.length > 0);
|
||||
return data;
|
||||
};
|
||||
|
||||
const fetchOpenSeaData = async (
|
||||
query: OpenSeaAssetQuery,
|
||||
): Promise<Array<Collectible>> => {
|
||||
const response = await opensea.getAssets(query);
|
||||
return parseAssets(response.assets);
|
||||
};
|
||||
|
||||
const parseAssets = async (
|
||||
assets: Array<OpenSeaAsset>,
|
||||
): Promise<Array<Collectible>> => {
|
||||
return assets
|
||||
.map(
|
||||
(asset) =>
|
||||
({
|
||||
address: asset.assetContract.address,
|
||||
tokenId: asset.tokenId,
|
||||
title: asset.name,
|
||||
imageUrl: asset.imageUrl,
|
||||
openseaLink: asset.openseaLink,
|
||||
priceString: getPriceString(asset.lastSale),
|
||||
} as Collectible),
|
||||
)
|
||||
.filter(
|
||||
(collectible: Collectible) =>
|
||||
!!collectible.title && !!collectible.imageUrl,
|
||||
);
|
||||
};
|
||||
|
||||
const ETH_ADDRESSES = [
|
||||
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // wETH
|
||||
'0x0000000000000000000000000000000000000000', // ETH
|
||||
];
|
||||
|
||||
const getPriceString = (event: AssetEvent | null): string => {
|
||||
if (event && event.paymentToken) {
|
||||
const {
|
||||
address,
|
||||
symbol: tokenSymbol,
|
||||
decimals,
|
||||
usdPrice,
|
||||
} = event.paymentToken;
|
||||
|
||||
const symbol = ETH_ADDRESSES.indexOf(address) === -1 ? tokenSymbol : 'Ξ';
|
||||
const price = Number(utils.formatUnits(event.totalPrice, decimals));
|
||||
const priceInUSD = usdPrice ? price * Number(usdPrice) : 0;
|
||||
return `${price.toFixed(2)}${symbol}${
|
||||
priceInUSD ? ` ($${priceInUSD.toFixed(2)})` : ''
|
||||
}`;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
@@ -22,6 +22,7 @@
|
||||
"next": "latest",
|
||||
"next-images": "^1.4.1",
|
||||
"next-urql": "2.0.0",
|
||||
"opensea-js": "^1.1.10",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-icons": "^3.11.0",
|
||||
|
||||
@@ -34,7 +34,7 @@ const PlayerPage: React.FC<Props> = ({ player }) => {
|
||||
const [fakeData, setFakeData] = React.useState([
|
||||
[BOX_TYPE.PLAYER_SKILLS, BOX_TYPE.PLAYER_CONTACT_BUTTONS],
|
||||
[BOX_TYPE.PLAYER_MEMBERSHIPS],
|
||||
[],
|
||||
[BOX_TYPE.PLAYER_GALLERY],
|
||||
]);
|
||||
|
||||
if (!player) {
|
||||
@@ -74,7 +74,12 @@ const PlayerPage: React.FC<Props> = ({ player }) => {
|
||||
/>
|
||||
);
|
||||
case BOX_TYPE.PLAYER_GALLERY:
|
||||
return <PlayerGallery setRemoveBox={() => removeBox(column, name)} />;
|
||||
return (
|
||||
<PlayerGallery
|
||||
player={player}
|
||||
setRemoveBox={() => removeBox(column, name)}
|
||||
/>
|
||||
);
|
||||
case BOX_TYPE.PLAYER_MEMBERSHIPS:
|
||||
return (
|
||||
<PlayerMemberships
|
||||
@@ -155,7 +160,9 @@ const PlayerPage: React.FC<Props> = ({ player }) => {
|
||||
ml={[0, null, null, 4]}
|
||||
>
|
||||
{(fakeData || [[], [], []])[2].map((name) => (
|
||||
<Box mb="6">{getBox(2, name)}</Box>
|
||||
<Box mb="6" key={name}>
|
||||
{getBox(2, name)}
|
||||
</Box>
|
||||
))}
|
||||
<Box mb="6">
|
||||
<PlayerAddBox
|
||||
|
||||
Reference in New Issue
Block a user