Skip to content

Commit abf343e

Browse files
committed
Add Contract layout in team/project
1 parent 3489ece commit abf343e

File tree

117 files changed

+2847
-1277
lines changed

Some content is hidden

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

117 files changed

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

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ 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";
67

78
type NFTWithContract = NFT & { contractAddress: string; chainId: number };
89

@@ -29,20 +30,26 @@ interface NFTCardsProps {
2930
trackingCategory: string;
3031
isPending: boolean;
3132
allNfts?: boolean;
33+
projectMeta: ProjectMeta | undefined;
3234
}
3335

3436
export const NFTCards: React.FC<NFTCardsProps> = ({
3537
nfts,
3638
trackingCategory,
3739
isPending,
3840
allNfts,
41+
projectMeta,
3942
}) => {
4043
const dummyData = useMemo(() => {
4144
return Array.from({
4245
length: allNfts ? nfts.length : 3,
4346
}).map((_, idx) => dummyMetadata(idx));
4447
}, [nfts.length, allNfts]);
4548

49+
const contractRootPath = projectMeta
50+
? `/team/${projectMeta.teamSlug}/${projectMeta.projectSlug}/contract`
51+
: "";
52+
4653
return (
4754
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
4855
{(isPending ? dummyData : nfts).map((token) => {
@@ -87,7 +94,7 @@ export const NFTCards: React.FC<NFTCardsProps> = ({
8794
<TrackedLinkTW
8895
category={trackingCategory}
8996
label="view_nft"
90-
href={`/${token.chainId}/${token.contractAddress}/nfts/${tokenId}`}
97+
href={`${contractRootPath}/${token.chainId}/${token.contractAddress}/nfts/${tokenId}`}
9198
className="before:absolute before:inset-0"
9299
>
93100
{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,12 @@
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";
67
import { LoadingPage } from "./page-skeletons";
78

89
export function RedirectToContractOverview(props: {
910
contract: ThirdwebContract;
11+
projectMeta: ProjectMeta | undefined;
1012
}) {
1113
const router = useDashboardRouter();
1214
const redirected = useRef(false);
@@ -17,8 +19,15 @@ export function RedirectToContractOverview(props: {
1719
return;
1820
}
1921
redirected.current = true;
20-
router.replace(`/${props.contract.chain.id}/${props.contract.address}`);
21-
}, [router, props.contract]);
22+
if (!props.projectMeta) {
23+
router.replace(`/${props.contract.chain.id}/${props.contract.address}`);
24+
} else {
25+
const { teamSlug, projectSlug } = props.projectMeta;
26+
router.replace(
27+
`/team/${teamSlug}/${projectSlug}/contract/${props.contract.chain.id}/${props.contract.address}`,
28+
);
29+
}
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)