- {data.map((item) => (
-
- ))}
+
+
+ Account Signers
+
+
+ {data.map((item) => (
+
+ ))}
+
);
};
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx
index c10fe11f36f..65f71d8aa36 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx
@@ -1,6 +1,8 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
+import { AccountSignersClient } from "./AccountSigners.client";
import { AccountSigners } from "./components/account-signers";
export default async function Page(props: {
@@ -15,7 +17,12 @@ export default async function Page(props: {
notFound();
}
- const { contract } = info;
+ const { contract, chainMetadata } = info;
+
+ if (chainMetadata.chainId === localhost.id) {
+ return
;
+ }
+
const { isAccountPermissionsSupported } =
await getContractPageMetadata(contract);
@@ -23,12 +30,5 @@ export default async function Page(props: {
redirect(`/${props.params.chain_id}/${props.params.contractAddress}`);
}
- return (
-
-
- Account Signers
-
-
-
- );
+ return
;
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx
new file mode 100644
index 00000000000..dffc95f9c04
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import type { ChainMetadata } from "thirdweb/chains";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { AccountPage } from "./AccountPage";
+
+export function AccountPageClient(props: {
+ contract: ThirdwebContract;
+ chainMetadata: ChainMetadata;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return
;
+ }
+
+ if (metadataQuery.isError) {
+ return
;
+ }
+
+ if (!metadataQuery.data.isAccount) {
+ return
;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx
index a465679cb47..ae2b201cf20 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx
@@ -1,7 +1,9 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
import { AccountPage } from "./AccountPage";
+import { AccountPageClient } from "./AccountPage.client";
export default async function Page(props: {
params: {
@@ -16,6 +18,12 @@ export default async function Page(props: {
}
const { contract, chainMetadata } = info;
+ if (contract.chain.id === localhost.id) {
+ return (
+
+ );
+ }
+
const { isAccount } = await getContractPageMetadata(contract);
if (!isAccount) {
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx
new file mode 100644
index 00000000000..005b3f1d561
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/AccountsPage.client.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { AccountsPage } from "./AccountsPage";
+
+export function AccountsPageClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return
;
+ }
+
+ if (metadataQuery.isError) {
+ return
;
+ }
+
+ if (!metadataQuery.data.isAccountFactory) {
+ return
;
+ }
+
+ return
;
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx
index 82d86959a13..998a7899413 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx
@@ -1,7 +1,9 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
import { AccountsPage } from "./AccountsPage";
+import { AccountsPageClient } from "./AccountsPage.client";
export default async function Page(props: {
params: {
@@ -15,7 +17,12 @@ export default async function Page(props: {
notFound();
}
- const { contract } = info;
+ const { contract, chainMetadata } = info;
+
+ if (chainMetadata.chainId === localhost.id) {
+ return
;
+ }
+
const { isAccountFactory } = await getContractPageMetadata(contract);
if (!isAccountFactory) {
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.client.tsx
new file mode 100644
index 00000000000..ed8010bd465
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/ContractAnalyticsPage.client.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { ContractAnalyticsPage } from "./ContractAnalyticsPage";
+
+export function ContractAnalyticsPageClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return
;
+ }
+
+ if (metadataQuery.isError) {
+ return
;
+ }
+
+ if (!metadataQuery.data.isAnalyticsSupported) {
+ return
;
+ }
+
+ return
;
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx
index d259d059f7d..85904d7360a 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx
@@ -1,7 +1,9 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
import { ContractAnalyticsPage } from "./ContractAnalyticsPage";
+import { ContractAnalyticsPageClient } from "./ContractAnalyticsPage.client";
export default async function Page(props: {
params: {
@@ -15,6 +17,10 @@ export default async function Page(props: {
notFound();
}
+ if (info.chainMetadata.chainId === localhost.id) {
+ return
;
+ }
+
const { isAnalyticsSupported } = await getContractPageMetadata(info.contract);
if (!isAnalyticsSupported) {
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx
new file mode 100644
index 00000000000..4c084f8759d
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/ClaimConditions.client.tsx
@@ -0,0 +1,38 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ClaimConditions } from "../_components/claim-conditions/claim-conditions";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+
+export function ClaimConditionsClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return
;
+ }
+
+ if (metadataQuery.isError) {
+ return
;
+ }
+
+ const {
+ isERC20ClaimConditionsSupported,
+ isERC721ClaimConditionsSupported,
+ supportedERCs,
+ } = metadataQuery.data;
+
+ if (!isERC20ClaimConditionsSupported && !isERC721ClaimConditionsSupported) {
+ return
;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx
index 12af1ceef38..f8193c0f13a 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx
@@ -1,7 +1,9 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { ClaimConditions } from "../_components/claim-conditions/claim-conditions";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
+import { ClaimConditionsClient } from "./ClaimConditions.client";
export default async function Page(props: {
params: {
@@ -14,8 +16,12 @@ export default async function Page(props: {
if (!info) {
notFound();
}
+ const { contract, chainMetadata } = info;
+
+ if (chainMetadata.chainId === localhost.id) {
+ return
;
+ }
- const { contract } = info;
const {
isERC20ClaimConditionsSupported,
isERC721ClaimConditionsSupported,
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.client.tsx
new file mode 100644
index 00000000000..b0829bb0b15
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.client.tsx
@@ -0,0 +1,26 @@
+"use client";
+
+import type { ChainMetadata } from "thirdweb/chains";
+import type { ThirdwebContract } from "thirdweb/contract";
+import { LoadingPage } from "../_components/page-skeletons";
+import { useResolveContractABI } from "../_hooks/useResolveContractABI";
+import { ContractCodePage } from "./contract-code-page";
+
+export function ContractCodePageClient(props: {
+ contract: ThirdwebContract;
+ chainMetadata: ChainMetadata;
+}) {
+ const abiQuery = useResolveContractABI(props.contract);
+
+ if (abiQuery.isPending) {
+ return
;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.tsx
new file mode 100644
index 00000000000..21306a29473
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/contract-code-page.tsx
@@ -0,0 +1,33 @@
+import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import type { Abi } from "abitype";
+import { CircleAlertIcon } from "lucide-react";
+import type { ChainMetadata } from "thirdweb/chains";
+import type { ThirdwebContract } from "thirdweb/contract";
+import { CodeOverview } from "../../../../../../contract-ui/tabs/code/components/code-overview";
+
+export function ContractCodePage(props: {
+ abi: Abi | undefined;
+ contract: ThirdwebContract;
+ chainMetadata: ChainMetadata;
+}) {
+ if (props.abi) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+ Failed to resolve contract ABI
+
+ Please verify that contract address is correct and deployed on "
+ {props.chainMetadata.name}" chain.
+
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx
index 3fcd4246acf..4b3bda1cc51 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/code/page.tsx
@@ -1,9 +1,9 @@
-import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
-import { CircleAlertIcon } from "lucide-react";
import { notFound } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { resolveContractAbi } from "thirdweb/contract";
-import { CodeOverview } from "../../../../../../contract-ui/tabs/code/components/code-overview";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
+import { ContractCodePage } from "./contract-code-page";
+import { ContractCodePageClient } from "./contract-code-page.client";
export default async function Page(props: {
params: {
@@ -19,26 +19,22 @@ export default async function Page(props: {
const { contract, chainMetadata } = info;
- try {
- const abi = await resolveContractAbi(contract);
-
+ if (contract.chain.id === localhost.id) {
return (
-
);
- } catch {
- return (
-
-
- Failed to resolve contract ABI
-
- Please verify that contract address is correct and deployed on "
- {chainMetadata.name}" chain.
-
-
- );
}
+
+ const abi = await resolveContractAbi(contract).then(() => undefined);
+
+ return (
+
+ );
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/EmbedSetup.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/EmbedSetup.client.tsx
new file mode 100644
index 00000000000..52794cbe07d
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/EmbedSetup.client.tsx
@@ -0,0 +1,32 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { EmbedSetup } from "./embed-setup";
+
+export function EmbedSetupClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return
;
+ }
+
+ if (metadataQuery.isError) {
+ return
;
+ }
+
+ if (metadataQuery.data.embedType === null) {
+ return
;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/page.tsx
index ffbe9fa5e9d..13bcbf22b20 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/embed/page.tsx
@@ -1,6 +1,8 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
+import { EmbedSetupClient } from "./EmbedSetup.client";
import { EmbedSetup } from "./embed-setup";
export default async function Page(props: {
@@ -15,11 +17,16 @@ export default async function Page(props: {
notFound();
}
- const { embedType } = await getContractPageMetadata(info.contract);
+ const { contract } = info;
+ if (contract.chain.id === localhost.id) {
+ return
;
+ }
+
+ const { embedType } = await getContractPageMetadata(contract);
if (embedType === null) {
redirect(`/${props.params.chain_id}/${props.params.contractAddress}`);
}
- return
;
+ return
;
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.client.tsx
new file mode 100644
index 00000000000..2c6285b3766
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.client.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import type { ChainMetadata } from "thirdweb/chains";
+import { LoadingPage } from "../_components/page-skeletons";
+import { useResolveContractABI } from "../_hooks/useResolveContractABI";
+import { ContractExplorerPage } from "./ContractExplorerPage";
+
+interface ContractExplorePageProps {
+ contract: ThirdwebContract;
+ chainMetadata: ChainMetadata;
+}
+
+export const ContractExplorerPageClient: React.FC
= ({
+ contract,
+ chainMetadata,
+}) => {
+ const abiQuery = useResolveContractABI(contract);
+
+ if (abiQuery.isPending) {
+ return ;
+ }
+
+ return (
+
+ );
+};
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.tsx
index 57a0ba58800..2ec7f4538a6 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/ContractExplorerPage.tsx
@@ -1,21 +1,36 @@
-"use client";
-
+import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Flex } from "@chakra-ui/react";
import type { Abi } from "abitype";
import { getContractFunctionsFromAbi } from "components/contract-components/getContractFunctionsFromAbi";
import { ContractFunctionsOverview } from "components/contract-functions/contract-functions";
+import { CircleAlertIcon } from "lucide-react";
import type { ThirdwebContract } from "thirdweb";
-
-// TODO - figure out why we have to add "use client" here and it does not work without it
+import type { ChainMetadata } from "thirdweb/chains";
interface ContractExplorePageProps {
contract: ThirdwebContract;
- abi: Abi;
+ abi: Abi | undefined;
+ chainMetadata: ChainMetadata;
}
+
export const ContractExplorerPage: React.FC = ({
contract,
abi,
+ chainMetadata,
}) => {
+ if (!abi) {
+ return (
+
+
+ Failed to resolve contract ABI
+
+ Please verify that contract address is correct and deployed on "
+ {chainMetadata.name}" chain.
+
+
+ );
+ }
+
const functions = getContractFunctionsFromAbi(abi);
return (
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx
index 940ec0a77d0..e6bdbe9aeda 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx
@@ -1,9 +1,9 @@
-import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
-import { CircleAlertIcon } from "lucide-react";
import { notFound } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { resolveContractAbi } from "thirdweb/contract";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { ContractExplorerPage } from "./ContractExplorerPage";
+import { ContractExplorerPageClient } from "./ContractExplorerPage.client";
export default async function Page(props: {
params: {
@@ -19,19 +19,22 @@ export default async function Page(props: {
const { contract, chainMetadata } = info;
- try {
- const abi = await resolveContractAbi(contract);
- return ;
- } catch {
+ if (contract.chain.id === localhost.id) {
return (
-
-
- Failed to resolve contract ABI
-
- Please verify that contract address is correct and deployed on "
- {chainMetadata.name}" chain.
-
-
+
);
}
+
+ const abi = await resolveContractAbi(contract).catch(() => undefined);
+
+ return (
+
+ );
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx
index 737f0b79c05..f0e14bef54d 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx
@@ -1,15 +1,14 @@
-import { ChakraProviderSetup } from "@/components/ChakraProviderSetup";
-import { SidebarLayout } from "@/components/blocks/SidebarLayout";
-import { ContractMetadata } from "components/custom-contract/contract-header/contract-metadata";
-import { DeprecatedAlert } from "components/shared/DeprecatedAlert";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractMetadata } from "thirdweb/extensions/common";
import { isAddress, isContractDeployed } from "thirdweb/utils";
import { resolveFunctionSelectors } from "../../../../../lib/selectors";
import { shortenIfAddress } from "../../../../../utils/usedapp-external";
-import { ConfigureCustomChain } from "./ConfigureCustomChain";
-import { PrimaryDashboardButton } from "./_components/primary-dashboard-button";
+import { ConfigureCustomChain } from "./_layout/ConfigureCustomChain";
+import { getContractMetadataHeaderData } from "./_layout/contract-metadata";
+import { ContractPageLayout } from "./_layout/contract-page-layout";
+import { ContractPageLayoutClient } from "./_layout/contract-page-layout.client";
import { supportedERCs } from "./_utils/detectedFeatures/supportedERCs";
import { getContractPageParamsInfo } from "./_utils/getContractFromParams";
import { getContractPageMetadata } from "./_utils/getContractPageMetadata";
@@ -38,44 +37,44 @@ export default async function Layout(props: {
notFound();
}
+ if (contract.chain.id === localhost.id) {
+ return (
+
+ {props.children}
+
+ );
+ }
+
// check if the contract exists
const isValidContract = await isContractDeployed(contract).catch(() => false);
if (!isValidContract) {
// TODO - replace 404 with a better page to upsale deploy or other thirdweb products
notFound();
}
-
const contractPageMetadata = await getContractPageMetadata(contract);
+
const sidebarLinks = getContractPageSidebarLinks({
chainSlug: chainMetadata.slug,
contractAddress: contract.address,
metadata: contractPageMetadata,
});
+ const { contractMetadata, externalLinks } =
+ await getContractMetadataHeaderData(contract);
+
return (
-
-
-
-
- {props.children}
-
-
+
+ {props.children}
+
);
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx
new file mode 100644
index 00000000000..3b0c7991e02
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/ContractEditModulesPage.client.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { ContractEditModulesPage } from "./ContractEditModulesPage";
+
+export function ContractEditModulesPageClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return ;
+ }
+
+ if (metadataQuery.isError) {
+ return ;
+ }
+
+ if (!metadataQuery.data.isModularCore) {
+ return ;
+ }
+
+ return ;
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx
index bd81c0cc96c..1c8be74a98c 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx
@@ -1,7 +1,9 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../_utils/getContractFromParams";
import { getContractPageMetadata } from "../_utils/getContractPageMetadata";
import { ContractEditModulesPage } from "./ContractEditModulesPage";
+import { ContractEditModulesPageClient } from "./ContractEditModulesPage.client";
export default async function Page(props: {
params: {
@@ -15,11 +17,16 @@ export default async function Page(props: {
notFound();
}
- const { isModularCore } = await getContractPageMetadata(info.contract);
+ const { contract } = info;
+ if (contract.chain.id === localhost.id) {
+ return ;
+ }
+
+ const { isModularCore } = await getContractPageMetadata(contract);
if (!isModularCore) {
redirect(`/${props.params.chain_id}/${props.params.contractAddress}`);
}
- return ;
+ return ;
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx
new file mode 100644
index 00000000000..54b6a92541c
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../_components/page-skeletons";
+import { RedirectToContractOverview } from "../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../_hooks/useContractPageMetadata";
+import { ContractNFTPage } from "./ContractNFTPage";
+
+export function ContractNFTPageClient(props: {
+ contract: ThirdwebContract;
+}) {
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return ;
+ }
+
+ if (metadataQuery.isError) {
+ return ;
+ }
+
+ const { supportedERCs, functionSelectors } = metadataQuery.data;
+
+ if (!supportedERCs.isERC721 && !supportedERCs.isERC1155) {
+ return ;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx
new file mode 100644
index 00000000000..2f7ad12695a
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx
@@ -0,0 +1,37 @@
+"use client";
+
+import type { ThirdwebContract } from "thirdweb";
+import { ErrorPage, LoadingPage } from "../../_components/page-skeletons";
+import { RedirectToContractOverview } from "../../_components/redirect-contract-overview.client";
+import { useContractPageMetadata } from "../../_hooks/useContractPageMetadata";
+import { TokenIdPage } from "./token-id";
+
+export function TokenIdPageClient(props: {
+ contract: ThirdwebContract;
+ tokenId: string;
+}) {
+ const { contract } = props;
+ const metadataQuery = useContractPageMetadata(props.contract);
+
+ if (metadataQuery.isPending) {
+ return ;
+ }
+
+ if (metadataQuery.isError) {
+ return ;
+ }
+
+ const { supportedERCs } = metadataQuery.data;
+
+ if (!supportedERCs.isERC721 && !supportedERCs.isERC1155) {
+ return ;
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx
index d41e4239b56..a490a5d3f0c 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx
@@ -1,6 +1,8 @@
import { notFound, redirect } from "next/navigation";
+import { localhost } from "thirdweb/chains";
import { getContractPageParamsInfo } from "../../_utils/getContractFromParams";
import { getContractPageMetadata } from "../../_utils/getContractPageMetadata";
+import { TokenIdPageClient } from "./TokenIdPage.client";
import { TokenIdPage } from "./token-id";
export default async function Page(props: {
@@ -16,18 +18,24 @@ export default async function Page(props: {
notFound();
}
+ if (!isOnlyNumbers(props.params.tokenId)) {
+ // redirect to nfts index page
+ redirect(`/${props.params.chain_id}/${props.params.contractAddress}/nfts`);
+ }
+
const { contract } = info;
+ if (contract.chain.id === localhost.id) {
+ return (
+
+ );
+ }
+
const { supportedERCs } = await getContractPageMetadata(contract);
if (!supportedERCs.isERC721 && !supportedERCs.isERC1155) {
redirect(`/${props.params.chain_id}/${props.params.contractAddress}`);
}
- if (!isOnlyNumbers(props.params.tokenId)) {
- // redirect to nfts index page
- redirect(`/${props.params.chain_id}/${props.params.contractAddress}/nfts`);
- }
-
return (
;
+ }
+
+ const { supportedERCs, functionSelectors } =
+ await getContractPageMetadata(contract);
if (!supportedERCs.isERC721 && !supportedERCs.isERC1155) {
redirect(`/${props.params.chain_id}/${props.params.contractAddress}`);
}
- const functionSelectors = await resolveFunctionSelectors(contract);
-
return (
= ({
chainSlug,
isAnalyticsSupported,
functionSelectors,
+ publishedBy,
}) => {
return (
@@ -99,11 +99,7 @@ export const ContractOverviewPage: React.FC = ({
contractAddress={contract.address}
/>
-
+ {publishedBy}
);
};
diff --git a/apps/dashboard/src/components/contract-components/shared/published-by.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx
similarity index 79%
rename from apps/dashboard/src/components/contract-components/shared/published-by.tsx
rename to apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx
index 50802e0fb01..29a42696e17 100644
--- a/apps/dashboard/src/components/contract-components/shared/published-by.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx
@@ -1,20 +1,14 @@
-import { getThirdwebClient } from "@/constants/thirdweb.server";
import { ContractCard } from "components/explore/contract-card";
import { THIRDWEB_DEPLOYER_ADDRESS } from "constants/addresses";
-import type { ThirdwebContract } from "thirdweb";
+import type { ThirdwebClient, ThirdwebContract } from "thirdweb";
import { polygon } from "thirdweb/chains";
import { getBytecode, getContract } from "thirdweb/contract";
import { getPublishedUriFromCompilerUri } from "thirdweb/extensions/thirdweb";
import { getInstalledModules } from "thirdweb/modules";
import { download } from "thirdweb/storage";
import { extractIPFSUri } from "thirdweb/utils";
-import { getAuthTokenWalletAddress } from "../../../app/api/lib/getAuthToken";
-import { isEnsName, resolveEns } from "../../../lib/ens";
-import { fetchPublishedContractsFromDeploy } from "../fetchPublishedContractsFromDeploy";
-
-interface PublishedByProps {
- contract: ThirdwebContract;
-}
+import { fetchPublishedContractsFromDeploy } from "../../../../../../../components/contract-components/fetchPublishedContractsFromDeploy";
+import { isEnsName, resolveEns } from "../../../../../../../lib/ens";
type ModuleMetadataPickedKeys = {
publisher: string;
@@ -23,15 +17,18 @@ type ModuleMetadataPickedKeys = {
version: string;
};
-export const PublishedBy: React.FC