Skip to content

Commit

Permalink
Merge pull request #1033 from alleslabs/feature/cfe-569-nft-detail
Browse files Browse the repository at this point in the history
[CFE-569]: Feat(pages): NFT details page
  • Loading branch information
evilpeach authored Jul 23, 2024
2 parents 79d687f + 478974e commit f40d941
Show file tree
Hide file tree
Showing 17 changed files with 330 additions and 63 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#1033](https://github.com/alleslabs/celatone-frontend/pull/1033) Add Sequencer for NFT details
- [#1015](https://github.com/alleslabs/celatone-frontend/pull/1015) New network selector
- [#1032](https://github.com/alleslabs/celatone-frontend/pull/1032) Search collection address on both full and sequencer tier
- [#1024](https://github.com/alleslabs/celatone-frontend/pull/1024) Add Sequencer for account detail NFTs
Expand Down
1 change: 1 addition & 0 deletions src/lib/app-provider/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export enum CELATONE_QUERY_KEYS {
NFT_TOKEN_MINT_INFO = "CELATONE_QUERY_NFT_TOKEN_MINT_INFO",
NFT_METADATA = "CELATONE_QUERY_NFT_METADATA",
NFT_TRANSACTIONS = "CELATONE_QUERY_NFT_TRANSACTIONS",
NFT_TRANSACTIONS_SEQUENCER = "CELATONE_QUERY_NFT_TRANSACTIONS_SEQUENCER",
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",
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/nft/NftCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { AppLink } from "../AppLink";
import { AmpEvent, track } from "lib/amplitude";
import { NFT_IMAGE_PLACEHOLDER } from "lib/data";
import { useMetadata } from "lib/services/nft";
import type { HexAddr32, Option } from "lib/types";
import type { HexAddr32, Nullable } from "lib/types";

interface NftCardProps {
uri: string;
tokenId: string;
collectionName: string;
collectionName: Nullable<string>;
collectionAddress: HexAddr32;
nftAddress: Option<HexAddr32>;
nftAddress: Nullable<HexAddr32>;
showCollection?: boolean;
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib/pages/account-details/components/nfts/FilterItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ 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";
import type { Nullable } from "lib/types";

interface FilterItemProps {
collectionName: string;
collectionName: Nullable<string>;
count: number;
onClick: () => void;
uri?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/pages/nft-details/components/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface TitleProps {
nftAddress: HexAddr32;
displayCollectionName: string;
tokenId: string;
isBurned?: boolean;
isBurned: boolean;
}

export const Title = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import type { HexAddr32 } from "lib/types";

import { TxsTable } from "./TxsTable";

interface TxsProps {
interface TxsFullProps {
nftAddress: HexAddr32;
totalData: number;
}

export const Txs = ({ nftAddress, totalData }: TxsProps) => {
export const TxsFull = ({ nftAddress, totalData }: TxsFullProps) => {
const {
pagesQuantity,
currentPage,
Expand Down
24 changes: 24 additions & 0 deletions src/lib/pages/nft-details/components/tables/txs/TxsSequencer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { EmptyState } from "lib/components/state";
import { useNftTransactionsSequencer } from "lib/services/nft";
import type { HexAddr32 } from "lib/types";

import { TxsTable } from "./TxsTable";

interface TxsSequencerProps {
nftAddress: HexAddr32;
}

export const TxsSequencer = ({ nftAddress }: TxsSequencerProps) => {
const { data: transactions, isLoading } =
useNftTransactionsSequencer(nftAddress);

return (
<TxsTable
txs={transactions}
isLoading={isLoading}
emptyState={
<EmptyState imageVariant="empty" message="Transactions not found." />
}
/>
);
};
2 changes: 2 additions & 0 deletions src/lib/pages/nft-details/components/tables/txs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./TxsFull";
export * from "./TxsSequencer";
56 changes: 39 additions & 17 deletions src/lib/pages/nft-details/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable complexity */
import {
Divider,
Flex,
Expand All @@ -22,6 +23,7 @@ import { Loading } from "lib/components/Loading";
import PageContainer from "lib/components/PageContainer";
import { CelatoneSeo } from "lib/components/Seo";
import { ErrorFetching, InvalidState } from "lib/components/state";
import { TierSwitcher } from "lib/components/TierSwitcher";
import { Tooltip } from "lib/components/Tooltip";
import { UserDocsLink } from "lib/components/UserDocsLink";
import { NFT_IMAGE_PLACEHOLDER } from "lib/data";
Expand All @@ -30,6 +32,7 @@ import {
useNftByNftAddress,
useNftMutateEventsCount,
useNftTransactionsCount,
useNftTransactionsSequencer,
} from "lib/services/nft";
import { useCollectionByCollectionAddress } from "lib/services/nft-collection";

Expand All @@ -41,7 +44,8 @@ import {
NftInfoItem,
NftMutateEvents,
Title,
Txs,
TxsFull,
TxsSequencer,
ViewResourceButton,
} from "./components";
import type { NftDetailQueryParams } from "./types";
Expand All @@ -54,15 +58,26 @@ const NftDetailsBody = ({
nftAddress,
}: NftDetailQueryParams) => {
const isMobile = useMobile();
const { isFullTier, isSequencerTier } = useTierConfig();

const { data: collection, isLoading: isCollectionLoading } =
useCollectionByCollectionAddress(collectionAddress);
const { data: nft, isLoading: isNftLoading } = useNftByNftAddress(
collectionAddress,
nftAddress
);
const { data: txCount = 0 } = useNftTransactionsCount(nftAddress);
const { data: mutateEventsCount = 0 } = useNftMutateEventsCount(nftAddress);

const { data: txCount = 0 } = useNftTransactionsCount(nftAddress, isFullTier);
const { data: transactions } = useNftTransactionsSequencer(
nftAddress,
isSequencerTier
);
const totalTxs = isFullTier ? txCount : transactions?.length ?? 0;

const { data: mutateEventsCount = 0 } = useNftMutateEventsCount(
nftAddress,
isFullTier
);
const { data: metadata } = useMetadata(nft?.data?.uri ?? "");

if (isCollectionLoading || isNftLoading) return <Loading />;
Expand Down Expand Up @@ -247,24 +262,31 @@ const NftDetailsBody = ({
borderColor="gray.700"
overflowX="scroll"
>
<CustomTab count={txCount}>Transactions</CustomTab>
<CustomTab
count={mutateEventsCount}
isDisabled={!mutateEventsCount}
>
Mutate Events
</CustomTab>
<CustomTab count={totalTxs}>Transactions</CustomTab>
{isFullTier && (
<CustomTab
count={mutateEventsCount}
isDisabled={!mutateEventsCount}
>
Mutate Events
</CustomTab>
)}
</TabList>
<TabPanels>
<TabPanel p={0}>
<Txs nftAddress={nftAddress} totalData={txCount} />
</TabPanel>
<TabPanel p={0}>
<NftMutateEvents
nftAddress={nftAddress}
totalData={mutateEventsCount}
<TierSwitcher
full={<TxsFull nftAddress={nftAddress} totalData={txCount} />}
sequencer={<TxsSequencer nftAddress={nftAddress} />}
/>
</TabPanel>
{isFullTier && (
<TabPanel p={0}>
<NftMutateEvents
nftAddress={nftAddress}
totalData={mutateEventsCount}
/>
</TabPanel>
)}
</TabPanels>
</Tabs>
<UserDocsLink
Expand All @@ -278,7 +300,7 @@ const NftDetailsBody = ({
};

const NftDetails = observer(() => {
useTierConfig({ minTier: "full" });
useTierConfig({ minTier: "sequencer" });
const router = useRouter();
const validated = zNftDetailQueryParams.safeParse(router.query);

Expand Down
19 changes: 19 additions & 0 deletions src/lib/services/move/module/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
zModuleTableCountsResponse,
zModuleTxsResponse,
zModuleVerificationInternal,
zMoveViewJsonResponse,
} from "lib/services/types";
import type {
AbiFormData,
Expand Down Expand Up @@ -180,3 +181,21 @@ export const getModuleRelatedProposals = async (
}
)
.then(({ data }) => parseWithError(zModuleRelatedProposalsResponse, data));

export const getMoveViewJson = async (
endpoint: string,
vmAddress: HexAddr,
moduleName: string,
functionName: string,
typeArgs: string[],
args: string[]
) =>
axios
.post(`${endpoint}/initia/move/v1/view/json`, {
address: vmAddress,
module_name: moduleName,
function_name: functionName,
type_args: typeArgs,
args,
})
.then(({ data }) => parseWithError(zMoveViewJsonResponse, data));
12 changes: 6 additions & 6 deletions src/lib/services/nft-collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const useCollectionByCollectionAddress = (
const { chainConfig } = useCelatoneApp();
const { tier } = useTierConfig();
const lcdEndpoint = useLcdEndpoint();

return useQuery<CollectionByCollectionAddressResponse>(
[
CELATONE_QUERY_KEYS.NFT_COLLECTION_BY_COLLECTION_ADDRESS,
Expand All @@ -76,18 +77,17 @@ export const useCollectionByCollectionAddress = (
handleQueryByTier({
tier,
threshold: "sequencer",
querySequencer: () =>
getCollectionByCollectionAddressSequencer(
lcdEndpoint,
collectionAddress
),
queryFull: () =>
getCollectionByCollectionAddress(
chainConfig.indexer,
collectionAddress
),
querySequencer: () =>
getCollectionByCollectionAddressSequencer(
lcdEndpoint,
collectionAddress
),
}),

{
retry: 1,
refetchOnWindowFocus: false,
Expand Down
Loading

0 comments on commit f40d941

Please sign in to comment.