From 73ae5817f2fe35220b9d8fd943a92d77fe570a2c Mon Sep 17 00:00:00 2001 From: MananTank Date: Wed, 2 Apr 2025 09:12:31 +0000 Subject: [PATCH] [TOOL-3763] Dashboard: Update Contracts page (#6611) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ## PR-Codex overview This PR focuses on enhancing the user interface and functionality of the contracts management section. It introduces new components and modifies existing ones to improve user experience, particularly around contract deployment and management. ### Detailed summary - Removed the `GetStartedWithContractsDeploy` component. - Added `DeployViaCLIOrImportCard` component for contract deployment options. - Updated the `DeployedContractsPage` to include the new `DeployViaCLIOrImportCard`. - Modified the `ContractTableUI` to display a message and button when no contracts are present. - Increased the height of the no contracts message section. - Added a link to discover contracts with an external icon. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- .../contracts/DeployedContractsPageHeader.tsx | 2 +- .../_components/DeployViaCLIOrImportCard.tsx | 56 +++++++ .../_components/DeployedContractsPage.tsx | 16 +- .../GetStartedWithContractsDeploy.tsx | 139 ------------------ .../tables/contract-table.tsx | 15 +- 5 files changed, 75 insertions(+), 153 deletions(-) create mode 100644 apps/dashboard/src/app/account/contracts/_components/DeployViaCLIOrImportCard.tsx delete mode 100644 apps/dashboard/src/app/account/contracts/_components/GetStartedWithContractsDeploy.tsx diff --git a/apps/dashboard/src/app/account/contracts/DeployedContractsPageHeader.tsx b/apps/dashboard/src/app/account/contracts/DeployedContractsPageHeader.tsx index 582b934c904..5f39132cb32 100644 --- a/apps/dashboard/src/app/account/contracts/DeployedContractsPageHeader.tsx +++ b/apps/dashboard/src/app/account/contracts/DeployedContractsPageHeader.tsx @@ -23,7 +23,7 @@ export function DeployedContractsPageHeader(props: { projectId={props.projectId} /> -
+

Contracts

diff --git a/apps/dashboard/src/app/account/contracts/_components/DeployViaCLIOrImportCard.tsx b/apps/dashboard/src/app/account/contracts/_components/DeployViaCLIOrImportCard.tsx new file mode 100644 index 00000000000..52e86570066 --- /dev/null +++ b/apps/dashboard/src/app/account/contracts/_components/DeployViaCLIOrImportCard.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { ArrowUpRightIcon, DownloadIcon } from "lucide-react"; +import Link from "next/link"; +import { useState } from "react"; +import { ImportModal } from "../../../../components/contract-components/import-contract/modal"; + +export function DeployViaCLIOrImportCard(props: { + teamId: string; + projectId: string; +}) { + const [importModalOpen, setImportModalOpen] = useState(false); + + return ( +
+ { + setImportModalOpen(false); + }} + teamId={props.teamId} + projectId={props.projectId} + /> + +

+ Already have a smart contract? +

+

+ Import an already deployed contract or deploy a contract from source + code to easily manage permissions, upload assets, and interact with + contract functions +

+ +
+ + +
+
+ ); +} diff --git a/apps/dashboard/src/app/account/contracts/_components/DeployedContractsPage.tsx b/apps/dashboard/src/app/account/contracts/_components/DeployedContractsPage.tsx index 5c0dd8acb0a..2f64bd51f62 100644 --- a/apps/dashboard/src/app/account/contracts/_components/DeployedContractsPage.tsx +++ b/apps/dashboard/src/app/account/contracts/_components/DeployedContractsPage.tsx @@ -3,7 +3,7 @@ import { ClientOnly } from "components/ClientOnly/ClientOnly"; import { Suspense } from "react"; import { ContractTable } from "../../../../components/contract-components/tables/contract-table"; import { DeployedContractsPageHeader } from "../DeployedContractsPageHeader"; -import { GetStartedWithContractsDeploy } from "./GetStartedWithContractsDeploy"; +import { DeployViaCLIOrImportCard } from "./DeployViaCLIOrImportCard"; import { getSortedDeployedContracts } from "./getSortedDeployedContracts"; export function DeployedContractsPage(props: { @@ -21,6 +21,11 @@ export function DeployedContractsPage(props: { }> +
+
); @@ -37,15 +42,6 @@ async function DeployedContractsPageAsync(props: { authToken: props.authToken, }); - if (deployedContracts.length === 0) { - return ( - - ); - } - return ( }> [ - { - title: "Build, deploy or import a contract", - description: - "Choose between deploying your own contract or import an existing one.", - children: ( - - ), - completed: false, // because we only show this component if the user does not have any contracts - }, - ], - [props.teamId, props.projectId], - ); - - return ( - - ); -} - -type ContentItem = { - title: string; - description: string; - href?: string; - onClick?: () => void; -}; - -type TabId = "explore" | "import" | "build" | "deploy"; - -const DeployOptions = (props: { - teamId: string; - projectId: string; -}) => { - const [showImportModal, setShowImportModal] = useState(false); - const router = useDashboardRouter(); - const trackEvent = useTrack(); - - const content: Record = useMemo( - () => ({ - explore: { - title: "Ready-to-deploy", - description: - "Pick from our library of ready-to-deploy contracts and deploy to any EVM chain in just 1-click.", - href: "/explore", - }, - import: { - title: "Import", - description: - "Import an already deployed contract to build apps on top of contract using thirdweb tools.", - onClick: () => setShowImportModal(true), - }, - build: { - title: "Build your own", - description: - "Get started with the Solidity SDK to create custom contracts specific to your use case.", - href: "/build", - }, - deploy: { - title: "Deploy from source", - description: - "Deploy your contract by using our interactive CLI. (Supports Hardhat, Forge, Truffle, and more)", - href: "https://portal.thirdweb.com/cli", - }, - }), - [], - ); - - const [activeTab, setActiveTab] = useState("explore"); - const activeTabContent = content[activeTab]; - - return ( -
- { - setShowImportModal(false); - }} - teamId={props.teamId} - projectId={props.projectId} - /> - - ({ - key, - name: value.title, - isActive: activeTab === key, - onClick: () => setActiveTab(key as TabId), - }))} - tabClassName="font-medium" - tabContainerClassName="gap-1" - /> - - -
- ); -}; diff --git a/apps/dashboard/src/components/contract-components/tables/contract-table.tsx b/apps/dashboard/src/components/contract-components/tables/contract-table.tsx index e3de6027ed4..ab796fd688b 100644 --- a/apps/dashboard/src/components/contract-components/tables/contract-table.tsx +++ b/apps/dashboard/src/components/contract-components/tables/contract-table.tsx @@ -22,7 +22,8 @@ import { import { useMutation } from "@tanstack/react-query"; import { ChainIcon } from "components/icons/ChainIcon"; import { NetworkSelectDropdown } from "components/selects/NetworkSelectDropdown"; -import { EllipsisVerticalIcon, XIcon } from "lucide-react"; +import { EllipsisVerticalIcon, ExternalLinkIcon, XIcon } from "lucide-react"; +import Link from "next/link"; import { useCallback, useEffect, useMemo, useState } from "react"; import React from "react"; import { toast } from "sonner"; @@ -202,8 +203,16 @@ export function ContractTableUI(props: { {contracts.length === 0 && ( -
- No Contracts +
+
+

No contracts added to project

+ +
)}