diff --git a/apps/dashboard/src/@/components/blocks/markdown-renderer.tsx b/apps/dashboard/src/@/components/blocks/markdown-renderer.tsx index 50fbd05d381..cfb3b903a58 100644 --- a/apps/dashboard/src/@/components/blocks/markdown-renderer.tsx +++ b/apps/dashboard/src/@/components/blocks/markdown-renderer.tsx @@ -94,7 +94,7 @@ export const MarkdownRenderer: React.FC<{

@@ -105,7 +105,7 @@ export const MarkdownRenderer: React.FC<{ {...cleanedProps(props)} className={cn( commonHeadingClassName, - "mt-8 mb-3 border-border border-b pb-2 text-lg md:text-xl", + "mt-8 mb-3 border-dashed border-b pb-2 text-lg md:text-xl", )} /> ), @@ -147,7 +147,7 @@ export const MarkdownRenderer: React.FC<{ li: ({ children: c, ...props }) => (
  • p]:m-0", + "text-muted-foreground leading-relaxed [&>p]:m-0", markdownProps.li?.className, )} {...cleanedProps(props)} @@ -157,7 +157,7 @@ export const MarkdownRenderer: React.FC<{ ), ol: (props) => (
      ), @@ -165,7 +165,7 @@ export const MarkdownRenderer: React.FC<{ p: (props) => (

      { return (

        ); diff --git a/apps/dashboard/src/@/components/contract-components/publisher/publisher-header.tsx b/apps/dashboard/src/@/components/contract-components/publisher/publisher-header.tsx index 395b0adaead..823830499f1 100644 --- a/apps/dashboard/src/@/components/contract-components/publisher/publisher-header.tsx +++ b/apps/dashboard/src/@/components/contract-components/publisher/publisher-header.tsx @@ -1,5 +1,6 @@ "use client"; +import { ExternalLinkIcon } from "lucide-react"; import Link from "next/link"; import { type ThirdwebClient, ZERO_ADDRESS } from "thirdweb"; import { @@ -9,7 +10,6 @@ import { AccountName, AccountProvider, } from "thirdweb/react"; -import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { useEns } from "@/hooks/contract-hooks"; import { replaceDeployerAddress } from "@/lib/publisher-utils"; @@ -29,57 +29,63 @@ export const PublisherHeader: React.FC = ({ }); return ( -
        -

        Published by

        - +
        +

        Published by

        -
        - - } - loadingComponent={} - /> - - - +
        + {ensQuery.data?.ensName} - ) : ( - - shortenIfAddress(replaceDeployerAddress(addr)) - } - /> - ) + + } + loadingComponent={ + } - formatFn={(name) => replaceDeployerAddress(name)} - loadingComponent={} /> - +
        + +
        + + + {ensQuery.data?.ensName} + + ) : ( + + shortenIfAddress(replaceDeployerAddress(addr)) + } + /> + ) + } + formatFn={(name) => replaceDeployerAddress(name)} + loadingComponent={} + /> + + + + View all published contracts{" "} + + +
        - -
        ); }; diff --git a/apps/dashboard/src/@/components/contracts/published-contract/index.tsx b/apps/dashboard/src/@/components/contracts/published-contract/index.tsx index c285f55ecba..bf7d93a0752 100644 --- a/apps/dashboard/src/@/components/contracts/published-contract/index.tsx +++ b/apps/dashboard/src/@/components/contracts/published-contract/index.tsx @@ -1,11 +1,6 @@ "use client"; -import { Divider, Flex, GridItem, List, ListItem } from "@chakra-ui/react"; import { useQuery } from "@tanstack/react-query"; -import { LinkButton } from "chakra/button"; -import { Card } from "chakra/card"; -import { Heading } from "chakra/heading"; -import { Text } from "chakra/text"; import { format } from "date-fns"; import { BookOpenTextIcon, @@ -26,15 +21,15 @@ import { MarkdownRenderer } from "@/components/blocks/markdown-renderer"; import type { PublishedContractWithVersion } from "@/components/contract-components/fetch-contracts-with-versions"; import { ContractFunctionsOverview } from "@/components/contracts/functions/contract-functions"; import { Button } from "@/components/ui/button"; -import { Separator } from "@/components/ui/separator"; import { usePublishedContractEvents, usePublishedContractFunctions, } from "@/hooks/contract-hooks"; import { correctAndUniqueLicenses } from "@/lib/licenses"; import { replaceIpfsUrl } from "@/lib/sdk"; +import { cn } from "@/lib/utils"; -interface ExtendedPublishedContract extends PublishedContractWithVersion { +type ExtendedPublishedContract = PublishedContractWithVersion & { name: string; displayName?: string; description?: string; @@ -43,19 +38,19 @@ interface ExtendedPublishedContract extends PublishedContractWithVersion { tags?: string[]; logo?: string; audit?: string; -} - -interface PublishedContractProps { - publishedContract: ExtendedPublishedContract; - isLoggedIn: boolean; - client: ThirdwebClient; -} +}; -export const PublishedContract: React.FC = ({ +export function PublishedContract({ publishedContract, isLoggedIn, client, -}) => { + className, +}: { + publishedContract: ExtendedPublishedContract; + isLoggedIn: boolean; + client: ThirdwebClient; + className?: string; +}) { const address = useActiveAccount()?.address; const contractFunctions = usePublishedContractFunctions(publishedContract); @@ -108,162 +103,181 @@ export const PublishedContract: React.FC = ({ ); return ( - <> - - - {address === publishedContract.publisher && ( - } - ml="auto" - size="sm" +
        + {/* left */} +
        + {address === publishedContract.publisher && ( +
        + +
        + )} - {publishedContract?.changelog && ( - - - {publishedContract?.version} Release Notes - - + {/* readme */} + {publishedContract?.readme && ( +
        + +
        + )} - -
        - )} - {contractFunctions && ( - +
        +

        + {publishedContract?.version} Release Notes +

        +
        + +
        + )} + + {contractFunctions && ( + + )} +
        + + {/* right */} +
        + {publishedContract.publisher && ( + + )} + +
        + +
          + {/* timestamp */} + {publishedContract.publishTimestamp && ( +
        • +
          + +
          +
          +
          + Publish Date +
          +

          + {publishDate} +

          +
          +
        • )} - - - - - {publishedContract.publisher && ( - + {/* audit */} + {publishedContract?.audit && ( +
        • +
          +
          + +
          +
          +
          + Audit Report +
          + + View Audit Report + + +
          +
          +
        • )} - + {/* license */} +
        • +
          + +
          +
          +
          + License{licenses.length > 1 ? "s" : ""} +
          +

          + {licenses.join(", ") || "None"} +

          +
          +
        • -
          -

          Details

          - - {publishedContract.publishTimestamp && ( - - - - - - Publish Date - - - {publishDate} - - - - - )} - {publishedContract?.audit && ( - - - - - - Audit Report - - - - View Audit Report - - - - - - )} - - - - - - License - {licenses.length > 1 ? "s" : ""} - - - {licenses.join(", ") || "None"} - - - - - {(publishedContract?.isDeployableViaProxy && - hasImplementationAddresses) || - (publishedContract?.isDeployableViaFactory && - hasFactoryAddresses) ? ( - - - - - - {publishedContract?.isDeployableViaFactory - ? "Factory" - : "Proxy"}{" "} - Enabled - - - - - ) : null} - -
          + {(publishedContract?.isDeployableViaProxy && + hasImplementationAddresses) || + (publishedContract?.isDeployableViaFactory && hasFactoryAddresses) ? ( +
        • +
          + +
          +
          + {publishedContract?.isDeployableViaFactory + ? "Factory" + : "Proxy"}{" "} + Enabled +
          +
        • + ) : null} +
        - +
        - - - - + +
        +
        ); -}; +} -// TODO: find a place to put this type ContractSource = { filename: string; source: string; }; + async function fetchSourceFilesFromMetadata( publishedMetadata: ExtendedPublishedContract, client: ThirdwebClient, diff --git a/apps/dashboard/src/@/utils/shareLink.ts b/apps/dashboard/src/@/utils/shareLink.ts deleted file mode 100644 index 5471b227127..00000000000 --- a/apps/dashboard/src/@/utils/shareLink.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { toast } from "sonner"; - -// if browser supports sharing use native sharing - use that, else just copy to clipboard + show toast -export async function shareLink(_data: ShareData) { - const data = { ..._data, url: _data.url || window.location.href }; - - if ( - "canShare" in navigator && - navigator.canShare && - navigator.canShare(data) - ) { - await navigator.share(data); - } else { - await navigator.clipboard.writeText(data.url); - toast.info("URL copied to clipboard"); - } -} diff --git a/apps/dashboard/src/app/(app)/(dashboard)/explore/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/explore/page.tsx index 7627635c64e..4309e08463c 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/explore/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/explore/page.tsx @@ -21,16 +21,20 @@ export const metadata: Metadata = { export default async function ExplorePage() { return (
        -
        -

        - Explore -

        -

        - The best place for web3 developers to explore smart contracts from - world-class web3 protocols & engineers — all deployable with one - click. -

        -
        +
        +
        +

        + Explore +

        +

        + The best place for web3 developers to explore smart contracts from + world-class web3 protocols & engineers — all deployable with one + click. +

        +
        +
        + +
        {EXPLORE_PAGE_DATA.map((category, idx) => ( @@ -42,7 +46,6 @@ export default async function ExplorePage() { ))}
        -
        diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx index a54fe3e4958..8f9e5d48405 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx @@ -1,16 +1,14 @@ -import { SimpleGrid } from "@chakra-ui/react"; -import { ChakraProviderSetup } from "chakra/ChakraProviderSetup"; import { notFound } from "next/navigation"; import { isAddress } from "thirdweb"; import { resolveAddress } from "thirdweb/extensions/ens"; import { getUserThirdwebClient } from "@/api/auth-token"; import { fetchPublishedContractVersions } from "@/components/contract-components/fetch-contracts-with-versions"; import { PublishedContract } from "@/components/contracts/published-contract"; -import { Separator } from "@/components/ui/separator"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { getRawAccount } from "../../../../../account/settings/getAccount"; import { PublishedActions } from "../../../components/contract-actions-published.client"; import { DeployContractHeader } from "../../../components/contract-header"; +import { PublishedContractBreadcrumbs } from "../components/breadcrumbs.client"; function mapThirdwebPublisher(publisher: string) { if (publisher === "thirdweb.eth") { @@ -75,28 +73,33 @@ export default async function PublishedContractPage( ]); return ( - <> - - +
        + +
        + +
        + - - - {/* TODO: remove the chakra things :) */} - - - + - - - + +
        + + +
        ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/components/breadcrumbs.client.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/components/breadcrumbs.client.tsx index 8f314800f91..85b7f0c1a99 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/components/breadcrumbs.client.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/components/breadcrumbs.client.tsx @@ -13,13 +13,14 @@ import { BreadcrumbPage, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; +import { cn } from "@/lib/utils"; -export function PublishedContractBreadcrumbs() { +export function PublishedContractBreadcrumbs(props: { className?: string }) { const pathname = usePathname() || ""; const segments = pathname.split("/").filter((segment) => segment !== ""); return ( - + diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/layout.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/layout.tsx index 7a453b8d398..954ce950a3c 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/layout.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/layout.tsx @@ -1,5 +1,4 @@ import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; -import { PublishedContractBreadcrumbs } from "./components/breadcrumbs.client"; import { getLatestPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping"; type Params = { publisher: string; contract_id: string }; @@ -8,12 +7,7 @@ export default function PublishedContractLayout(props: { children: React.ReactNode; params: Promise; }) { - return ( -
        - -
        {props.children}
        -
        - ); + return props.children; } export async function generateMetadata(props: { params: Promise }) { diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx index 4df049b4845..38869e0fdc3 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx @@ -1,13 +1,12 @@ -import { ChakraProviderSetup } from "chakra/ChakraProviderSetup"; import { notFound } from "next/navigation"; import { getAuthToken } from "@/api/auth-token"; import { PublishedContract } from "@/components/contracts/published-contract"; -import { Separator } from "@/components/ui/separator"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { getRawAccount } from "../../../../account/settings/getAccount"; import { PublishedActions } from "../../components/contract-actions-published.client"; import { DeployContractHeader } from "../../components/contract-header"; +import { PublishedContractBreadcrumbs } from "./components/breadcrumbs.client"; import { getPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping"; type PublishedContractDeployPageProps = { @@ -44,31 +43,36 @@ export default async function PublishedContractPage( ]); return ( - <> - - +
        + +
        + +
        + - - - {/* TODO: remove the chakra things :) */} - -
        - + -
        -
        - + +
        + + +
        ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-actions-published.client.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-actions-published.client.tsx index 07362f2ad47..84ef2fa1745 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-actions-published.client.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-actions-published.client.tsx @@ -1,10 +1,9 @@ "use client"; -import { ChevronsRightIcon } from "lucide-react"; +import { ArrowUpRightIcon } from "lucide-react"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { Button } from "@/components/ui/button"; -import { shareLink } from "@/utils/shareLink"; export function PublishedActions(props: { publisher: string; @@ -16,26 +15,13 @@ export function PublishedActions(props: { const stringifiedSearchParams = searchparams?.toString(); return ( -
        - - -
        + Deploy Now + + + ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-header.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-header.tsx index 0f1aabd6884..06b433c74fc 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-header.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-header.tsx @@ -1,5 +1,6 @@ import type { PropsWithChildren } from "react"; import type { PublishedContractWithVersion } from "@/components/contract-components/fetch-contracts-with-versions"; +import { cn } from "@/lib/utils"; import { ModuleList } from "../[publisher]/[contract_id]/components/module-list.client"; import { DeployContractInfo } from "./contract-info"; import { DeployContractVersionSelector } from "./version-selector"; @@ -10,14 +11,15 @@ type DeployContractHeaderProps = { version?: string; allVersions: PublishedContractWithVersion[]; activeVersion: PublishedContractWithVersion; + className?: string; }; export function DeployContractHeader( props: PropsWithChildren, ) { return ( -
        -
        +
        +
        - { - v.version) - .filter((v) => v !== undefined) || [] - } - version={props.activeVersion.version || "latest"} - /> - } + v.version) + .filter((v) => v !== undefined) || [] + } + version={props.activeVersion.version || "latest"} + /> {props.children}
        diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-info.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-info.tsx index 958bded9118..2476d8ec414 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-info.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/contract-info.tsx @@ -1,3 +1,5 @@ +import { FileTextIcon } from "lucide-react"; +import { Img } from "@/components/blocks/Img"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { resolveSchemeWithErrorHandler } from "@/utils/resolveSchemeWithErrorHandler"; @@ -15,22 +17,28 @@ export function DeployContractInfo(props: { }); return ( -
        -
        - {contractImageLink && ( -
        - {/*eslint-disable-next-line @next/next/no-img-element*/} - {props.name} -
        - )} - -
        -

        - {contractNameDisplay} -

        -

        {props.description}

        +
        +
        +
        + {props.name} + +
        + } + src={contractImageLink || ""} + />
        + +
        +

        + {contractNameDisplay} +

        +

        {props.description}

        +
        ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/publish-based-deploy.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/publish-based-deploy.tsx index 63289e485a7..877c609b88f 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/publish-based-deploy.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/publish-based-deploy.tsx @@ -7,6 +7,7 @@ import { } from "@/components/contract-components/fetch-contracts-with-versions"; import { ZERO_FEE_VERSIONS } from "@/constants/fee-config"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; +import { PublishedContractBreadcrumbs } from "../[publisher]/[contract_id]/components/breadcrumbs.client"; import { DeployContractHeader } from "./contract-header"; import { DeployFormForUri } from "./uri-based-deploy"; @@ -92,18 +93,28 @@ export async function DeployFormForPublishInfo(props: PublishBasedDeployProps) { ]); return ( -
        - - m !== null)} - pathname={`/${props.publisher}/${props.contract_id}${props.version ? `/${props.version}` : ""}/deploy`} - /> +
        +
        + +
        + +
        + +
        + +
        + m !== null)} + pathname={`/${props.publisher}/${props.contract_id}${props.version ? `/${props.version}` : ""}/deploy`} + /> +
        ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx index 7f4236152bd..16f8dcea766 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx @@ -1,4 +1,3 @@ -import { ChakraProviderSetup } from "chakra/ChakraProviderSetup"; import type { FetchDeployMetadataResult } from "thirdweb/contract"; import { getUserThirdwebClient } from "@/api/auth-token"; import { getProjects } from "@/api/projects"; @@ -48,17 +47,14 @@ export async function DeployFormForUri(props: DeployFormForUriProps) { })), ); - // TODO: remove the `ChakraProviderSetup` wrapper once the form is updated to no longer use chakra return ( - - m !== null)} - teamsAndProjects={teamsAndProjects} - /> - + m !== null)} + teamsAndProjects={teamsAndProjects} + /> ); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/version-selector.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/version-selector.tsx index 0bda2c1d3f0..3c257d8a2c2 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/version-selector.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/version-selector.tsx @@ -57,7 +57,7 @@ export function DeployContractVersionSelector({ }} value={version} > - +