diff --git a/CHANGELOG.md b/CHANGELOG.md index 637f1f9aa..0a040d650 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug fixes +- [#735](https://github.com/alleslabs/celatone-frontend/pull/735) Fix nfts related bugs - [#734](https://github.com/alleslabs/celatone-frontend/pull/734) Fix search spamming by using debounce - [#733](https://github.com/alleslabs/celatone-frontend/pull/733) Fix contract list nullable fields - [#732](https://github.com/alleslabs/celatone-frontend/pull/732) Fix custom tab incorrect variant and recent modules text diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index e8b08ff80..faf280141 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -118,7 +118,6 @@ export enum CELATONE_QUERY_KEYS { NFT_TRANSACTIONS_COUNT = "CELATONE_QUERY_NFT_TRANSACTIONS_COUNT", NFT_MUTATE_EVENTS = "CELATONE_QUERY_NFT_MUTATE_EVENTS", NFT_MUTATE_EVENTS_COUNT = "CELATONE_QUERY_NFT_MUTATE_EVENTS_COUNT", - NFTS_BY_ACCOUNT = "CELATONE_QUERY_NFTS_BY_ACCOUNT", NFTS_COUNT_BY_ACCOUNT = "CELATONE_QUERY_NFTS_COUNT_BY_ACCOUNT", NFTS_BY_ACCOUNT_BY_COLLECTION = "CELATONE_QUERY_NFTS_BY_ACCOUNT_BY_COLLECTION", } diff --git a/src/lib/components/action-msg/SingleMsg.tsx b/src/lib/components/action-msg/SingleMsg.tsx index 5518fab98..9841fc69a 100644 --- a/src/lib/components/action-msg/SingleMsg.tsx +++ b/src/lib/components/action-msg/SingleMsg.tsx @@ -54,6 +54,8 @@ export const SingleMsg = ({ @@ -62,13 +64,13 @@ export const SingleMsg = ({ ))} {/* Tag left over */} {tags && length && length - tags.length > 0 && ( - + +{length - tags.length} )} {/* Length */} {!tags && length && ( - + {length} )} diff --git a/src/lib/components/button/InstantiateButton.tsx b/src/lib/components/button/InstantiateButton.tsx index bcba9ccbf..80a835541 100644 --- a/src/lib/components/button/InstantiateButton.tsx +++ b/src/lib/components/button/InstantiateButton.tsx @@ -23,10 +23,11 @@ const getInstantiateButtonProps = ( variant: string; icon: JSX.Element | undefined; } => { + const buttonDisabledState = "outline-gray"; if (isUnknown) { return { tooltipLabel: "", - variant: "outline-gray", + variant: buttonDisabledState, icon: undefined, }; } @@ -35,20 +36,15 @@ const getInstantiateButtonProps = ( tooltipLabel: isWalletConnected ? "You can instantiate without opening proposal" : "You need to connect wallet to instantiate contract", - variant: "outline-primary", - icon: ( - - ), + variant: isWalletConnected ? "outline-primary" : buttonDisabledState, + icon: , }; } return { tooltipLabel: isWalletConnected ? "Instantiate through proposal only (Coming Soon)" : "You need to connect wallet to open instantiate proposal", - variant: "outline-gray", + variant: buttonDisabledState, icon: , }; }; diff --git a/src/lib/components/icon/CustomIcon.tsx b/src/lib/components/icon/CustomIcon.tsx index 25350fcbb..0e204cc11 100644 --- a/src/lib/components/icon/CustomIcon.tsx +++ b/src/lib/components/icon/CustomIcon.tsx @@ -1539,7 +1539,7 @@ export const ICONS = { /> ), - viewBox: viewboxDefault, + viewBox: "0 0 16 14", }, }; diff --git a/src/lib/components/json-schema/EditSchemaButtons.tsx b/src/lib/components/json-schema/EditSchemaButtons.tsx index 4756c8cc5..c33837a30 100644 --- a/src/lib/components/json-schema/EditSchemaButtons.tsx +++ b/src/lib/components/json-schema/EditSchemaButtons.tsx @@ -26,10 +26,9 @@ export const EditSchemaButtons = ({ } aria-label="reattach schema" /> diff --git a/src/lib/components/nft/NftCard.tsx b/src/lib/components/nft/NftCard.tsx index 3d4421da9..bbcada94c 100644 --- a/src/lib/components/nft/NftCard.tsx +++ b/src/lib/components/nft/NftCard.tsx @@ -39,8 +39,11 @@ export const NftCard = ({ width="100%" height="100%" objectFit="cover" + backgroundPosition="center" borderRadius="8px" - src={metadata?.image ? metadata.image : NFT_IMAGE_PLACEHOLDER} + src={metadata?.image} + fallbackSrc={NFT_IMAGE_PLACEHOLDER} + fallbackStrategy="beforeLoadOrError" /> diff --git a/src/lib/components/table/modules/ModulePathLink.tsx b/src/lib/components/table/modules/ModulePathLink.tsx index 7b226c704..4e7866877 100644 --- a/src/lib/components/table/modules/ModulePathLink.tsx +++ b/src/lib/components/table/modules/ModulePathLink.tsx @@ -22,7 +22,7 @@ export const ModulePathLink = ({ className="copier-wrapper" display={{ base: "inline-flex", md: "flex" }} align="center" - h="24px" + h={{ base: "auto", md: "24px" }} > - {oldValue} + + {oldValue} + - {newValue} + + {newValue} + } diff --git a/src/lib/components/table/mutate-events/MutateEventsTableRow.tsx b/src/lib/components/table/mutate-events/MutateEventsTableRow.tsx index c409c8fd4..e594b9183 100644 --- a/src/lib/components/table/mutate-events/MutateEventsTableRow.tsx +++ b/src/lib/components/table/mutate-events/MutateEventsTableRow.tsx @@ -28,11 +28,19 @@ export const MutateEventsTableRow = ({ {mutatedFieldName} - {oldValue} + + + {oldValue} + + - {newValue} + + + {newValue} + + {formatUTC(timestamp)} diff --git a/src/lib/layout/mobile/NavDrawer.tsx b/src/lib/layout/mobile/NavDrawer.tsx index 5b3995d40..711ac3782 100644 --- a/src/lib/layout/mobile/NavDrawer.tsx +++ b/src/lib/layout/mobile/NavDrawer.tsx @@ -18,6 +18,7 @@ import { NetworkMenu } from "../NetworkMenu"; import { AmpEvent, track } from "lib/amplitude"; import { useMoveConfig, + useNftConfig, usePublicProjectConfig, useWasmConfig, } from "lib/app-provider"; @@ -33,6 +34,7 @@ export const NavDrawer = () => { const { getSavedPublicProjects } = usePublicProjectStore(); const wasm = useWasmConfig({ shouldRedirect: false }); const move = useMoveConfig({ shouldRedirect: false }); + const nft = useNftConfig({ shouldRedirect: false }); const publicProject = usePublicProjectConfig({ shouldRedirect: false }); const mobileMenu: MenuInfo[] = [ @@ -84,6 +86,15 @@ export const NavDrawer = () => { }, ] : []), + ...(nft.enabled + ? [ + { + name: "NFT Collections", + slug: "/nft-collections", + icon: "group" as IconKeys, + }, + ] + : []), ], }, ]; diff --git a/src/lib/pages/account-details/components/nfts/FilterItem.tsx b/src/lib/pages/account-details/components/nfts/FilterItem.tsx index 875e2d904..cc51f6524 100644 --- a/src/lib/pages/account-details/components/nfts/FilterItem.tsx +++ b/src/lib/pages/account-details/components/nfts/FilterItem.tsx @@ -1,7 +1,8 @@ -import { Badge, Box, Flex, Image, Text } from "@chakra-ui/react"; +import { Badge, Flex, Image, Text } from "@chakra-ui/react"; import { AmpEvent, track } from "lib/amplitude"; import { CustomIcon } from "lib/components/icon"; +import { NFT_IMAGE_PLACEHOLDER } from "lib/data"; import { useMetadata } from "lib/services/nft"; interface FilterItemProps { @@ -10,6 +11,7 @@ interface FilterItemProps { onClick: () => void; uri?: string; isActive?: boolean; + isDefault?: boolean; } export const FilterItem = ({ @@ -18,6 +20,7 @@ export const FilterItem = ({ onClick, uri, isActive, + isDefault = false, }: FilterItemProps) => { const { data: metadata } = useMetadata(uri ?? ""); @@ -39,17 +42,25 @@ export const FilterItem = ({ justify="space-between" > - {metadata && uri ? ( + {isDefault ? ( + + + + ) : ( - ) : ( - - - )} {collectionName} diff --git a/src/lib/pages/account-details/components/nfts/NftsByCollection.tsx b/src/lib/pages/account-details/components/nfts/NftsByCollection.tsx index 5a880f7b8..b63a7b4f5 100644 --- a/src/lib/pages/account-details/components/nfts/NftsByCollection.tsx +++ b/src/lib/pages/account-details/components/nfts/NftsByCollection.tsx @@ -1,24 +1,22 @@ import { Stack } from "@chakra-ui/react"; import { useEffect, useState } from "react"; -import { useAccountNfts } from "../../data"; import InputWithIcon from "lib/components/InputWithIcon"; import { NftList } from "lib/components/nft"; import { Pagination } from "lib/components/pagination"; import { usePaginator } from "lib/components/pagination/usePaginator"; import { EmptyState } from "lib/components/state"; import { useDebounce } from "lib/hooks"; +import { useNftsByAccountByCollection } from "lib/services/nft"; import type { HexAddr, HexAddr32 } from "lib/types"; interface NftsByCollectionProps { accountAddress: HexAddr; - totalData: number; collectionAddress?: HexAddr32; } export const NftsByCollection = ({ accountAddress, - totalData, collectionAddress, }: NftsByCollectionProps) => { const [searchKeyword, setSearchKeyword] = useState(""); @@ -26,25 +24,28 @@ export const NftsByCollection = ({ const { pagesQuantity, + setTotalData, currentPage, setCurrentPage, pageSize, setPageSize, offset, } = usePaginator({ - total: totalData, initialState: { pageSize: 10, currentPage: 1, isDisabled: false, }, }); - const { data: nfts, isLoading } = useAccountNfts( + const { data, isLoading } = useNftsByAccountByCollection( accountAddress, pageSize, offset, debouncedSearch, - collectionAddress + collectionAddress, + { + onSuccess: ({ total }) => setTotalData(total), + } ); useEffect(() => { @@ -64,7 +65,7 @@ export const NftsByCollection = ({ amptrackSection="nft-account-detail-tokenid-search" /> - {totalData > 10 && ( + {data && data.total > 10 && ( { diff --git a/src/lib/pages/account-details/components/nfts/NftsOverview.tsx b/src/lib/pages/account-details/components/nfts/NftsOverview.tsx index a30e27e51..f1d5d4911 100644 --- a/src/lib/pages/account-details/components/nfts/NftsOverview.tsx +++ b/src/lib/pages/account-details/components/nfts/NftsOverview.tsx @@ -4,7 +4,7 @@ import { useMobile } from "lib/app-provider"; import { NftList } from "lib/components/nft"; import { EmptyState } from "lib/components/state"; import { MobileTitle, TableTitle, ViewMore } from "lib/components/table"; -import { useNftsByAccount } from "lib/services/nft"; +import { useNftsByAccountByCollection } from "lib/services/nft"; import type { HexAddr } from "lib/types"; interface NftsOverviewProps { @@ -19,7 +19,7 @@ export const NftsOverview = ({ onViewMore, }: NftsOverviewProps) => { const isMobile = useMobile(); - const { data: nfts, isFetching } = useNftsByAccount(userAddress, 5, 0); + const { data, isFetching } = useNftsByAccountByCollection(userAddress, 5, 0); return ( @@ -29,7 +29,7 @@ export const NftsOverview = ({ <> { onClick={() => handleOnClick(undefined)} isActive={selectedCollection === undefined} count={totalData} + isDefault /> {collections.map((item) => ( { diff --git a/src/lib/pages/account-details/data.ts b/src/lib/pages/account-details/data.ts index 7f621b7f6..351f239e4 100644 --- a/src/lib/pages/account-details/data.ts +++ b/src/lib/pages/account-details/data.ts @@ -6,13 +6,10 @@ import { useAdminContractsByAddress, useInstantiatedContractsByAddress, } from "lib/services/contractService"; -import { useAccountNftsByCollection, useNftsByAccount } from "lib/services/nft"; import type { BechAddr, CodeInfo, ContractInfo, - HexAddr, - HexAddr32, Nullish, Option, } from "lib/types"; @@ -154,27 +151,3 @@ export const useAccountCodes = ( isLoading, }; }; - -export const useAccountNfts = ( - accountAddress: HexAddr, - pageSize: number, - offset: number, - search: string, - collectionAddress?: HexAddr32 -) => { - const allNftsResult = useNftsByAccount( - accountAddress, - pageSize, - offset, - search - ); - const collectionNftsResult = useAccountNftsByCollection( - accountAddress, - pageSize, - offset, - search, - collectionAddress - ); - - return collectionAddress ? collectionNftsResult : allNftsResult; -}; diff --git a/src/lib/pages/module-details/components/ModuleTop.tsx b/src/lib/pages/module-details/components/ModuleTop.tsx index 305fafb24..bbe8d17a0 100644 --- a/src/lib/pages/module-details/components/ModuleTop.tsx +++ b/src/lib/pages/module-details/components/ModuleTop.tsx @@ -157,6 +157,7 @@ export const ModuleTop = ({ moduleData, isVerified }: ModuleTopProps) => { textFormat="normal" maxWidth="fit-content" type="user_address" + fixedHeight={false} /> diff --git a/src/lib/pages/nft-collection-details/components/CollectionSuppliesOverview.tsx b/src/lib/pages/nft-collection-details/components/CollectionSuppliesOverview.tsx index 7d6a2ed00..c2b461150 100644 --- a/src/lib/pages/nft-collection-details/components/CollectionSuppliesOverview.tsx +++ b/src/lib/pages/nft-collection-details/components/CollectionSuppliesOverview.tsx @@ -21,7 +21,7 @@ interface CollectionSuppliesOverviewProps { onViewMore: () => void; } -export const CollectionSuppliesOverview = ({ +export const CollectionSuppliesOverviewBody = ({ totalCount, nfts, isLoading, @@ -41,16 +41,9 @@ export const CollectionSuppliesOverview = ({ return ( ); - return ( - - - - NFTs in this collection - - {totalCount} - - + <> + {nftsInfo.map((nft) => ( @@ -58,6 +51,28 @@ export const CollectionSuppliesOverview = ({ ))} {totalCount > displayedNftCount && } - + ); }; + +export const CollectionSuppliesOverview = ({ + totalCount, + nfts, + isLoading, + onViewMore, +}: CollectionSuppliesOverviewProps) => ( + + + + NFTs in this collection + + {totalCount} + + + +); diff --git a/src/lib/pages/nft-collection-details/data.ts b/src/lib/pages/nft-collection-details/data.ts index 4a3d20e45..7284c1c4c 100644 --- a/src/lib/pages/nft-collection-details/data.ts +++ b/src/lib/pages/nft-collection-details/data.ts @@ -59,7 +59,7 @@ export const useCollectionInfos = ( ? Number(supplyData.max_supply) : undefined, }, - royalty: Number(royaltyData?.royalty ?? 0), + royalty: Number(royaltyData?.royalty ?? 0) * 100, }, isLoading: isFetching, }; diff --git a/src/lib/pages/nft-collection-details/index.tsx b/src/lib/pages/nft-collection-details/index.tsx index 9e278eab4..2ac301758 100644 --- a/src/lib/pages/nft-collection-details/index.tsx +++ b/src/lib/pages/nft-collection-details/index.tsx @@ -14,7 +14,6 @@ import { useCallback, useEffect } from "react"; import { AmpEvent, track, trackUseTab } from "lib/amplitude"; import { useInternalNavigate, useMobile } from "lib/app-provider"; -import { AppLink } from "lib/components/AppLink"; import { Breadcrumb } from "lib/components/Breadcrumb"; import { CustomTab } from "lib/components/CustomTab"; import { ExplorerLink } from "lib/components/ExplorerLink"; @@ -123,7 +122,9 @@ const CollectionDetailsBody = ({ direction="column" my={6} gap={1} - maxW={{ base: "full", md: "800px" }} + overflow="hidden" + minW={{ md: "680px" }} + maxW="full" > {name} @@ -159,22 +160,27 @@ const CollectionDetailsBody = ({ - - - + diff --git a/src/lib/pages/nft-collections/components/CollectionCard.tsx b/src/lib/pages/nft-collections/components/CollectionCard.tsx index e8a8198bc..bc07f2150 100644 --- a/src/lib/pages/nft-collections/components/CollectionCard.tsx +++ b/src/lib/pages/nft-collections/components/CollectionCard.tsx @@ -22,32 +22,46 @@ export const CollectionCard = ({ collectionInfo }: CollectionCardProps) => { bg: "gray.800", }} > - - {metadata?.image ? ( - - ) : ( - - )} - - + + + + {name} + {collections.map((collection) => ( diff --git a/src/lib/pages/nft-details/components/NftInfoItem.tsx b/src/lib/pages/nft-details/components/NftInfoItem.tsx index d1e7bc9f1..89ab1a555 100644 --- a/src/lib/pages/nft-details/components/NftInfoItem.tsx +++ b/src/lib/pages/nft-details/components/NftInfoItem.tsx @@ -13,7 +13,7 @@ export const NftInfoItem = ({ isCentered = true, }: NftInfoItemProps) => ( - {label}: + {label} {children} diff --git a/src/lib/pages/nft-details/components/Title.tsx b/src/lib/pages/nft-details/components/Title.tsx index 0b6138b7d..470f9d0f3 100644 --- a/src/lib/pages/nft-details/components/Title.tsx +++ b/src/lib/pages/nft-details/components/Title.tsx @@ -1,27 +1,54 @@ -import { Flex, Heading, Text } from "@chakra-ui/react"; +import { Alert, Flex, Heading, Text } from "@chakra-ui/react"; +import { useMobile } from "lib/app-provider"; import { AppLink } from "lib/components/AppLink"; import type { HexAddr32 } from "lib/types"; +import { ViewResourceButton } from "./ViewResourceButton"; + interface TitleProps { collectionAddress: HexAddr32; + nftAddress: HexAddr32; displayCollectionName: string; tokenId: string; + isBurned?: boolean; } export const Title = ({ collectionAddress, displayCollectionName, tokenId, -}: TitleProps) => ( - - - - {displayCollectionName} - - - - {tokenId} - - -); + nftAddress, + isBurned, +}: TitleProps) => { + const isMobile = useMobile(); + return ( + + {isBurned && ( + + + This NFT is already burned + + + )} + + + + + {displayCollectionName} + + + + {tokenId} + + + {!isMobile && } + + + ); +}; diff --git a/src/lib/pages/nft-details/components/ViewResourceButton.tsx b/src/lib/pages/nft-details/components/ViewResourceButton.tsx index ecbab95c7..a052c1e7f 100644 --- a/src/lib/pages/nft-details/components/ViewResourceButton.tsx +++ b/src/lib/pages/nft-details/components/ViewResourceButton.tsx @@ -15,6 +15,7 @@ export const ViewResourceButton = ({ nftAddress }: ViewResourceButtonProps) => {