Skip to content

Commit 3f5b1f2

Browse files
committed
Add Contract layout in team/project
1 parent 9479d25 commit 3f5b1f2

File tree

118 files changed

+2947
-1302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+2947
-1302
lines changed

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/ContractDirectListingsPage.client.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import type { ThirdwebContract } from "thirdweb";
4+
import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
45
import { ErrorPage, LoadingPage } from "../../_components/page-skeletons";
56
import { RedirectToContractOverview } from "../../_components/redirect-contract-overview.client";
67
import { useContractPageMetadata } from "../../_hooks/useContractPageMetadata";
@@ -9,6 +10,7 @@ import { ContractDirectListingsPage } from "./ContractDirectListingsPage";
910
export function ContractDirectListingsPageClient(props: {
1011
contract: ThirdwebContract;
1112
isLoggedIn: boolean;
13+
projectMeta: ProjectMeta | undefined;
1214
}) {
1315
const metadataQuery = useContractPageMetadata(props.contract);
1416

@@ -21,7 +23,12 @@ export function ContractDirectListingsPageClient(props: {
2123
}
2224

2325
if (!metadataQuery.data.isDirectListingSupported) {
24-
return <RedirectToContractOverview contract={props.contract} />;
26+
return (
27+
<RedirectToContractOverview
28+
contract={props.contract}
29+
projectMeta={props.projectMeta}
30+
/>
31+
);
2532
}
2633

2734
return (
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,18 @@
1-
import { notFound, redirect } from "next/navigation";
21
import { getRawAccount } from "../../../../../../account/settings/getAccount";
3-
import { getContractPageParamsInfo } from "../../_utils/getContractFromParams";
4-
import { getContractPageMetadata } from "../../_utils/getContractPageMetadata";
5-
import { ContractDirectListingsPage } from "./ContractDirectListingsPage";
6-
import { ContractDirectListingsPageClient } from "./ContractDirectListingsPage.client";
2+
import type { PublicContractPageParams } from "../../types";
3+
import { SharedDirectListingsPage } from "./shared-direct-listings-page";
74

85
export default async function Page(props: {
9-
params: Promise<{
10-
contractAddress: string;
11-
chain_id: string;
12-
}>;
6+
params: Promise<PublicContractPageParams>;
137
}) {
14-
const params = await props.params;
15-
const account = await getRawAccount();
16-
const info = await getContractPageParamsInfo(params);
17-
18-
if (!info) {
19-
notFound();
20-
}
21-
22-
if (info.isLocalhostChain) {
23-
return (
24-
<ContractDirectListingsPageClient
25-
contract={info.clientContract}
26-
isLoggedIn={!!account}
27-
/>
28-
);
29-
}
30-
31-
const { isDirectListingSupported, isInsightSupported } =
32-
await getContractPageMetadata(info.serverContract);
33-
34-
if (!isDirectListingSupported) {
35-
redirect(`/${params.chain_id}/${params.contractAddress}`);
36-
}
8+
const [params, account] = await Promise.all([props.params, getRawAccount()]);
379

3810
return (
39-
<ContractDirectListingsPage
40-
contract={info.clientContract}
11+
<SharedDirectListingsPage
12+
contractAddress={params.contractAddress}
13+
chainIdOrSlug={params.chain_id}
14+
projectMeta={undefined}
4115
isLoggedIn={!!account}
42-
isInsightSupported={isInsightSupported}
4316
/>
4417
);
4518
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { notFound } from "next/navigation";
2+
import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
3+
import { redirectToContractLandingPage } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils";
4+
import { getContractPageParamsInfo } from "../../_utils/getContractFromParams";
5+
import { getContractPageMetadata } from "../../_utils/getContractPageMetadata";
6+
import { ContractDirectListingsPage } from "./ContractDirectListingsPage";
7+
import { ContractDirectListingsPageClient } from "./ContractDirectListingsPage.client";
8+
9+
export async function SharedDirectListingsPage(props: {
10+
contractAddress: string;
11+
chainIdOrSlug: string;
12+
projectMeta: ProjectMeta | undefined;
13+
isLoggedIn: boolean;
14+
}) {
15+
const info = await getContractPageParamsInfo({
16+
contractAddress: props.contractAddress,
17+
chainIdOrSlug: props.chainIdOrSlug,
18+
teamId: props.projectMeta?.teamId,
19+
});
20+
21+
if (!info) {
22+
notFound();
23+
}
24+
25+
if (info.isLocalhostChain) {
26+
return (
27+
<ContractDirectListingsPageClient
28+
contract={info.clientContract}
29+
isLoggedIn={props.isLoggedIn}
30+
projectMeta={props.projectMeta}
31+
/>
32+
);
33+
}
34+
35+
const { isDirectListingSupported, isInsightSupported } =
36+
await getContractPageMetadata(info.serverContract);
37+
38+
if (!isDirectListingSupported) {
39+
redirectToContractLandingPage({
40+
chainIdOrSlug: props.chainIdOrSlug,
41+
contractAddress: props.contractAddress,
42+
projectMeta: props.projectMeta,
43+
});
44+
}
45+
46+
return (
47+
<ContractDirectListingsPage
48+
contract={info.clientContract}
49+
isLoggedIn={props.isLoggedIn}
50+
isInsightSupported={isInsightSupported}
51+
/>
52+
);
53+
}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/ContractEnglishAuctionsPage.client.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import type { ThirdwebContract } from "thirdweb";
4+
import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
45
import { ErrorPage, LoadingPage } from "../../_components/page-skeletons";
56
import { RedirectToContractOverview } from "../../_components/redirect-contract-overview.client";
67
import { useContractPageMetadata } from "../../_hooks/useContractPageMetadata";
@@ -9,6 +10,7 @@ import { ContractEnglishAuctionsPage } from "./ContractEnglishAuctionsPage";
910
export function ContractEnglishAuctionsPageClient(props: {
1011
contract: ThirdwebContract;
1112
isLoggedIn: boolean;
13+
projectMeta: ProjectMeta | undefined;
1214
}) {
1315
const metadataQuery = useContractPageMetadata(props.contract);
1416

@@ -21,7 +23,12 @@ export function ContractEnglishAuctionsPageClient(props: {
2123
}
2224

2325
if (!metadataQuery.data.isEnglishAuctionSupported) {
24-
return <RedirectToContractOverview contract={props.contract} />;
26+
return (
27+
<RedirectToContractOverview
28+
contract={props.contract}
29+
projectMeta={props.projectMeta}
30+
/>
31+
);
2532
}
2633

2734
return (
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,18 @@
1-
import { notFound, redirect } from "next/navigation";
21
import { getRawAccount } from "../../../../../../account/settings/getAccount";
3-
import { getContractPageParamsInfo } from "../../_utils/getContractFromParams";
4-
import { getContractPageMetadata } from "../../_utils/getContractPageMetadata";
5-
import { ContractEnglishAuctionsPage } from "./ContractEnglishAuctionsPage";
6-
import { ContractEnglishAuctionsPageClient } from "./ContractEnglishAuctionsPage.client";
2+
import type { PublicContractPageParams } from "../../types";
3+
import { SharedEnglishAuctionsPage } from "./shared-english-auctions-page";
74

85
export default async function Page(props: {
9-
params: Promise<{
10-
contractAddress: string;
11-
chain_id: string;
12-
}>;
6+
params: Promise<PublicContractPageParams>;
137
}) {
14-
const params = await props.params;
15-
const info = await getContractPageParamsInfo(params);
16-
17-
if (!info) {
18-
notFound();
19-
}
20-
21-
const twAccount = await getRawAccount();
22-
23-
if (info.isLocalhostChain) {
24-
return (
25-
<ContractEnglishAuctionsPageClient
26-
contract={info.clientContract}
27-
isLoggedIn={!!twAccount}
28-
/>
29-
);
30-
}
31-
32-
const { isEnglishAuctionSupported, isInsightSupported } =
33-
await getContractPageMetadata(info.serverContract);
34-
35-
if (!isEnglishAuctionSupported) {
36-
redirect(`/${params.chain_id}/${params.contractAddress}`);
37-
}
8+
const [params, account] = await Promise.all([props.params, getRawAccount()]);
389

3910
return (
40-
<ContractEnglishAuctionsPage
41-
contract={info.clientContract}
42-
isLoggedIn={!!twAccount}
43-
isInsightSupported={isInsightSupported}
11+
<SharedEnglishAuctionsPage
12+
contractAddress={params.contractAddress}
13+
chainIdOrSlug={params.chain_id}
14+
projectMeta={undefined}
15+
isLoggedIn={!!account}
4416
/>
4517
);
4618
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { notFound } from "next/navigation";
2+
import type { ProjectMeta } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
3+
import { redirectToContractLandingPage } from "../../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/utils";
4+
import { getContractPageParamsInfo } from "../../_utils/getContractFromParams";
5+
import { getContractPageMetadata } from "../../_utils/getContractPageMetadata";
6+
import { ContractEnglishAuctionsPage } from "./ContractEnglishAuctionsPage";
7+
import { ContractEnglishAuctionsPageClient } from "./ContractEnglishAuctionsPage.client";
8+
9+
export async function SharedEnglishAuctionsPage(props: {
10+
contractAddress: string;
11+
chainIdOrSlug: string;
12+
projectMeta: ProjectMeta | undefined;
13+
isLoggedIn: boolean;
14+
}) {
15+
const info = await getContractPageParamsInfo({
16+
contractAddress: props.contractAddress,
17+
chainIdOrSlug: props.chainIdOrSlug,
18+
teamId: props.projectMeta?.teamId,
19+
});
20+
21+
if (!info) {
22+
notFound();
23+
}
24+
25+
if (info.isLocalhostChain) {
26+
return (
27+
<ContractEnglishAuctionsPageClient
28+
contract={info.clientContract}
29+
isLoggedIn={props.isLoggedIn}
30+
projectMeta={props.projectMeta}
31+
/>
32+
);
33+
}
34+
35+
const metadata = await getContractPageMetadata(info.serverContract);
36+
37+
if (!metadata.isEnglishAuctionSupported) {
38+
redirectToContractLandingPage({
39+
contractAddress: props.contractAddress,
40+
chainIdOrSlug: props.chainIdOrSlug,
41+
projectMeta: props.projectMeta,
42+
});
43+
}
44+
45+
return (
46+
<ContractEnglishAuctionsPage
47+
contract={info.clientContract}
48+
isLoggedIn={props.isLoggedIn}
49+
isInsightSupported={metadata.isInsightSupported}
50+
/>
51+
);
52+
}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { TrackedLinkTW } from "@/components/ui/tracked-link";
33
import { useMemo } from "react";
44
import { type NFT, ZERO_ADDRESS } from "thirdweb";
55
import { NFTMediaWithEmptyState } from "tw-components/nft-media";
6+
import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
7+
import { buildContractPagePath } from "../_utils/contract-page-path";
68

79
type NFTWithContract = NFT & { contractAddress: string; chainId: number };
810

@@ -29,13 +31,15 @@ interface NFTCardsProps {
2931
trackingCategory: string;
3032
isPending: boolean;
3133
allNfts?: boolean;
34+
projectMeta: ProjectMeta | undefined;
3235
}
3336

3437
export const NFTCards: React.FC<NFTCardsProps> = ({
3538
nfts,
3639
trackingCategory,
3740
isPending,
3841
allNfts,
42+
projectMeta,
3943
}) => {
4044
const dummyData = useMemo(() => {
4145
return Array.from({
@@ -87,7 +91,12 @@ export const NFTCards: React.FC<NFTCardsProps> = ({
8791
<TrackedLinkTW
8892
category={trackingCategory}
8993
label="view_nft"
90-
href={`/${token.chainId}/${token.contractAddress}/nfts/${tokenId}`}
94+
href={buildContractPagePath({
95+
projectMeta,
96+
chainIdOrSlug: token.chainId.toString(),
97+
contractAddress: token.contractAddress,
98+
subpath: `/nfts/${tokenId}`,
99+
})}
91100
className="before:absolute before:inset-0"
92101
>
93102
{v.name}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/redirect-contract-overview.client.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import { useDashboardRouter } from "@/lib/DashboardRouter";
44
import { useEffect, useRef } from "react";
55
import type { ThirdwebContract } from "thirdweb";
6+
import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
7+
import { buildContractPagePath } from "../_utils/contract-page-path";
68
import { LoadingPage } from "./page-skeletons";
79

810
export function RedirectToContractOverview(props: {
911
contract: ThirdwebContract;
12+
projectMeta: ProjectMeta | undefined;
1013
}) {
1114
const router = useDashboardRouter();
1215
const redirected = useRef(false);
@@ -17,8 +20,14 @@ export function RedirectToContractOverview(props: {
1720
return;
1821
}
1922
redirected.current = true;
20-
router.replace(`/${props.contract.chain.id}/${props.contract.address}`);
21-
}, [router, props.contract]);
23+
const landingPage = buildContractPagePath({
24+
projectMeta: props.projectMeta,
25+
chainIdOrSlug: props.contract.chain.id.toString(),
26+
contractAddress: props.contract.address,
27+
});
28+
29+
router.replace(landingPage);
30+
}, [router, props]);
2231

2332
return <LoadingPage />;
2433
}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
import { useQuery } from "@tanstack/react-query";
44
import type { MinimalTeamsAndProjects } from "components/contract-components/contract-deploy-form/add-to-project-card";
5-
import type { ThirdwebClient, ThirdwebContract } from "thirdweb";
5+
import type { ThirdwebContract } from "thirdweb";
66
import type { ChainMetadata } from "thirdweb/chains";
7+
import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
78
import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
89
import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
910
import { getContractPageSidebarLinks } from "../_utils/getContractPageSidebarLinks";
@@ -15,7 +16,7 @@ export function ContractPageLayoutClient(props: {
1516
contract: ThirdwebContract;
1617
children: React.ReactNode;
1718
teamsAndProjects: MinimalTeamsAndProjects | undefined;
18-
client: ThirdwebClient;
19+
projectMeta: ProjectMeta | undefined;
1920
}) {
2021
const metadataQuery = useContractPageMetadata(props.contract);
2122
const headerMetadataQuery = useQuery({
@@ -39,6 +40,7 @@ export function ContractPageLayoutClient(props: {
3940
chainSlug: props.chainMetadata.slug,
4041
contractAddress: props.contract.address,
4142
metadata: metadataQuery.data,
43+
projectMeta: props.projectMeta,
4244
});
4345

4446
return (

0 commit comments

Comments
 (0)