diff --git a/apps/dashboard/redirects.js b/apps/dashboard/redirects.js index 39517d59761..b8e2f83154c 100644 --- a/apps/dashboard/redirects.js +++ b/apps/dashboard/redirects.js @@ -62,6 +62,56 @@ const legacyDashboardToTeamRedirects = [ }, ]; +const projectRoute = "/team/:team_slug/:project_slug"; + +const projectPageRedirects = [ + { + destination: `${projectRoute}/universal-bridge/:path*`, + permanent: false, + source: `${projectRoute}/connect/pay/:path*`, + }, + { + destination: `${projectRoute}/universal-bridge/:path*`, + permanent: false, + source: `${projectRoute}/connect/universal-bridge/:path*`, + }, + { + destination: `${projectRoute}/account-abstraction/:path*`, + permanent: false, + source: `${projectRoute}/connect/account-abstraction/:path*`, + }, + { + destination: `${projectRoute}/wallets/:path*`, + permanent: false, + source: `${projectRoute}/connect/in-app-wallets/:path*`, + }, + { + destination: `${projectRoute}/vault/:path*`, + permanent: false, + source: `${projectRoute}/engine/cloud/vault/:path*`, + }, + { + destination: `${projectRoute}/transactions/:path*`, + permanent: false, + source: `${projectRoute}/engine/cloud/:path*`, + }, + { + destination: `${projectRoute}/tokens/:path*`, + permanent: false, + source: `${projectRoute}/assets/:path*`, + }, + { + destination: projectRoute, + permanent: false, + source: `${projectRoute}/nebula/:path*`, + }, + { + source: `${projectRoute}/connect/analytics`, + destination: `${projectRoute}`, + permanent: false, + }, +]; + /** @type {import('next').NextConfig['redirects']} */ async function redirects() { return [ @@ -326,14 +376,6 @@ async function redirects() { permanent: false, source: "/unlimited-wallets", }, - // pay > universal-bridge redirect - { - destination: - "/team/:team_slug/:project_slug/connect/universal-bridge/:path*", - permanent: false, - source: "/team/:team_slug/:project_slug/connect/pay/:path*", - }, - // all /learn/tutorials (and sub-routes) -> /learn/guides { destination: "/learn/guides/:path*", @@ -382,8 +424,8 @@ async function redirects() { permanent: false, source: "/engine", }, - ...legacyDashboardToTeamRedirects, + ...projectPageRedirects, ]; } diff --git a/apps/dashboard/src/@/analytics/report.ts b/apps/dashboard/src/@/analytics/report.ts index faf869a1e7f..88d9613318a 100644 --- a/apps/dashboard/src/@/analytics/report.ts +++ b/apps/dashboard/src/@/analytics/report.ts @@ -10,7 +10,7 @@ import type { Team } from "../api/team"; * ### Why do we need to report this event? * - To track the number of contracts deployed * - To track the number of contracts deployed on each chain - * - To track if the contract was deployed on the asset page vs on the deploy page + * - To track if the contract was deployed on the token page vs on the deploy page * * ### Who is responsible for this event? * @jnsdls @@ -226,7 +226,7 @@ type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721"; /** * ### Why do we need to report this event? - * - To track number of successful asset purchases from the asset page + * - To track number of successful asset purchases from the token page * - To track which asset and contract types are being purchased the most * * ### Who is responsible for this event? @@ -246,7 +246,7 @@ export function reportAssetBuySuccessful(properties: { /** * ### Why do we need to report this event? - * - To track number of failed asset purchases from the asset page + * - To track number of failed asset purchases from the token page * - To track the errors that users encounter when trying to purchase an asset * * ### Who is responsible for this event? diff --git a/apps/dashboard/src/@/components/blocks/Sidebar.tsx b/apps/dashboard/src/@/components/blocks/Sidebar.tsx index 2342f2e6328..d8d22fd0043 100644 --- a/apps/dashboard/src/@/components/blocks/Sidebar.tsx +++ b/apps/dashboard/src/@/components/blocks/Sidebar.tsx @@ -9,6 +9,7 @@ export type SidebarBaseLink = { label: React.ReactNode; exactMatch?: boolean; icon?: React.FC<{ className?: string }>; + isActive?: (pathname: string) => boolean; }; export type SidebarLink = diff --git a/apps/dashboard/src/@/components/blocks/SidebarLayout.tsx b/apps/dashboard/src/@/components/blocks/SidebarLayout.tsx index e87ae95ac84..7f85ee9fade 100644 --- a/apps/dashboard/src/@/components/blocks/SidebarLayout.tsx +++ b/apps/dashboard/src/@/components/blocks/SidebarLayout.tsx @@ -123,6 +123,7 @@ function RenderSidebarGroup(props: { className="flex items-center gap-2 text-muted-foreground text-sm hover:bg-accent" exactMatch={link.exactMatch} href={link.href} + isActive={link.isActive} onClick={() => { sidebar.setOpenMobile(false); }} diff --git a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx index f87a31876d8..f689dba3afe 100644 --- a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx +++ b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx @@ -17,8 +17,6 @@ function Story() { description="Upgrade to increase limits and access advanced features." icon={} title="Unlock more with thirdweb" - trackingCategory="storybook" - trackingLabel="green" /> @@ -33,8 +31,6 @@ function Story() { description="Add additional space to your account." icon={} title="Need more storage?" - trackingCategory="storybook" - trackingLabel="blue" /> @@ -48,8 +44,6 @@ function Story() { }} description="Get early access to experimental features." title="Join the beta" - trackingCategory="storybook" - trackingLabel="purple" /> diff --git a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx index 8188c02dbe5..9050c2854de 100644 --- a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx +++ b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx @@ -44,8 +44,6 @@ type UpsellBannerCardProps = { target?: "_blank"; link: string; }; - trackingCategory: string; - trackingLabel: string; accentColor?: keyof typeof ACCENT; icon?: React.ReactNode; }; diff --git a/apps/dashboard/src/@/components/ui/NavLink.tsx b/apps/dashboard/src/@/components/ui/NavLink.tsx index 0f6509855f7..61eaeb88696 100644 --- a/apps/dashboard/src/@/components/ui/NavLink.tsx +++ b/apps/dashboard/src/@/components/ui/NavLink.tsx @@ -10,15 +10,18 @@ export type NavButtonProps = { href: string; exactMatch?: boolean; onClick?: () => void; + isActive?: (pathname: string) => boolean; }; export function NavLink(props: React.PropsWithChildren) { const pathname = usePathname(); - const isActive = pathname - ? props.exactMatch - ? pathname === props.href - : pathname.startsWith(props.href) - : false; + const isActive = props.isActive + ? props.isActive(pathname) + : pathname + ? props.exactMatch + ? pathname === props.href + : pathname.startsWith(props.href) + : false; return ( = ({ rel="noopener noreferrer" target="_blank" > - View Asset Page + View Token Page ); diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx index c3b99560076..08876f4d464 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx @@ -50,12 +50,10 @@ export const ContractOverviewPage: React.FC = ({ icon: , link: `/${chainSlug}/${contract.address}`, target: "_blank", - text: "View asset page", + text: "View token page", }} - description="A public page is available for this contract for anyone to buy this asset" - title="Public asset page available" - trackingCategory="erc20-contract" - trackingLabel="view-asset-page" + description="A public page is available for this contract for anyone to buy this token" + title="Public token page available" /> )} diff --git a/apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx b/apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx index c2ad310d83c..d5cc4efeaee 100644 --- a/apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx +++ b/apps/dashboard/src/app/(app)/account/contracts/DeployedContractsPageHeader.tsx @@ -15,7 +15,7 @@ export function DeployedContractsPageHeader(props: { const [importModalOpen, setImportModalOpen] = useState(false); return ( -
+
-
+
-

+

Contracts

+

+ Deploy and manage contracts for your project +

- @@ -225,8 +225,8 @@ export function EngineInstancesTableUI(props: { projectSlug: string; }) { return ( -
-
+
+

Engine Instances

diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/engine-overview.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/engine-overview.tsx index 5d99cd6f674..831ef4a5e8f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/engine-overview.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/engine-overview.tsx @@ -142,6 +142,7 @@ function BackendWalletsSection(props: { chainId={chainId} className="min-w-40 max-w-52 lg:max-w-60" client={props.client} + disableChainId onChange={setChainId} popoverContentClassName="!w-[80vw] md:!w-[500px]" /> diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx index 8a5638a65c0..adbbd605cfa 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx @@ -1,12 +1,12 @@ -import { AnnouncementBanner } from "components/notices/AnnouncementBanner"; import Link from "next/link"; import { redirect } from "next/navigation"; -import { getProject, getProjects } from "@/api/projects"; +import { getProject, getProjects, type Project } from "@/api/projects"; import { getTeamBySlug, getTeams } from "@/api/team"; import { Button } from "@/components/ui/button"; import { SidebarProvider } from "@/components/ui/sidebar"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { CustomChatButton } from "../../../../../../components/CustomChat/CustomChatButton"; +import { AnnouncementBanner } from "../../../../../../components/notices/AnnouncementBanner"; import { siwaExamplePrompts } from "../../../../(dashboard)/support/definitions"; import { getValidAccount } from "../../../../account/settings/getAccount"; import { @@ -16,6 +16,7 @@ import { import { TeamHeaderLoggedIn } from "../../../components/TeamHeader/team-header-logged-in.client"; import { ProjectSidebarLayout } from "./components/ProjectSidebarLayout"; import { SaveLastUsedProject } from "./components/SaveLastUsedProject"; +import { getEngineInstances } from "./engine/dedicated/_utils/getEngineInstances"; export default async function ProjectLayout(props: { children: React.ReactNode; @@ -59,6 +60,11 @@ export default async function ProjectLayout(props: { teamId: team.id, }); + const engineLinkType = await getEngineLinkType({ + authToken, + project, + }); + return (
@@ -88,7 +94,10 @@ export default async function ProjectLayout(props: { teamsAndProjects={teamsAndProjects} />
- + {props.children}
@@ -109,3 +118,30 @@ export default async function ProjectLayout(props: { ); } + +async function getEngineLinkType(params: { + authToken: string; + project: Project; +}) { + const projectEngineCloudService = params.project.services.find( + (service) => service.name === "engineCloud", + ); + + const engineCloudToken = projectEngineCloudService?.managementAccessToken; + + // if we have a management access token, link to engine cloud page + let engineLinkType: "cloud" | "dedicated" = "cloud"; + + // if we don't have a engine cloud management access token, check if there are any legacy engine instances + if (!engineCloudToken) { + const engineInstances = await getEngineInstances({ + authToken: params.authToken, + teamIdOrSlug: params.project.teamId, + }); + // if we have any legacy engine instances, link to the legacy engine page + if (engineInstances.data && engineInstances.data.length > 0) { + engineLinkType = "dedicated"; + } + } + return engineLinkType; +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx deleted file mode 100644 index 8a25dfaf227..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import "server-only"; -import { unstable_cache } from "next/cache"; -import { ANALYTICS_SERVICE_URL } from "@/constants/server-envs"; - -export type NebulaAnalyticsDataItem = { - date: string; - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; -}; - -export const fetchNebulaAnalytics = unstable_cache( - async (params: { - teamId: string; - projectId: string; - authToken: string; - from: string; - to: string; - period: "day" | "week" | "month" | "year" | "all"; - }) => { - const analyticsEndpoint = ANALYTICS_SERVICE_URL; - const url = new URL(`${analyticsEndpoint}/v2/nebula/usage`); - url.searchParams.set("teamId", params.teamId); - url.searchParams.set("projectId", params.projectId); - url.searchParams.set("from", params.from); - url.searchParams.set("to", params.to); - url.searchParams.set("period", params.period); - - const res = await fetch(url, { - headers: { - Authorization: `Bearer ${params.authToken}`, - }, - }); - - if (!res.ok) { - const error = await res.text(); - return { - error: error, - ok: false as const, - }; - } - - const resData = await res.json(); - - return { - data: resData.data as NebulaAnalyticsDataItem[], - ok: true as const, - }; - }, - ["nebula-analytics"], - { - revalidate: 60 * 60, // 1 hour - }, -); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx deleted file mode 100644 index 020e15a3fbb..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx +++ /dev/null @@ -1,51 +0,0 @@ -"use client"; - -import { DateRangeSelector } from "components/analytics/date-range-selector"; -import { IntervalSelector } from "components/analytics/interval-selector"; -import { getNebulaFiltersFromSearchParams } from "lib/time"; -import { - useResponsiveSearchParams, - useSetResponsiveSearchParams, -} from "responsive-rsc"; -import { normalizeTimeISOString } from "@/lib/time"; - -export function NebulaAnalyticsFilter() { - const responsiveSearchParams = useResponsiveSearchParams(); - const setResponsiveSearchParams = useSetResponsiveSearchParams(); - - const { range, interval } = getNebulaFiltersFromSearchParams({ - from: responsiveSearchParams.from, - interval: responsiveSearchParams.interval, - to: responsiveSearchParams.to, - }); - - return ( -
- { - setResponsiveSearchParams((v) => { - return { - ...v, - from: normalizeTimeISOString(newRange.from), - to: normalizeTimeISOString(newRange.to), - }; - }); - }} - /> - - { - setResponsiveSearchParams((v) => { - return { - ...v, - interval: newInterval, - }; - }); - }} - /> -
- ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx deleted file mode 100644 index 898a3792edf..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { FileCode2Icon, MessageSquareQuoteIcon } from "lucide-react"; -import Link from "next/link"; -import { - ResponsiveSearchParamsProvider, - ResponsiveSuspense, -} from "responsive-rsc"; -import { Button } from "@/components/ui/button"; -import { normalizeTimeISOString } from "@/lib/time"; -import { fetchNebulaAnalytics } from "./fetch-nebula-analytics"; -import { NebulaAnalyticsFilter } from "./nebula-analytics-filter"; -import { NebulaAnalyticsDashboardUI } from "./nebula-analytics-ui"; -import { getNebulaAnalyticsRangeFromSearchParams } from "./utils"; - -export function NebulaAnalyticsPage(props: { - searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }; - teamId: string; - authToken: string; - projectId: string; -}) { - return ( - -
-
-

Nebula

- -
- - - -
-
-
- -
-
-

Analytics

- -
- } - searchParamsUsed={["from", "to", "interval"]} - > - - -
-
- ); -} - -async function NebulaAnalyticDashboard(props: { - teamId: string; - authToken: string; - projectId: string; - searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }; -}) { - const { range, interval } = getNebulaAnalyticsRangeFromSearchParams( - props.searchParams, - ); - - const res = await fetchNebulaAnalytics({ - authToken: props.authToken, - from: normalizeTimeISOString(range.from), - // internally renamed - period: interval, - projectId: props.projectId, - teamId: props.teamId, - to: normalizeTimeISOString(range.to), - }); - - if (!res.ok) { - return ( -
-
-

- Failed to fetch Nebula analytics -

-

{res.error}

-
-
- ); - } - - return ; -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx deleted file mode 100644 index df9cc2aeed7..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/nextjs"; -import { subDays } from "date-fns"; -import type { NebulaAnalyticsDataItem } from "./fetch-nebula-analytics"; -import { NebulaAnalyticsDashboardUI } from "./nebula-analytics-ui"; - -const meta = { - component: NebulaAnalyticsDashboardUI, - decorators: [ - (Story) => ( -
- -
- ), - ], - parameters: { - nextjs: { - appDirectory: true, - }, - }, - title: "Nebula/Analytics", -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const SixtyDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(60), - isPending: false, - }, -}; - -export const ThirtyDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(30), - isPending: false, - }, -}; - -export const SevenDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(7), - isPending: false, - }, -}; - -export const Pending: Story = { - args: { - data: [], - isPending: true, - }, -}; - -function generateRandomNebulaAnalyticsData( - days: number, -): NebulaAnalyticsDataItem[] { - return Array.from({ length: days }, (_, i) => ({ - date: subDays(new Date(), i).toISOString(), - totalCompletionTokens: randomInt(1000, 2000 + i * 100), - totalPromptTokens: randomInt(500, 700 + i * 100), - totalRequests: randomInt(4000, 5000 + i * 100), - totalSessions: randomInt(400, 1000 + i * 100), - })); -} - -function randomInt(min: number, max: number) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx deleted file mode 100644 index 15a556e1444..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx +++ /dev/null @@ -1,203 +0,0 @@ -"use client"; - -import { format } from "date-fns"; -import { - ActivityIcon, - MessageCircleQuestionIcon, - MessageSquareIcon, - MessageSquareQuoteIcon, -} from "lucide-react"; -import { useMemo } from "react"; -import { ThirdwebAreaChart } from "@/components/blocks/charts/area-chart"; -import { SkeletonContainer } from "@/components/ui/skeleton"; -import type { NebulaAnalyticsDataItem } from "./fetch-nebula-analytics"; - -type ChartData = { - time: Date; - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; -}; - -type AnalyticsChartProps = { - data: ChartData[]; - isPending: boolean; - title: string; - description: string; - dataKey: keyof ChartData; - color: string; -}; - -function AnalyticsChart({ - data, - isPending, - title, - description, - dataKey, - color, -}: AnalyticsChartProps) { - return ( - ({ - ...item, - time: item.time.getTime(), - }))} - header={{ - description, - title, - titleClassName: "text-xl mb-1", - }} - hideLabel={false} - isPending={isPending} - toolTipLabelFormatter={toolTipLabelFormatter} - /> - ); -} - -export function NebulaAnalyticsDashboardUI(props: { - data: NebulaAnalyticsDataItem[]; - isPending: boolean; -}) { - const data = useMemo(() => { - const val: { - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; - chartData: ChartData[]; - } = { - chartData: [], - totalCompletionTokens: 0, - totalPromptTokens: 0, - totalRequests: 0, - totalSessions: 0, - }; - - for (const item of props.data) { - val.totalPromptTokens += item.totalPromptTokens; - val.totalCompletionTokens += item.totalCompletionTokens; - val.totalSessions += item.totalSessions; - val.totalRequests += item.totalRequests; - val.chartData.push({ - time: new Date(item.date), - totalCompletionTokens: item.totalCompletionTokens, - totalPromptTokens: item.totalPromptTokens, - totalRequests: item.totalRequests, - totalSessions: item.totalSessions, - }); - } - - return val; - }, [props.data]); - - return ( -
-
- - - - -
- -
- -
- - - - - - - -
-
- ); -} - -function toolTipLabelFormatter(_v: string, item: unknown) { - if (Array.isArray(item)) { - const time = item[0].payload.time as number; - return format(new Date(time), "MMM d, yyyy"); - } - return undefined; -} - -function StatCard(props: { - title: string; - value: number; - icon: React.FC<{ className?: string }>; - isPending: boolean; -}) { - return ( -
-
-

{props.title}

- -
- ( -

{v}

- )} - skeletonData={10000} - /> -
- ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts deleted file mode 100644 index a96c4d4216c..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getNebulaFiltersFromSearchParams } from "lib/time"; - -export function getNebulaAnalyticsRangeFromSearchParams(searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; -}) { - return getNebulaFiltersFromSearchParams({ - from: searchParams.from, - interval: searchParams.interval, - to: searchParams.to, - }); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx deleted file mode 100644 index a5bc9dd34f0..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { FooterLinksSection } from "../components/footer/FooterLinksSection"; - -export default function Layout(props: { children: React.ReactNode }) { - return ( -
-
{props.children}
-
-
-
- -
-
-
- ); -} - -function NebulaFooter() { - return ( - - ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx deleted file mode 100644 index 10e9d94264c..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { CodeServer } from "@/components/ui/code/code.server"; -import { SecretKeySection } from "../components/ProjectFTUX/SecretKeySection"; -import { WaitingForIntegrationCard } from "../components/WaitingForIntegrationCard/WaitingForIntegrationCard"; - -export function NebulaFTUX(props: { - secretKeyMasked: string; - teamId: string; - projectId: string; -}) { - return ( - - ), - label: "JavaScript", - }, - { - code: ( - - ), - label: "Python", - }, - { - code: ( - - ), - label: "Curl", - }, - ]} - ctas={[ - { - href: "https://nebula.thirdweb.com/", - label: "Try on Playground", - }, - { - href: "https://portal.thirdweb.com/nebula", - label: "View Docs", - }, - ]} - title="Integrate Nebula" - > - -
- - ); -} - -const jsCode = `\ -// Example: Send message to Nebula -// Replace PROJECT_SECRET_KEY with your project's full secret key - -const res = await fetch("https://nebula-api.thirdweb.com/chat", { - method: "POST", - headers: { - "x-secret-key": "PROJECT_SECRET_KEY", - }, - body: { - message: "Hello", - stream: false, - }, -}); - -const data = await res.json(); -`; - -const curlCode = `\ -# Example: Send message to Nebula -# Replace PROJECT_SECRET_KEY with your project's full secret key - -curl -X POST https://nebula-api.thirdweb.com/chat \ --H "x-secret-key:PROJECT_SECRET_KEY" \ --d '{ - "message": "Hello", - "stream": false, -}' -`; - -const pythonCode = `\ -# Example: Send message to Nebula -# Replace PROJECT_SECRET_KEY with your project's full secret key - -import requests - -response = requests.post("https://nebula-api.thirdweb.com/chat", headers={ - "x-secret-key": "PROJECT_SECRET_KEY" -}, json={ - "message": "Hello", - "stream": False, -}) - -data = response.json() -`; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx deleted file mode 100644 index 0cd59a39315..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { redirect } from "next/navigation"; -import { isProjectActive } from "@/api/analytics"; -import { getProject } from "@/api/projects"; -import { getTeamBySlug } from "@/api/team"; -import { getAuthToken } from "../../../../../api/lib/getAuthToken"; -import { loginRedirect } from "../../../../../login/loginRedirect"; -import { NebulaAnalyticsPage } from "./components/analytics/nebula-analytics-page"; -import { NebulaFTUX } from "./nebula-ftux"; - -export default async function Page(props: { - params: Promise<{ - team_slug: string; - project_slug: string; - }>; - searchParams: Promise<{ - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }>; -}) { - const [params, searchParams] = await Promise.all([ - props.params, - props.searchParams, - ]); - - const [authToken, team, project] = await Promise.all([ - getAuthToken(), - getTeamBySlug(params.team_slug), - getProject(params.team_slug, params.project_slug), - ]); - - if (!team) { - redirect("/team"); - } - - if (!project) { - redirect(`/team/${params.team_slug}`); - } - - if (!authToken) { - loginRedirect(`/team/${params.team_slug}/${params.project_slug}/nebula`); - } - - const activeResponse = await isProjectActive({ - projectId: project.id, - teamId: team.id, - }); - - const showFTUX = !activeResponse.nebula; - - if (showFTUX) { - return ( -
-
-
-

Nebula

-
-
- -
- -
-
- ); - } - - return ( - - ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx index 5617962bb6f..37d4ea5b6e1 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx @@ -221,10 +221,10 @@ export function ProjectGeneralSettingsPageUI(props: { const projectLayout = `/team/${props.teamSlug}/${props.project.slug}`; const paths = { - aaConfig: `${projectLayout}/connect/account-abstraction/settings`, + aaConfig: `${projectLayout}/account-abstraction/settings`, afterDeleteRedirectTo: `/team/${props.teamSlug}`, - inAppConfig: `${projectLayout}/connect/in-app-wallets/settings`, - payConfig: `${projectLayout}/connect/universal-bridge/settings`, + inAppConfig: `${projectLayout}/wallets/settings`, + payConfig: `${projectLayout}/universal-bridge/settings`, }; const { project } = props; @@ -762,7 +762,7 @@ function EnabledServicesSetting(props: { return (
{/* Left */} @@ -780,7 +780,7 @@ function EnabledServicesSetting(props: {
); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/PageHeader.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/PageHeader.tsx similarity index 97% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/PageHeader.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/PageHeader.tsx index 8a360dd866b..b539141d69b 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/PageHeader.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/PageHeader.tsx @@ -24,9 +24,9 @@ export function CreateAssetPageHeader(props: { - Assets + Tokens diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/chain-overview.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/chain-overview.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/chain-overview.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/chain-overview.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/download-file-button.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/download-file-button.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/download-file-button.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/download-file-button.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/file-preview.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/file-preview.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/file-preview.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/file-preview.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/schema.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/schema.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/schema.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/schema.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/step-card.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/step-card.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/step-card.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/step-card.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/_common/form.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/_common/form.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/_common/form.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/_common/form.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/_common/pages.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/_common/pages.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/_common/pages.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/_common/pages.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/collection-info/nft-collection-info-fieldset.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/collection-info/nft-collection-info-fieldset.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/collection-info/nft-collection-info-fieldset.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/collection-info/nft-collection-info-fieldset.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page-ui.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page-ui.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx index ce23253e178..c15bceaa91f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx @@ -374,7 +374,7 @@ export function CreateNFTPage(props: { }} onLaunchSuccess={() => { revalidatePathAction( - `/team/${props.teamSlug}/project/${props.projectSlug}/assets`, + `/team/${props.teamSlug}/project/${props.projectSlug}/tokens`, "page", ); }} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/page.tsx similarity index 96% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/page.tsx index ea98b963ada..4880b9039e1 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/page.tsx @@ -24,7 +24,7 @@ export default async function Page(props: { if (!authToken || !accountAddress) { loginRedirect( - `/team/${params.team_slug}/${params.project_slug}/assets/create/nft`, + `/team/${params.team_slug}/${params.project_slug}/tokens/create/nft`, ); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/sales/sales-settings.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/sales/sales-settings.tsx similarity index 97% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/sales/sales-settings.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/sales/sales-settings.tsx index 98733109378..07358dcf99a 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/sales/sales-settings.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/sales/sales-settings.tsx @@ -37,7 +37,7 @@ export function SalesSettings(props: {

Primary Sales

Set the wallet address that should receive the revenue from - initial sales of the assets + initial sales of the tokens

Royalties

Set the wallet address should receive the revenue from royalties - earned from secondary sales of the assets + earned from secondary sales of the tokens

@@ -70,7 +70,7 @@ export function SalesSettings(props: { helperText={ <> The wallet address that should receive the revenue from - royalties earned from secondary sales of the assets. + royalties earned from secondary sales of the tokens. } isRequired diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-instructions.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/batch-upload-instructions.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-instructions.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/batch-upload-instructions.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-nfts.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/batch-upload-nfts.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-nfts.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/batch-upload-nfts.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/process-files.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/process-files.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/process-files.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/batch-upload/process-files.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/schema.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/schema.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/schema.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/schema.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/single-upload/attributes.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/single-upload/attributes.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/single-upload-nft.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/single-upload/single-upload-nft.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/single-upload-nft.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/single-upload/single-upload-nft.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.stories.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/upload-nfts.stories.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.stories.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/upload-nfts.stories.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/upload-nfts.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/upload-nfts/upload-nfts.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/_common/form.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/_common/form.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/_common/form.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/_common/form.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx index 4c86b81ddae..f99523f27f4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx @@ -342,7 +342,7 @@ export function CreateTokenAssetPage(props: { }} onLaunchSuccess={() => { revalidatePathAction( - `/team/${props.teamSlug}/project/${props.projectId}/assets`, + `/team/${props.teamSlug}/project/${props.projectId}/tokens`, "page", ); }} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.stories.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.stories.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.stories.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.stories.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-airdrop.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-airdrop.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-airdrop.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-airdrop.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-distribution.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-distribution.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-distribution.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-distribution.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-sale.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-sale.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/distribution/token-sale.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-sale.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/page.tsx similarity index 89% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/page.tsx index 2b5a0a94b3a..c2b36a810e4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/page.tsx @@ -1,12 +1,12 @@ +import { + getAuthToken, + getAuthTokenWalletAddress, +} from "@app/api/lib/getAuthToken"; +import { loginRedirect } from "@app/login/loginRedirect"; import { redirect } from "next/navigation"; import { getProject } from "@/api/projects"; import { getTeamBySlug } from "@/api/team"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; -import { - getAuthToken, - getAuthTokenWalletAddress, -} from "../../../../../../../api/lib/getAuthToken"; -import { loginRedirect } from "../../../../../../../login/loginRedirect"; import { CreateAssetPageHeader } from "../_common/PageHeader"; import { CreateTokenAssetPage } from "./create-token-page-impl"; @@ -24,7 +24,7 @@ export default async function Page(props: { if (!authToken || !accountAddress) { loginRedirect( - `/team/${params.team_slug}/${params.project_slug}/assets/create/token`, + `/team/${params.team_slug}/${params.project_slug}/tokens/create/token`, ); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/token-info/token-info-fieldset.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/token-info/token-info-fieldset.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/token-info/token-info-fieldset.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/token-info/token-info-fieldset.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/page.tsx similarity index 96% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/page.tsx index 9d1208d1f18..73603bd4427 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/page.tsx @@ -24,7 +24,7 @@ export default async function Page(props: { ]); if (!authToken) { - loginRedirect(`/team/${params.team_slug}/${params.project_slug}/assets`); + loginRedirect(`/team/${params.team_slug}/${params.project_slug}/tokens`); } if (!team) { @@ -53,9 +53,9 @@ export default async function Page(props: { />
-

Your assets

+

Your Tokens

- List of all assets created or imported into this project + List of all tokens created or imported into this project

@@ -79,7 +79,7 @@ function AssetsHeader() {

- Assets + Tokens

Create and Manage tokens for your project diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/analytics-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/analytics-page.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/analytics-page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/analytics-page.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/filter.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/filter.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/filter.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/filter.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/ftux.client.tsx similarity index 89% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/ftux.client.tsx index 3e6c949181c..90c2e866fa1 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/ftux.client.tsx @@ -4,10 +4,10 @@ import Link from "next/link"; import { useMemo, useState } from "react"; import type { ThirdwebClient } from "thirdweb"; import type { Project } from "@/api/projects"; -import { Button } from "@/components/ui/button"; +import { Button } from "../../../../../../../../@/components/ui/button"; +import { CreateVaultAccountButton } from "../../vault/components/create-vault-account.client"; import CreateServerWallet from "../server-wallets/components/create-server-wallet.client"; import type { Wallet } from "../server-wallets/wallet-table/types"; -import CreateVaultAccountButton from "../vault/components/create-vault-account.client"; import { SendTestTransaction } from "./send-test-tx.client"; import { deleteUserAccessToken } from "./utils"; @@ -107,7 +107,11 @@ export const EngineChecklist: React.FC = (props) => { return null; } return ( - + ); }; @@ -122,13 +126,13 @@ function CreateVaultAccountStep(props: { onUserAccessTokenCreated={props.onUserAccessTokenCreated} project={props.project} /> - - - +

); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/send-test-tx.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/send-test-tx.client.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/send-test-tx.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/send-test-tx.client.tsx index ca78c4f2b04..1bfa896da23 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/send-test-tx.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/send-test-tx.client.tsx @@ -263,7 +263,7 @@ export function SendTestTransaction(props: { onClick={() => { if (props.walletId) { router.replace( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud`, + `/team/${props.teamSlug}/${props.project.slug}/transactions`, ); } else { router.refresh(); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/summary.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/summary.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/summary.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/summary.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-chart/tx-chart-ui.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-chart/tx-chart-ui.tsx index 9db43392fde..02af55f0887 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-chart/tx-chart-ui.tsx @@ -184,7 +184,7 @@ function EmptyChartContent(props: {
@@ -74,19 +67,15 @@ function TransactionsLayout(props: { { exactMatch: true, name: "Transactions", - path: `${engineLayoutSlug}`, + path: `${layoutPath}`, }, { name: "API Explorer", - path: `${engineLayoutSlug}/explorer`, + path: `${layoutPath}/explorer`, }, { name: "Server Wallets", - path: `${engineLayoutSlug}/server-wallets`, - }, - { - name: "Vault", - path: `${engineLayoutSlug}/vault`, + path: `${layoutPath}/server-wallets`, }, ]} scrollableClassName="container max-w-7xl" diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/analytics.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/analytics.ts similarity index 96% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/analytics.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/analytics.ts index 9462f5c1567..e87721cff4e 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/analytics.ts +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/analytics.ts @@ -1,6 +1,6 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; +import type { TransactionStats } from "types/analytics"; import { NEXT_PUBLIC_ENGINE_CLOUD_URL } from "@/constants/public-envs"; -import type { TransactionStats } from "../../../../../../../../../types/analytics"; -import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; import type { Transaction, TransactionsResponse, diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/utils.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/utils.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/utils.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/utils.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/vault.client.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/vault.client.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/lib/vault.client.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/vault.client.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/page.tsx similarity index 98% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/page.tsx index 73080e14d80..3ecafefe821 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/page.tsx @@ -1,9 +1,9 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; import { createVaultClient, listEoas } from "@thirdweb-dev/vault-sdk"; import { notFound, redirect } from "next/navigation"; import { getProject } from "@/api/projects"; import { NEXT_PUBLIC_THIRDWEB_VAULT_URL } from "@/constants/public-envs"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; -import { getAuthToken } from "../../../../../../api/lib/getAuthToken"; import { TransactionsAnalyticsPageContent } from "./analytics/analytics-page"; import { EngineChecklist } from "./analytics/ftux.client"; import { TransactionAnalyticsSummary } from "./analytics/summary"; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/create-server-wallet.client.tsx similarity index 95% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/create-server-wallet.client.tsx index 21fb201f045..9c1b6407443 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/create-server-wallet.client.tsx @@ -86,9 +86,7 @@ export default function CreateServerWallet(props: { const handleCreateServerWallet = async () => { if (!props.managementAccessToken) { - router.push( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud/vault`, - ); + router.push(`/team/${props.teamSlug}/${props.project.slug}/vault`); } else { await createEoaMutation.mutateAsync({ label, @@ -106,9 +104,7 @@ export default function CreateServerWallet(props: { onClick={() => props.managementAccessToken ? setModalOpen(true) - : router.push( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud/vault`, - ) + : router.push(`/team/${props.teamSlug}/${props.project.slug}/vault`) } variant={"primary"} > diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/try-it-out.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/try-it-out.tsx similarity index 92% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/try-it-out.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/try-it-out.tsx index d0e94a89090..f31fb354299 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/try-it-out.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/components/try-it-out.tsx @@ -11,7 +11,7 @@ export function TryItOut() { const [activeTab, setActiveTab] = useState("sdk"); return ( -
+
@@ -25,8 +25,10 @@ export function TryItOut() {
+
-
+
{activeTab === "sdk" && ( -
+
Using the thirdweb SDK on the backend @@ -114,22 +116,26 @@ export function TryItOut() {

-

- Installation -

- -

- Usage example: Minting a ERC1155 NFT to a user -

- +
+

+ Installation +

+ +
+
+

+ Usage example: Minting a ERC1155 NFT to a user +

+ +
)} {activeTab === "curl" && ( @@ -140,7 +146,7 @@ export function TryItOut() { /> )} {activeTab === "js" && ( -
+

A lightweight, type safe wrapper package of the Engine HTTP API is available on{" "} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/page.tsx similarity index 97% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/page.tsx index ea2ed01fcc1..31043a018b1 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/page.tsx @@ -1,9 +1,9 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; import { createVaultClient, listEoas } from "@thirdweb-dev/vault-sdk"; import { notFound } from "next/navigation"; import { getProject } from "@/api/projects"; import { NEXT_PUBLIC_THIRDWEB_VAULT_URL } from "@/constants/public-envs"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; -import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; import type { Wallet } from "./wallet-table/types"; import { ServerWalletsTable } from "./wallet-table/wallet-table"; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/types.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/wallet-table/types.ts similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/types.ts rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/wallet-table/types.ts diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/wallet-table/wallet-table-ui.client.tsx similarity index 73% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/wallet-table/wallet-table-ui.client.tsx index 1069313b6ec..420aba0ab76 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/server-wallets/wallet-table/wallet-table-ui.client.tsx @@ -90,7 +90,7 @@ export function ServerWalletsTableUI({ />

- + @@ -138,60 +138,63 @@ export function ServerWalletsTableUI({
-
-
- Found {totalRecords} server wallets + + {totalPages > 1 && ( +
+
+ Found {totalRecords} server wallets +
+ + + + 1 ? currentPage - 1 : 1 + }`} + legacyBehavior + passHref + > + + + + {Array.from({ length: totalPages }, (_, i) => i + 1).map( + (pageNumber) => ( + + + + {pageNumber} + + + + ), + )} + + + = totalPages + ? "pointer-events-none opacity-50" + : "" + } + /> + + + +
- - - - 1 ? currentPage - 1 : 1 - }`} - legacyBehavior - passHref - > - - - - {Array.from({ length: totalPages }, (_, i) => i + 1).map( - (pageNumber) => ( - - - - {pageNumber} - - - - ), - )} - - - = totalPages - ? "pointer-events-none opacity-50" - : "" - } - /> - - - - -
+ )}
); } @@ -259,7 +262,7 @@ function SendTestTransaction(props: { - -
- -
- @@ -142,6 +130,15 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
+ +
+ + + +
); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/loading.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/universal-bridge/webhooks/loading.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/loading.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/universal-bridge/webhooks/loading.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/universal-bridge/webhooks/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/universal-bridge/webhooks/page.tsx new file mode 100644 index 00000000000..4b643e627e3 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/universal-bridge/webhooks/page.tsx @@ -0,0 +1,39 @@ +import { redirect } from "next/navigation"; +import { getProject } from "@/api/projects"; +import { UnderlineLink } from "@/components/ui/UnderlineLink"; +import { PayWebhooksPage } from "./components/webhooks.client"; + +export default async function Page(props: { + params: Promise<{ + team_slug: string; + project_slug: string; + }>; +}) { + const params = await props.params; + const project = await getProject(params.team_slug, params.project_slug); + + if (!project) { + redirect(`/team/${params.team_slug}`); + } + + return ( +
+

Webhooks

+

+ Get notified for Bridge, Swap and Onramp events.{" "} + + Learn more + +

+
+ +
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx similarity index 97% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx index b7f68abc3d8..2a2d50f9810 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx @@ -1,7 +1,13 @@ "use client"; + import { useMutation } from "@tanstack/react-query"; import { createServiceAccount } from "@thirdweb-dev/vault-sdk"; -import { CheckIcon, DownloadIcon, Loader2Icon, LockIcon } from "lucide-react"; +import { + CheckIcon, + DownloadIcon, + Loader2Icon, + UserLockIcon, +} from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import type { Project } from "@/api/projects"; @@ -18,15 +24,15 @@ import { import { Spinner } from "@/components/ui/Spinner/Spinner"; import { useDashboardRouter } from "@/lib/DashboardRouter"; import { cn } from "@/lib/utils"; -import { storeUserAccessToken } from "../../analytics/utils"; +import { storeUserAccessToken } from "../../transactions/analytics/utils"; import { createManagementAccessToken, createWalletAccessToken, initVaultClient, maskSecret, -} from "../../lib/vault.client"; +} from "../../transactions/lib/vault.client"; -export default function CreateVaultAccountButton(props: { +export function CreateVaultAccountButton(props: { project: Project; onUserAccessTokenCreated?: (userAccessToken: string) => void; }) { @@ -151,7 +157,7 @@ export default function CreateVaultAccountButton(props: { {isLoading ? ( ) : ( - + )} {"Create Vault Admin Account"} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx new file mode 100644 index 00000000000..f362e3033f6 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx @@ -0,0 +1,87 @@ +import { InfoIcon } from "lucide-react"; +import Link from "next/link"; +import type { Project } from "@/api/projects"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { CreateVaultAccountButton } from "./create-vault-account.client"; +import ListAccessTokens from "./list-access-tokens.client"; +import RotateAdminKeyButton from "./rotate-admin-key.client"; + +export function KeyManagement({ + maskedAdminKey, + project, +}: { + maskedAdminKey?: string; + project: Project; +}) { + return ( +
+ {!maskedAdminKey && } + + {maskedAdminKey && ( + <> +
+
+

+ Admin Key +

+

+ This key is used to create new server wallets and access tokens. +
We do not store this key. If you lose it, you can rotate + it to create a new one. Doing so will invalidate all existing + access tokens. +

+
+
+
+

+ {maskedAdminKey} +

+
+ +
+
+
+ + + )} +
+ ); +} + +async function CreateVaultAccountAlert(props: { project: Project }) { + return ( +
+ + + + What is Vault? + + + Vault is thirdweb's non-custodial key management system for your + server wallets that allows you to: +
    +
  • Create multiple server wallets.
  • +
  • Create Vault access tokens.
  • +
  • Sign transactions using a Vault access token.
  • +
+ Your keys are stored in a hardware enclave, and all requests are + end-to-end encrypted.{" "} + + Learn more about Vault security model. + +
+ Creating server wallets and access tokens requires a Vault admin + account. Create one below to get started. + +
+ + + +
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx index 8ba79bd1ca9..33c18b3b4a1 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx @@ -20,7 +20,7 @@ import { createWalletAccessToken, initVaultClient, SERVER_WALLET_MANAGEMENT_ACCESS_TOKEN_PURPOSE, -} from "../../lib/vault.client"; +} from "../../transactions/lib/vault.client"; export default function ListAccessTokens(props: { project: Project }) { const [modalOpen, setModalOpen] = useState(false); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx index 92e8c5f227a..3a4733f3919 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx @@ -31,7 +31,7 @@ import { createWalletAccessToken, initVaultClient, maskSecret, -} from "../../lib/vault.client"; +} from "../../transactions/lib/vault.client"; export default function RotateAdminKeyButton(props: { project: Project }) { const [modalOpen, setModalOpen] = useState(false); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx new file mode 100644 index 00000000000..83c583b1744 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx @@ -0,0 +1,31 @@ +import Link from "next/link"; + +export default function VaultLayout(props: { children: React.ReactNode }) { + return ( +
+
+
+

Vault

+

+ Secure, non-custodial key management system for your server wallets.{" "} + + Learn more. + +

+
+
+
+ +
+ {props.children} +
+ +
+
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx similarity index 92% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx index 5651b521e2e..c27ea7701b9 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx @@ -1,6 +1,7 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; import { notFound } from "next/navigation"; import { getProject } from "@/api/projects"; -import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; + import { KeyManagement } from "./components/key-management"; export default async function VaultPage(props: { diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/footer.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/footer.tsx similarity index 96% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/footer.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/footer.tsx index ecec0a930b3..862fc6b5dbe 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/footer.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/footer.tsx @@ -1,4 +1,4 @@ -import { FooterLinksSection } from "../../../components/footer/FooterLinksSection"; +import { FooterLinksSection } from "../../components/footer/FooterLinksSection"; export function InAppWalletsFooter() { return ( diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/header.tsx similarity index 88% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/header.tsx index f4914afabab..cce0bc726f4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/_components/header.tsx @@ -3,8 +3,8 @@ import { UnderlineLink } from "@/components/ui/UnderlineLink"; export async function InAppWalletsHeader() { return (
-

- In-App Wallets +

+ Wallets

A wallet infrastructure that enables apps to create, manage, and control diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/analytics/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/page.tsx similarity index 74% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/analytics/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/page.tsx index 45260aec949..ee465483d76 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/analytics/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/analytics/page.tsx @@ -10,7 +10,5 @@ export default async function Page(props: { }) { const params = await props.params; // Default to the users tab - redirect( - `/team/${params.team_slug}/${params.project_slug}/connect/in-app-wallets`, - ); + redirect(`/team/${params.team_slug}/${params.project_slug}/wallets`); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/layout.tsx similarity index 84% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/layout.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/layout.tsx index db919afcfca..6a75875579b 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/layout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/layout.tsx @@ -27,23 +27,23 @@ export default async function Layout(props: {

-
+
; @@ -21,7 +21,7 @@ export default async function Page(props: { ]); if (!authToken) { - loginRedirect(`/team/${team_slug}/connect/in-app-wallets/settings`); + loginRedirect(`/team/${team_slug}/wallets/settings`); } if (!team) { diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/webhooks/loading.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/loading.tsx similarity index 100% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/webhooks/loading.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/loading.tsx diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/page.tsx similarity index 73% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/page.tsx index daac9753981..e20009024c0 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/page.tsx @@ -1,10 +1,9 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; +import { loginRedirect } from "@app/login/loginRedirect"; import { InAppWalletUsersPageContent } from "components/embedded-wallets/Users"; import { redirect } from "next/navigation"; import { getProject } from "@/api/projects"; import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; -import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; -import { loginRedirect } from "../../../../../../../login/loginRedirect"; -import { TRACKING_CATEGORY } from "../_constants"; export default async function Page(props: { params: Promise<{ team_slug: string; project_slug: string }>; @@ -17,7 +16,7 @@ export default async function Page(props: { if (!authToken) { loginRedirect( - `/team/${params.team_slug}/${params.project_slug}/connect/in-app-wallets/users`, + `/team/${params.team_slug}/${params.project_slug}/wallets/users`, ); } @@ -35,7 +34,6 @@ export default async function Page(props: { authToken={authToken} client={client} projectClientId={project.publishableKey} - trackingCategory={TRACKING_CATEGORY} /> ); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/CreateWebhookModal.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/CreateWebhookModal.tsx index 0c341cd591c..40232ef2e9d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/CreateWebhookModal.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/CreateWebhookModal.tsx @@ -1,7 +1,7 @@ "use client"; import { zodResolver } from "@hookform/resolvers/zod"; -import { XIcon } from "lucide-react"; +import { PlusIcon, XIcon } from "lucide-react"; import { useState } from "react"; import { useForm, useWatch } from "react-hook-form"; import { toast } from "sonner"; @@ -43,7 +43,7 @@ interface CreateWebhookModalProps { client: ThirdwebClient; } -export function CreateWebhookModal({ +export function CreateContractWebhookButton({ projectClientId, supportedChainIds, client, @@ -222,7 +222,10 @@ export function CreateWebhookModal({ return ( - + -
- -
+
+ +
); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contract-webhooks/contract-webhooks-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contract-webhooks/contract-webhooks-page.tsx new file mode 100644 index 00000000000..b3fe91d55ae --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contract-webhooks/contract-webhooks-page.tsx @@ -0,0 +1,80 @@ +import { + getSupportedWebhookChains, + getWebhooks, + type WebhookResponse, +} from "@/api/insight/webhooks"; +import type { Project } from "@/api/projects"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; +import { CreateContractWebhookButton } from "../components/CreateWebhookModal"; +import { ContractsWebhooksTable } from "../components/WebhooksTable"; + +export async function ContractsWebhooksPageContent(props: { + project: Project; + authToken: string; +}) { + let webhooks: WebhookResponse[] = []; + let errorMessage = ""; + let supportedChainIds: number[] = []; + + const projectClientId = props.project.publishableKey; + + try { + const webhooksRes = await getWebhooks(projectClientId); + if (webhooksRes.error) { + errorMessage = webhooksRes.error; + } else if (webhooksRes.data) { + webhooks = webhooksRes.data; + } + + const supportedChainsRes = await getSupportedWebhookChains(); + if ("chains" in supportedChainsRes) { + supportedChainIds = supportedChainsRes.chains; + } else { + errorMessage = supportedChainsRes.error; + } + } catch (error) { + errorMessage = "Failed to load webhooks. Please try again later."; + console.error("Error loading project or webhooks", error); + } + + const client = getClientThirdwebClient({ + jwt: props.authToken, + teamId: props.project.teamId, + }); + + return ( +
+ {errorMessage ? ( +
+
+

+ Unable to load webhooks +

+

{errorMessage}

+
+
+ ) : webhooks.length > 0 ? ( + + ) : ( +
+
+

No webhooks found

+

+ Create a webhook to get started. +

+
+ +
+ )} +
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx new file mode 100644 index 00000000000..c76bc502dfb --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx @@ -0,0 +1,45 @@ +import { TabPathLinks } from "@/components/ui/tabs"; + +export default async function WebhooksLayout(props: { + children: React.ReactNode; + params: Promise<{ + team_slug: string; + project_slug: string; + }>; +}) { + const params = await props.params; + return ( +
+
+
+

+ Webhooks +

+

+ Create and manage webhooks to get notified about events +

+
+
+ + +
+
+ {props.children} +
+
+
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx index 6d413a75938..53e25b1b122 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx @@ -1,25 +1,14 @@ +import { getAuthToken } from "@app/api/lib/getAuthToken"; import { notFound } from "next/navigation"; -import { - getSupportedWebhookChains, - getWebhooks, - type WebhookResponse, -} from "@/api/insight/webhooks"; import { getProject } from "@/api/projects"; import { UnderlineLink } from "@/components/ui/UnderlineLink"; -import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; -import { getAuthToken } from "../../../../../api/lib/getAuthToken"; -import { CreateWebhookModal } from "./components/CreateWebhookModal"; -import { WebhooksTable } from "./components/WebhooksTable"; +import { ContractsWebhooksPageContent } from "./contract-webhooks/contract-webhooks-page"; export default async function WebhooksPage({ params, }: { params: Promise<{ team_slug: string; project_slug: string }>; }) { - let webhooks: WebhookResponse[] = []; - let errorMessage = ""; - let supportedChainIds: number[] = []; - const [authToken, resolvedParams] = await Promise.all([ getAuthToken(), params, @@ -34,87 +23,23 @@ export default async function WebhooksPage({ notFound(); } - const projectClientId = project.publishableKey; - - try { - const webhooksRes = await getWebhooks(projectClientId); - if (webhooksRes.error) { - errorMessage = webhooksRes.error; - } else if (webhooksRes.data) { - webhooks = webhooksRes.data; - } - - const supportedChainsRes = await getSupportedWebhookChains(); - if ("chains" in supportedChainsRes) { - supportedChainIds = supportedChainsRes.chains; - } else { - errorMessage = supportedChainsRes.error; - } - } catch (error) { - errorMessage = "Failed to load webhooks. Please try again later."; - console.error("Error loading project or webhooks", error); - } - - const client = getClientThirdwebClient({ - jwt: authToken, - teamId: project.teamId, - }); - return ( -
-
-
-

- Webhooks -

-

- Create and manage webhooks to get notified about blockchain events, - transactions and more.{" "} - - Learn more about webhooks. - -

-
-
-
-
- {errorMessage ? ( -
-
-

- Unable to load webhooks -

-

{errorMessage}

-
-
- ) : webhooks.length > 0 ? ( - - ) : ( -
-
-

No webhooks found

-

- Create a webhook to get started. -

-
- -
- )} -
-
+
+

+ Contract Webhooks +

+

+ Get notified about blockchain events, transactions and more.{" "} + + Learn more + +

+
+
); } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/universal-bridge/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/universal-bridge/page.tsx new file mode 100644 index 00000000000..dac9b2a071f --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/universal-bridge/page.tsx @@ -0,0 +1,41 @@ +import { redirect } from "next/navigation"; +import { getProject } from "@/api/projects"; +import { UnderlineLink } from "@/components/ui/UnderlineLink"; +import { PayWebhooksPage } from "../../universal-bridge/webhooks/components/webhooks.client"; + +export default async function Page(props: { + params: Promise<{ + team_slug: string; + project_slug: string; + }>; +}) { + const params = await props.params; + const project = await getProject(params.team_slug, params.project_slug); + + if (!project) { + redirect(`/team/${params.team_slug}`); + } + + return ( +
+

+ Universal Bridge Webhooks +

+

+ Get notified for Bridge, Swap and Onramp events.{" "} + + Learn more + +

+
+ +
+ ); +} diff --git a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx index 4e731405dc5..3f68ba246fd 100644 --- a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx +++ b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx @@ -58,7 +58,7 @@ export const ImportModal: React.FC = (props) => { > - Import {props.type === "contract" ? "Contract" : "Asset"} + Import {props.type === "contract" ? "Contract" : "Token"} Import a deployed contract in your project 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 81de393a4ad..5e7abbcae8d 100644 --- a/apps/dashboard/src/components/contract-components/tables/contract-table.tsx +++ b/apps/dashboard/src/components/contract-components/tables/contract-table.tsx @@ -163,7 +163,7 @@ export function ContractTableUI(props: { Contract Address )} - {props.variant === "asset" && Asset Page} + {props.variant === "asset" && Token Page} Actions @@ -262,7 +262,7 @@ export function ContractTableUI(props: {
{props.variant === "asset" ? ( -

No assets found

+

No tokens found

) : (

No contracts found

)} diff --git a/apps/dashboard/src/components/dashboard/StepsCard.tsx b/apps/dashboard/src/components/dashboard/StepsCard.tsx index 4f565c69ffb..eba5a9d2e8d 100644 --- a/apps/dashboard/src/components/dashboard/StepsCard.tsx +++ b/apps/dashboard/src/components/dashboard/StepsCard.tsx @@ -37,7 +37,7 @@ export const StepsCard: React.FC = ({ return (
{/* Title + Desc */} -

+

{title}

diff --git a/apps/dashboard/src/components/embedded-wallets/Users/index.tsx b/apps/dashboard/src/components/embedded-wallets/Users/index.tsx index 280beebd2d4..4c58aaa43cb 100644 --- a/apps/dashboard/src/components/embedded-wallets/Users/index.tsx +++ b/apps/dashboard/src/components/embedded-wallets/Users/index.tsx @@ -36,7 +36,6 @@ const getUserIdentifier = (accounts: WalletUser["linkedAccounts"]) => { const columnHelper = createColumnHelper(); export function InAppWalletUsersPageContent(props: { - trackingCategory: string; authToken: string; projectClientId: string; client: ThirdwebClient; diff --git a/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx b/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx index 00a9e329542..76d7b9aab22 100644 --- a/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx +++ b/apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx @@ -3,7 +3,9 @@ import { getUniversalBridgeUsage, getUniversalBridgeWalletUsage, } from "@/api/analytics"; +import { CodeServer } from "@/components/ui/code/code.server"; import type { Range } from "../../analytics/date-range-selector"; +import { apiCode, embedCode, sdkCode } from "./code-examples"; import { PayCustomersTable } from "./components/PayCustomersTable"; import { PaymentHistory } from "./components/PaymentHistory"; import { PaymentsSuccessRate } from "./components/PaymentsSuccessRate"; @@ -59,8 +61,38 @@ export async function PayAnalytics(props: { const hasVolume = volumeData.some((d) => d.amountUsdCents > 0); const hasWallet = walletData.some((d) => d.count > 0); + if (!hasVolume && !hasWallet) { - return ; + return ( + + ), + embed: ( + + ), + sdk: ( + + ), + } as const + } + /> + ); } return ( diff --git a/apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx b/apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx index 7cf3a02b736..7f199bb6df7 100644 --- a/apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx +++ b/apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx @@ -1,22 +1,31 @@ "use client"; + import { ExternalLinkIcon } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; import { Button } from "@/components/ui/button"; -import { CodeServer } from "@/components/ui/code/code.server"; import { TabButtons } from "@/components/ui/tabs"; -export function PayEmbedFTUX(props: { clientId: string }) { - const [tab, setTab] = useState("embed"); +type Tab = "embed" | "sdk" | "api"; + +export function PayEmbedFTUX(props: { + clientId: string; + codeExamples: { + embed: React.ReactNode; + sdk: React.ReactNode; + api: React.ReactNode; + }; +}) { + const [tab, setTab] = useState("embed"); return (
-
-

+
+

Start Monetizing Your App

-
+
- {tab === "embed" && ( - - )} - {tab === "sdk" && ( - - )} - {tab === "api" && ( - - )} + + {props.codeExamples[tab]}
-
+