Sidebars cleanup (#4534)
## Problem solved
Short description of the bug fixed or feature added
<!-- start pr-codex -->
---
## PR-Codex overview
This PR updates sidebar components and layouts in the dashboard, adds `SidebarLayout`, and refactors sidebar imports.
### Detailed summary
- Updated sidebar links in various components
- Added `SidebarLayout` component
- Refactored sidebar imports to use `SidebarLayout` and `MobileSidebar`
- Updated layout components for better organization
> The following files were skipped due to too many changes: `apps/dashboard/src/pages/dashboard/settings/notifications.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/create/EcosystemCreatePage.tsx`, `apps/dashboard/src/pages/dashboard/settings/api-keys/[id].tsx`, `apps/dashboard/src/pages/dashboard/settings/api-keys/index.tsx`, `apps/dashboard/src/pages/dashboard/contracts/publish.tsx`, `apps/dashboard/src/components/layout/app-shell/index.tsx`, `apps/dashboard/src/pages/dashboard/settings/devices.tsx`, `apps/dashboard/src/pages/publish/[...paths].tsx`, `apps/dashboard/src/pages/dashboard/contracts/deploy.tsx`, `apps/dashboard/src/@/components/blocks/SidebarLayout.stories.tsx`, `apps/dashboard/.storybook/preview.tsx`, `apps/dashboard/src/pages/dashboard/connect/analytics.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/layout.tsx`, `apps/dashboard/src/pages/dashboard/connect/in-app-wallets.tsx`, `apps/dashboard/src/pages/dashboard/settings/storage.tsx`, `apps/dashboard/src/app/(dashboard)/trending/page.tsx`, `apps/dashboard/src/pages/dashboard/connect/account-abstraction.tsx`, `apps/dashboard/src/app/account/layout.tsx`, `apps/dashboard/src/@/components/blocks/MobileSidebar.tsx`, `apps/dashboard/src/@/components/blocks/Sidebar.tsx`, `apps/dashboard/src/core-ui/sidebar/contracts.tsx`, `apps/dashboard/src/pages/explore/index.tsx`, `apps/dashboard/src/core-ui/sidebar/settings.tsx`, `apps/dashboard/src/components/pages/publish.tsx`
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
This commit is contained in:
@@ -89,7 +89,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
name: "lucide-react",
|
||||
importNames: ["Link", "Table"],
|
||||
importNames: ["Link", "Table", "Sidebar"],
|
||||
message:
|
||||
'This is likely a mistake. If you really want to import this - postfix the imported name with Icon. Example - "LinkIcon"',
|
||||
},
|
||||
|
||||
@@ -51,28 +51,28 @@ function StoryLayout(props: {
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-end p-4 border-b gap-2">
|
||||
<Button
|
||||
onClick={() => setTheme("dark")}
|
||||
size="sm"
|
||||
variant={theme === "dark" ? "default" : "ghost"}
|
||||
>
|
||||
<MoonIcon className="size-5" />
|
||||
</Button>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<div className="min-h-screen flex flex-col bg-background text-foreground min-w-0">
|
||||
<div className="flex justify-end p-4 border-b gap-2">
|
||||
<Button
|
||||
onClick={() => setTheme("dark")}
|
||||
size="sm"
|
||||
variant={theme === "dark" ? "default" : "ghost"}
|
||||
>
|
||||
<MoonIcon className="size-5" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={() => setTheme("light")}
|
||||
size="sm"
|
||||
variant={theme === "light" ? "default" : "ghost"}
|
||||
>
|
||||
<SunIcon className="size-5" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setTheme("light")}
|
||||
size="sm"
|
||||
variant={theme === "light" ? "default" : "ghost"}
|
||||
>
|
||||
<SunIcon className="size-5" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grow flex flex-col min-w-0">{props.children}</div>
|
||||
</div>
|
||||
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{props.children}
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,19 +2,44 @@
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { cn } from "../../lib/utils";
|
||||
import { NavLink } from "../ui/NavLink";
|
||||
import type { SidebarLink } from "./Sidebar";
|
||||
|
||||
export function MobileSidebar(props: {
|
||||
links?: SidebarLink[];
|
||||
footer?: React.ReactNode;
|
||||
trigger: React.ReactNode;
|
||||
trigger?: React.ReactNode;
|
||||
triggerClassName?: string;
|
||||
}) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const pathname = usePathname();
|
||||
const activeLink = props.links?.find((link) => {
|
||||
if (link.exactMatch) {
|
||||
return link.href === pathname;
|
||||
}
|
||||
return pathname?.startsWith(link.href);
|
||||
});
|
||||
|
||||
const defaultTrigger = (
|
||||
<Button
|
||||
className={cn(
|
||||
"w-full lg:hidden text-left justify-between gap-2 bg-muted/50",
|
||||
props.triggerClassName,
|
||||
)}
|
||||
variant="outline"
|
||||
>
|
||||
{activeLink?.label}
|
||||
<ChevronDownIcon className="size-4 text-muted-foreground" />
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogTrigger asChild>{props.trigger}</DialogTrigger>
|
||||
<DialogTrigger asChild>{props.trigger || defaultTrigger}</DialogTrigger>
|
||||
<DialogContent
|
||||
className="p-4 rounded-t-xl rounded-b-none"
|
||||
dialogCloseClassName="hidden"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import type React from "react";
|
||||
import { cn } from "../../lib/utils";
|
||||
import { NavLink } from "../ui/NavLink";
|
||||
@@ -22,22 +23,29 @@ export type SidebarContentProps = {
|
||||
export function Sidebar(props: SidebarContentProps) {
|
||||
return (
|
||||
<aside
|
||||
className={cn("w-[240px] flex-shrink-0 hidden lg:block", props.className)}
|
||||
className={cn(
|
||||
"w-[230px] flex-shrink-0 hidden lg:block self-start sticky top-0",
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<div className="sticky top-0 pt-8">
|
||||
<div className="pt-7">
|
||||
{props.header}
|
||||
<div className="flex flex-col border-l-2 border-border">
|
||||
{props.links?.map((link) => (
|
||||
<NavLink
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="text-sm py-1.5 pl-4 text-muted-foreground hover:text-foreground border-l-2 ml-[-2px] border-transparent hover:border-foreground transition-colors"
|
||||
activeClassName="text-foreground border-link-foreground"
|
||||
exactMatch={link.exactMatch}
|
||||
>
|
||||
{link.label}
|
||||
</NavLink>
|
||||
))}
|
||||
<div className="flex flex-col gap-1">
|
||||
{props.links?.map((link) => {
|
||||
const isExternal = link.href.startsWith("http");
|
||||
return (
|
||||
<NavLink
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className="py-2 hover:bg-muted rounded-md px-3 text-muted-foreground text-sm flex items-center gap-2"
|
||||
activeClassName="text-foreground"
|
||||
exactMatch={link.exactMatch}
|
||||
>
|
||||
{link.label}
|
||||
{isExternal && <ExternalLinkIcon className="size-3" />}
|
||||
</NavLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { mobileViewport } from "../../../stories/utils";
|
||||
import { SidebarLayout } from "./SidebarLayout";
|
||||
|
||||
const meta = {
|
||||
title: "layouts/SidebarLayout",
|
||||
component: Story,
|
||||
parameters: {
|
||||
nextjs: {
|
||||
appDirectory: true,
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Story>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Desktop: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const Mobile: Story = {
|
||||
args: {},
|
||||
parameters: {
|
||||
viewport: mobileViewport("iphone14"),
|
||||
},
|
||||
};
|
||||
|
||||
function Story() {
|
||||
return (
|
||||
<SidebarLayout
|
||||
sidebarLinks={[
|
||||
{
|
||||
href: "/foo",
|
||||
label: "consectetur",
|
||||
},
|
||||
{
|
||||
href: "/bar",
|
||||
label: "adipiscing",
|
||||
},
|
||||
{
|
||||
href: "/bar",
|
||||
label: "eiusmod",
|
||||
},
|
||||
{
|
||||
label: "incididunt",
|
||||
href: "https://playground.thirdweb.com/",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<ContentPlaceholder />
|
||||
</SidebarLayout>
|
||||
);
|
||||
}
|
||||
|
||||
function ContentPlaceholder() {
|
||||
return (
|
||||
<div className="bg-muted grow flex items-center justify-center">
|
||||
<p className="text-muted-foreground text-3xl"> CHILDREN </p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { MobileSidebar } from "./MobileSidebar";
|
||||
import { Sidebar, type SidebarLink } from "./Sidebar";
|
||||
|
||||
export function SidebarLayout(props: {
|
||||
sidebarLinks: SidebarLink[];
|
||||
children: React.ReactNode;
|
||||
desktopSidebarClassName?: string;
|
||||
mobileSidebarClassName?: string;
|
||||
}) {
|
||||
const { sidebarLinks, children } = props;
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row gap-6 container px-4 w-full grow max-sm:pt-6">
|
||||
<Sidebar links={sidebarLinks} className={props.desktopSidebarClassName} />
|
||||
<MobileSidebar
|
||||
links={sidebarLinks}
|
||||
triggerClassName={props.mobileSidebarClassName}
|
||||
/>
|
||||
<main className="grow max-sm:w-full flex flex-col lg:pt-8 pb-10">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ export const Mobile: Story = {
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-6 text-foregroun flex flex-col gap-6 max-w-[1000px] mx-auto">
|
||||
<div className="flex flex-col gap-6 lg:max-w-[1000px] lg:mx-auto min-w-0 py-6 px-4">
|
||||
<BadgeContainer label="Normal">
|
||||
<TableDemo />
|
||||
</BadgeContainer>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { NavLink } from "../../../../components/nav-link.client";
|
||||
import type { SidebarNavSection } from "./types";
|
||||
|
||||
export type SidebarSectionProps = {
|
||||
section: SidebarNavSection;
|
||||
};
|
||||
|
||||
export const SidebarSection: React.FC<SidebarSectionProps> = ({ section }) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-2 h-7 relative">
|
||||
{/* title element */}
|
||||
<label className="text-sm text-muted-foreground">{section.title}</label>
|
||||
<nav>
|
||||
<ul>
|
||||
{section.items.map((item) => (
|
||||
<li key={item.id}>
|
||||
<NavLink
|
||||
prefetch={false}
|
||||
href={item.href}
|
||||
className="pl-3 border-l-2 h-8 text-sm text-muted-foreground flex items-center hover:text-accent-foreground hover:border-foreground"
|
||||
activeClassName="border-primary hover:border-primary text-accent-foreground font-semibold"
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,65 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { MenuIcon } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import type React from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { SidebarSection } from "./section";
|
||||
import type { SidebarNavSection } from "./types";
|
||||
|
||||
export type SideBarNavProps = {
|
||||
sections: Array<SidebarNavSection>;
|
||||
};
|
||||
|
||||
export const SidebarNav: React.FC<SideBarNavProps> = ({ sections }) => {
|
||||
const currentPath = usePathname() || "";
|
||||
|
||||
const activeLinkInSections = useMemo(() => {
|
||||
for (const section of sections) {
|
||||
return section.items.find((item) => item.href.startsWith(currentPath));
|
||||
}
|
||||
}, [sections, currentPath]);
|
||||
|
||||
const [isMobileOpen, setIsMobileOpen] = useState(false);
|
||||
|
||||
// legitimate use case
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
useEffect(() => {
|
||||
// close mobile sidebar when path changes
|
||||
if (currentPath) {
|
||||
setIsMobileOpen(false);
|
||||
}
|
||||
}, [currentPath]);
|
||||
|
||||
return (
|
||||
<aside className="w-full md:w-[250px] lg:w-[300px] border-b md:border-b-0 relative md:sticky top-0 flex-shrink-0">
|
||||
{/* mobile toggle */}
|
||||
<div className="flex flex-row items-center justify-between w-full py-4 md:hidden">
|
||||
<label className="flex items-center h-8 pl-3 text-sm font-semibold border-l-2 text-accent-foreground border-primary">
|
||||
{activeLinkInSections?.title || "Dashboard"}
|
||||
</label>
|
||||
<Button
|
||||
onClick={() => setIsMobileOpen((prev) => !prev)}
|
||||
size="icon"
|
||||
variant="outline"
|
||||
>
|
||||
<MenuIcon />
|
||||
</Button>
|
||||
</div>
|
||||
{/* actual link sections */}
|
||||
<div
|
||||
className={cn(
|
||||
"transition-all md:transition-none max-h-0 md:max-h-full md:h-full overflow-hidden md:overflow-auto absolute md:bg-transparent md:relative w-full px-4 md:py-10",
|
||||
isMobileOpen &&
|
||||
"h-svh max-h-svh top-full mt-[1px] md:top-0 overflow-auto backdrop-blur-lg md:backdrop-blur-none py-4 bg-background/50 z-50",
|
||||
)}
|
||||
>
|
||||
{sections.map((section) => (
|
||||
<SidebarSection section={section} key={section.id} />
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
export type SidebarNavLink = {
|
||||
id: string;
|
||||
title: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
export type SidebarNavSection = {
|
||||
id: string;
|
||||
title: string;
|
||||
// TODO: make sections be able to be in items when we need nested sections
|
||||
items: Array<SidebarNavLink>;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
|
||||
export function ConnectSidebarLayout(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<SidebarLayout
|
||||
sidebarLinks={[
|
||||
{
|
||||
label: "Analytics",
|
||||
href: "/dashboard/connect/analytics",
|
||||
},
|
||||
{
|
||||
label: "In-App Wallets",
|
||||
href: "/dashboard/connect/in-app-wallets",
|
||||
},
|
||||
{
|
||||
label: "Ecosystem Wallets",
|
||||
href: "/dashboard/connect/ecosystem",
|
||||
},
|
||||
{
|
||||
label: "Account Abstraction",
|
||||
href: "/dashboard/connect/account-abstraction",
|
||||
},
|
||||
{
|
||||
label: "Pay",
|
||||
href: "/dashboard/connect/pay",
|
||||
},
|
||||
{
|
||||
label: "Playground",
|
||||
href: "https://playground.thirdweb.com/connect/sign-in/button",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</SidebarLayout>
|
||||
);
|
||||
}
|
||||
+1
-1
@@ -31,7 +31,7 @@ export async function EcosystemLayoutSlug({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full gap-10 px-2 py-10 sm:px-4">
|
||||
<div className="flex flex-col w-full gap-10">
|
||||
<EcosystemHeader
|
||||
ecosystem={ecosystem}
|
||||
ecosystemLayoutPath={ecosystemLayoutPath}
|
||||
|
||||
+4
-4
@@ -5,16 +5,16 @@ export function EcosystemCreatePage(props: {
|
||||
ecosystemLayoutPath: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col w-full gap-10 px-2 py-10 sm:px-4">
|
||||
<header className="flex flex-col gap-2">
|
||||
<h2 className="text-4xl font-bold text-foreground">
|
||||
<div className="flex flex-col w-full gap-6">
|
||||
<header className="flex flex-col gap-1">
|
||||
<h2 className="text-3xl font-semibold text-foreground tracking-tight">
|
||||
Create an Ecosystem
|
||||
</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Create wallets that work across every chain and every app.
|
||||
</p>
|
||||
</header>
|
||||
<main className="grid w-full max-w-sm gap-8 md:max-w-lg lg:max-w-4xl xl:gap-12 lg:grid-cols-2">
|
||||
<main className="grid w-full max-w-sm gap-6 md:max-w-lg lg:max-w-4xl lg:grid-cols-2">
|
||||
<section className="flex items-start">
|
||||
<EcosystemWalletPricingCard />
|
||||
</section>
|
||||
|
||||
@@ -1,52 +1,7 @@
|
||||
import { SidebarNav } from "../components/sidebar/sidebar.client";
|
||||
import type { SidebarNavSection } from "../components/sidebar/types";
|
||||
import { ConnectSidebarLayout } from "./DashboardConnectLayout";
|
||||
|
||||
const SIDEBAR_SECTIONS = [
|
||||
{
|
||||
id: "connect",
|
||||
title: "Connect",
|
||||
items: [
|
||||
{
|
||||
id: "analytics",
|
||||
title: "Analytics",
|
||||
href: "/dashboard/connect/analytics",
|
||||
},
|
||||
{
|
||||
id: "embedded-wallets",
|
||||
title: "In-App Wallets",
|
||||
href: "/dashboard/connect/in-app-wallets",
|
||||
},
|
||||
{
|
||||
id: "ecosystem",
|
||||
title: "Ecosystem Wallets",
|
||||
href: "/dashboard/connect/ecosystem",
|
||||
},
|
||||
{
|
||||
id: "account-abstraction",
|
||||
title: "Account Abstraction",
|
||||
href: "/dashboard/connect/account-abstraction",
|
||||
},
|
||||
{
|
||||
id: "pay-settings",
|
||||
title: "Pay",
|
||||
href: "/dashboard/connect/pay",
|
||||
},
|
||||
{
|
||||
id: "playground",
|
||||
title: "Playground",
|
||||
href: "https://playground.thirdweb.com/connect/sign-in/button",
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies Array<SidebarNavSection>;
|
||||
|
||||
export default function DashboardConnectLayout(props: {
|
||||
export default function Layout(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col md:flex-row md:h-full container px-4">
|
||||
<SidebarNav sections={SIDEBAR_SECTIONS} />
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
return <ConnectSidebarLayout>{props.children}</ConnectSidebarLayout>;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,12 @@ export default async function DashboardConnectPayPage() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-8 py-6 w-full">
|
||||
<div className="flex flex-col gap-8 w-full">
|
||||
<div className="flex flex-col lg:flex-row gap-6 justify-between items-start">
|
||||
<div className="max-w-[800px]">
|
||||
<h1 className="text-5xl tracking-tight font-bold mb-5">Pay</h1>
|
||||
<h1 className="text-3xl lg:text-4xl tracking-tight font-bold mb-3">
|
||||
Pay
|
||||
</h1>
|
||||
<p className="text-muted-foreground leading-7">
|
||||
Pay allows your users to purchase cryptocurrencies and execute
|
||||
transactions with their credit card or debit card, or with any token
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { type SortBy, type TimeRange, fetchTopContracts } from "lib/search";
|
||||
import type { Metadata } from "next";
|
||||
import { ContractsSidebarLayout } from "../../../core-ui/sidebar/contracts";
|
||||
import { TrendingContractSection } from "./components/trending-table";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -25,42 +25,16 @@ export default async function DashboardContractTrendingPage(props: {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="container px-4 flex gap-2">
|
||||
<Sidebar
|
||||
links={[
|
||||
{
|
||||
href: "/dashboard/contracts/deploy",
|
||||
label: "Deploy",
|
||||
},
|
||||
{
|
||||
href: "/dashboard/contracts/publish",
|
||||
label: "Publish",
|
||||
},
|
||||
{
|
||||
href: "/explore",
|
||||
label: "Explore",
|
||||
},
|
||||
{
|
||||
href: "/trending",
|
||||
label: "Trending",
|
||||
},
|
||||
{
|
||||
href: "/dashboard/contracts/build",
|
||||
label: "Build",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<div className="py-8">
|
||||
<h1 className="text-3xl md:text-4xl tracking-tight font-semibold mb-5">
|
||||
Trending Contracts
|
||||
</h1>
|
||||
<ContractsSidebarLayout>
|
||||
<h1 className="text-2xl md:text-3xl tracking-tight font-semibold mb-5">
|
||||
Trending Contracts
|
||||
</h1>
|
||||
|
||||
<TrendingContractSection
|
||||
topContracts={topContracts}
|
||||
searchParams={props.searchParams}
|
||||
showPagination={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<TrendingContractSection
|
||||
topContracts={topContracts}
|
||||
searchParams={props.searchParams}
|
||||
showPagination={true}
|
||||
/>
|
||||
</ContractsSidebarLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getProjects } from "@/api/projects";
|
||||
import { getTeams } from "@/api/team";
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
import { AppFooter } from "@/components/blocks/app-footer";
|
||||
import { TabPathLinks } from "@/components/ui/tabs";
|
||||
import type React from "react";
|
||||
import { TWAutoConnect } from "../components/autoconnect";
|
||||
import { AccountHeader } from "./components/AccountHeader";
|
||||
@@ -13,7 +13,25 @@ export default async function AccountLayout(props: {
|
||||
<div className="min-h-full flex flex-col bg-background">
|
||||
<div className="grow flex flex-col">
|
||||
<HeaderAndNav />
|
||||
<main className="grow flex flex-col">{props.children}</main>
|
||||
<SidebarLayout
|
||||
sidebarLinks={[
|
||||
{
|
||||
href: "/account",
|
||||
label: "Overview",
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
href: "/account/wallets",
|
||||
label: "Wallets",
|
||||
},
|
||||
{
|
||||
href: "/account/settings",
|
||||
label: "Settings",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</SidebarLayout>
|
||||
</div>
|
||||
<TWAutoConnect />
|
||||
<AppFooter />
|
||||
@@ -32,27 +50,8 @@ async function HeaderAndNav() {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="bg-muted/50">
|
||||
<div className="bg-muted/50 border-b">
|
||||
<AccountHeader teamsAndProjects={teamsAndProjects} />
|
||||
|
||||
<TabPathLinks
|
||||
tabContainerClassName="px-4 lg:px-6"
|
||||
links={[
|
||||
{
|
||||
path: "/account",
|
||||
name: "Overview",
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
path: "/account/wallets",
|
||||
name: "Wallets",
|
||||
},
|
||||
{
|
||||
path: "/account/settings",
|
||||
name: "Settings",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ export const headerLinks = {
|
||||
left: [
|
||||
{
|
||||
name: "Connect",
|
||||
href: "/dashboard/connect",
|
||||
href: "/dashboard/connect/analytics",
|
||||
},
|
||||
{
|
||||
name: "Contracts",
|
||||
|
||||
+1
-3
@@ -38,9 +38,7 @@ function Story(props: {
|
||||
type: "mobile" | "desktop";
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={"min-h-screen text-foreground lg:max-w-[1100px] py-6 mx-auto"}
|
||||
>
|
||||
<div className={"min-h-screen text-foreground container py-6"}>
|
||||
{props.type === "desktop" && <TeamSettingsSidebar teamSlug="foo" />}
|
||||
|
||||
{props.type === "mobile" && (
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
export function ConnectMobileSidebar(props: {
|
||||
links: { label: string; href: string }[];
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const activeLink = props.links.find((link) => pathname === link.href);
|
||||
return (
|
||||
<MobileSidebar
|
||||
links={props.links}
|
||||
trigger={
|
||||
<Button
|
||||
className="w-full lg:hidden text-left justify-between gap-2"
|
||||
variant="outline"
|
||||
>
|
||||
{activeLink?.label || "Connect"}
|
||||
<ChevronDownIcon className="size-5 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ export const Mobile: Story = {
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-4 text-foreground gap-6 max-w-[1000px] flex flex-col mx-auto py-10">
|
||||
<div className="container py-8">
|
||||
<ConnectAnalyticsDashboardUI
|
||||
walletUsage={createWalletStatsStub(30)}
|
||||
aggregateWalletUsage={createWalletStatsStub(30)}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ export const Mobile: Story = {
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-4 text-foreground gap-6 max-w-[1000px] flex flex-col mx-auto">
|
||||
<div className="gap-6 flex flex-col container py-8">
|
||||
<BadgeContainer label="30 days">
|
||||
<DailyConnectionsChartCard
|
||||
walletStats={createWalletStatsStub(30)}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ export const Mobile: Story = {
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-4 text-foreground gap-6 max-w-[1000px] flex flex-col mx-auto">
|
||||
<div className="container flex flex-col gap-10 py-10">
|
||||
<BadgeContainer label="30 days">
|
||||
<WalletConnectorsChartCard
|
||||
walletStats={createWalletStatsStub(30)}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ export const Mobile: Story = {
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-4 text-foreground gap-6 max-w-[1000px] flex flex-col mx-auto">
|
||||
<div className="flex flex-col gap-10 py-10 container">
|
||||
<BadgeContainer label="30 days">
|
||||
<WalletDistributionChartCard
|
||||
walletStats={createWalletStatsStub(30)}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { ConnectMobileSidebar } from "./ConnectMobileSidebar";
|
||||
|
||||
export default function Layout(props: {
|
||||
params: {
|
||||
@@ -41,7 +41,7 @@ export default function Layout(props: {
|
||||
<div className="h-full container flex gap-4">
|
||||
<Sidebar links={links} />
|
||||
<div className="grow py-6 max-sm:w-full">
|
||||
<ConnectMobileSidebar links={links} />
|
||||
<MobileSidebar links={links} triggerClassName="max-sm:mb-6" />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { getEngineGeneralSidebarLinks } from "./getEngineGeneralSidebarLinks";
|
||||
import { EngineGeneralPageMobileSidebar } from "./sidebars";
|
||||
|
||||
export default function Layout(props: {
|
||||
params: {
|
||||
@@ -17,7 +17,7 @@ export default function Layout(props: {
|
||||
<div className="container flex gap-6">
|
||||
<Sidebar links={sidebarLinks} />
|
||||
<div className="pt-6 grow max-sm:w-full">
|
||||
<EngineGeneralPageMobileSidebar links={sidebarLinks} />
|
||||
<MobileSidebar links={sidebarLinks} triggerClassName="max-sm:mb-6" />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import type { SidebarLink } from "@/components/blocks/Sidebar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
export function EngineGeneralPageMobileSidebar(props: {
|
||||
links: SidebarLink[];
|
||||
}) {
|
||||
const { links } = props;
|
||||
const pathname = usePathname();
|
||||
const activeLink = links.find((link) => link.href === pathname);
|
||||
|
||||
return (
|
||||
<MobileSidebar
|
||||
links={links}
|
||||
trigger={
|
||||
<Button
|
||||
className="w-full lg:hidden text-left justify-between gap-2 mb-6"
|
||||
variant="outline"
|
||||
>
|
||||
{activeLink?.label || "Connect"}
|
||||
<ChevronDownIcon className="size-5 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -81,7 +81,7 @@ export const DeployedContracts: React.FC<DeployedContractsProps> = ({
|
||||
setImportModalOpen(false);
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-col lg:flex-row lg:justify-between gap-4 md:py-4">
|
||||
<div className="flex flex-col lg:flex-row lg:justify-between gap-4 md:pb-4">
|
||||
<div>
|
||||
<h1 className="text-3xl lg:text-4xl font-semibold tracking-tight mb-1.5">
|
||||
Your contracts
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ function Variants(props: {
|
||||
canEditAdvancedFeatures: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background px-4 py-6 text-foreground max-w-[1140px] mx-auto">
|
||||
<div className="py-6 max-w-[1140px] mx-auto w-full px-4">
|
||||
<div className="flex gap-10 flex-col">
|
||||
<InAppWalletSettingsUI
|
||||
canEditAdvancedFeatures={props.canEditAdvancedFeatures}
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { EngineMobileSidebar, EngineSidebar } from "./EngineSidebar";
|
||||
import { SidebarLayout } from "../../@/components/blocks/SidebarLayout";
|
||||
|
||||
export function EngineGeneralPageLayout(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-6 container px-4 w-full">
|
||||
<EngineSidebar />
|
||||
<div className="grow max-sm:w-full pt-6 lg:pt-8">
|
||||
<EngineMobileSidebar />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
<SidebarLayout
|
||||
sidebarLinks={[
|
||||
{
|
||||
label: "Overview",
|
||||
exactMatch: true,
|
||||
href: "/dashboard/engine",
|
||||
},
|
||||
{
|
||||
label: "Create",
|
||||
href: "/dashboard/engine/create",
|
||||
},
|
||||
{
|
||||
label: "Import",
|
||||
href: "/dashboard/engine/import",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</SidebarLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
const links = [
|
||||
{
|
||||
label: "Overview",
|
||||
exactMatch: true,
|
||||
href: "/dashboard/engine",
|
||||
},
|
||||
{
|
||||
label: "Create",
|
||||
href: "/dashboard/engine/create",
|
||||
},
|
||||
{
|
||||
label: "Import",
|
||||
href: "/dashboard/engine/import",
|
||||
},
|
||||
];
|
||||
|
||||
export function EngineSidebar() {
|
||||
return <Sidebar links={links} />;
|
||||
}
|
||||
|
||||
export function EngineMobileSidebar() {
|
||||
const pathname = usePathname();
|
||||
const activeLink = links.find((link) => pathname === link.href);
|
||||
return (
|
||||
<MobileSidebar
|
||||
links={links}
|
||||
trigger={
|
||||
<Button
|
||||
className="w-full lg:hidden text-left justify-between gap-2 mb-6"
|
||||
variant="outline"
|
||||
>
|
||||
{activeLink?.label || "Connect"}
|
||||
<ChevronDownIcon className="size-5 text-muted-foreground" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -24,7 +24,6 @@ export interface AppShellProps {
|
||||
layout?: "custom-contract";
|
||||
noSEOOverride?: boolean;
|
||||
hasSidebar?: boolean;
|
||||
noOverflowX?: boolean;
|
||||
pageContainerClassName?: string;
|
||||
mainClassName?: string;
|
||||
}
|
||||
@@ -33,7 +32,6 @@ export const AppShell: ComponentWithChildren<AppShellProps> = ({
|
||||
children,
|
||||
layout,
|
||||
hasSidebar,
|
||||
noOverflowX,
|
||||
pageContainerClassName,
|
||||
mainClassName,
|
||||
}) => {
|
||||
@@ -66,7 +64,6 @@ export const AppShell: ComponentWithChildren<AppShellProps> = ({
|
||||
as="main"
|
||||
colSpan={{ base: 2, md: 1 }}
|
||||
rowSpan={1}
|
||||
overflowX={noOverflowX ? undefined : "auto"}
|
||||
className={mainClassName}
|
||||
>
|
||||
<Container maxW="container.page">
|
||||
@@ -188,7 +185,7 @@ const AppHeader: React.FC = () => {
|
||||
isActive: pathname === "/dashboard",
|
||||
},
|
||||
{
|
||||
href: "/dashboard/connect",
|
||||
href: "/dashboard/connect/analytics",
|
||||
name: "Connect",
|
||||
isActive: pathname.startsWith("/dashboard/connect"),
|
||||
},
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { Spinner } from "@/components/ui/Spinner/Spinner";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -163,75 +162,51 @@ export const PublishWithVersionPage: React.FC<PublishWithVersionPageProps> = ({
|
||||
if (isDeploy) {
|
||||
const showLoading = !deployContractId || !publishedContract;
|
||||
return (
|
||||
<div className="flex gap-2">
|
||||
{/* Left */}
|
||||
<Sidebar
|
||||
header={<div className="font-semibold text-lg mb-4">Contracts</div>}
|
||||
links={[
|
||||
{ href: "/dashboard/contracts/deploy", label: "Deploy" },
|
||||
{
|
||||
href: "/dashboard/contracts/publish",
|
||||
label: "Publish",
|
||||
},
|
||||
{
|
||||
href: "/explore",
|
||||
label: "Explore",
|
||||
},
|
||||
{
|
||||
href: "/trending",
|
||||
label: "Trending",
|
||||
},
|
||||
{ href: "/dashboard/contracts/build", label: "Build" },
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Right */}
|
||||
<div className="flex-1">
|
||||
{/* header */}
|
||||
<div className="py-6 flex flex-col gap-4 border-b border-border md:py-12">
|
||||
<div className="flex flex-col md:flex-row justify-between gap-6 md:items-center">
|
||||
{contractInfo}
|
||||
<div className="flex flex-col-reverse md:flex-row gap-3">
|
||||
{versionSelector}
|
||||
<div className="flex gap-3">
|
||||
<Button asChild variant="outline">
|
||||
<Link
|
||||
href={`${pathname?.replace("/deploy", "") + (stringifiedSearchParams ? `?${stringifiedSearchParams}` : "")}`}
|
||||
target="_blank"
|
||||
>
|
||||
Contract
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
shareLink({
|
||||
title: `Deploy ${contractNameDisplay}`,
|
||||
});
|
||||
}}
|
||||
<div className="flex-1">
|
||||
{/* header */}
|
||||
<div className="pb-6 flex flex-col gap-4 border-b border-border md:pb-8">
|
||||
<div className="flex flex-col md:flex-row justify-between gap-6 md:items-center">
|
||||
{contractInfo}
|
||||
<div className="flex flex-col-reverse md:flex-row gap-3">
|
||||
{versionSelector}
|
||||
<div className="flex gap-3">
|
||||
<Button asChild variant="outline">
|
||||
<Link
|
||||
href={`${pathname?.replace("/deploy", "") + (stringifiedSearchParams ? `?${stringifiedSearchParams}` : "")}`}
|
||||
target="_blank"
|
||||
>
|
||||
Share
|
||||
</Button>
|
||||
</div>
|
||||
Contract
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
shareLink({
|
||||
title: `Deploy ${contractNameDisplay}`,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Share
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{modulesList}
|
||||
</div>
|
||||
{modulesList}
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="pt-6 md:pt-10">
|
||||
{showLoading ? (
|
||||
<div className="h-[300px] flex items-center justify-center">
|
||||
<Spinner className="size-10" />
|
||||
</div>
|
||||
) : (
|
||||
<ContractDeployForm
|
||||
contractId={deployContractId}
|
||||
version={publishedContract.version || "latest"}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/* Content */}
|
||||
<div className="pt-6 md:pt-10">
|
||||
{showLoading ? (
|
||||
<div className="h-[300px] flex items-center justify-center">
|
||||
<Spinner className="size-10" />
|
||||
</div>
|
||||
) : (
|
||||
<ContractDeployForm
|
||||
contractId={deployContractId}
|
||||
version={publishedContract.version || "latest"}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -240,7 +215,7 @@ export const PublishWithVersionPage: React.FC<PublishWithVersionPageProps> = ({
|
||||
return (
|
||||
<Flex direction="column" gap={{ base: 6, md: 10 }}>
|
||||
{/* Header */}
|
||||
<div className="py-2 flex flex-col gap-4 md:pt-8 md:pb-0">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col md:flex-row justify-between gap-6">
|
||||
{contractInfo}
|
||||
<div className="flex gap-3">
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { SidebarNav } from "./nav";
|
||||
import type { Route } from "./types";
|
||||
|
||||
type ConnectSidebarProps = {
|
||||
activePage:
|
||||
| "playground"
|
||||
| "analytics"
|
||||
| "embedded-wallets"
|
||||
| "account-abstraction"
|
||||
| "payments-contracts"
|
||||
| "payments-settings"
|
||||
| "pay-settings";
|
||||
};
|
||||
|
||||
const links: Route[] = [
|
||||
{
|
||||
path: "/dashboard/connect/analytics",
|
||||
title: "Analytics",
|
||||
name: "analytics",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/connect/in-app-wallets",
|
||||
title: "In-App Wallets",
|
||||
name: "embedded-wallets",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/connect/ecosystem",
|
||||
title: "Ecosystem Wallets",
|
||||
name: "ecosystem",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/connect/account-abstraction",
|
||||
title: "Account Abstraction",
|
||||
name: "account-abstraction",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/connect/pay",
|
||||
title: "Pay",
|
||||
name: "pay-settings",
|
||||
},
|
||||
{
|
||||
name: "playground",
|
||||
title: "Playground",
|
||||
path: "https://playground.thirdweb.com/connect/sign-in/button",
|
||||
},
|
||||
];
|
||||
|
||||
export const ConnectSidebar: React.FC<ConnectSidebarProps> = ({
|
||||
activePage,
|
||||
}) => {
|
||||
return <SidebarNav links={links} activePage={activePage} title="Connect" />;
|
||||
};
|
||||
@@ -1,32 +1,32 @@
|
||||
import { SidebarNav } from "./nav";
|
||||
import type { Route } from "./types";
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
|
||||
type ContractsSidebarProps = {
|
||||
activePage?: "build" | "explore" | "deploy" | "publish";
|
||||
};
|
||||
|
||||
const links: Route[] = [
|
||||
{ path: "/dashboard/contracts/deploy", title: "Deploy", name: "deploy" },
|
||||
{
|
||||
path: "/dashboard/contracts/publish",
|
||||
title: "Publish",
|
||||
name: "publish",
|
||||
},
|
||||
{
|
||||
path: "/explore",
|
||||
title: "Explore",
|
||||
name: "explore",
|
||||
},
|
||||
{
|
||||
path: "/trending",
|
||||
title: "Trending",
|
||||
name: "trending",
|
||||
},
|
||||
{ path: "/dashboard/contracts/build", title: "Build", name: "build" },
|
||||
];
|
||||
|
||||
export const ContractsSidebar: React.FC<ContractsSidebarProps> = ({
|
||||
activePage,
|
||||
export const ContractsSidebarLayout = (props: {
|
||||
children: React.ReactNode;
|
||||
desktopSidebarClassName?: string;
|
||||
mobileSidebarClassName?: string;
|
||||
}) => {
|
||||
return <SidebarNav links={links} activePage={activePage} title="Contracts" />;
|
||||
return (
|
||||
<SidebarLayout
|
||||
desktopSidebarClassName={props.desktopSidebarClassName}
|
||||
mobileSidebarClassName={props.mobileSidebarClassName}
|
||||
sidebarLinks={[
|
||||
{ href: "/dashboard/contracts/deploy", label: "Deploy" },
|
||||
{
|
||||
href: "/dashboard/contracts/publish",
|
||||
label: "Publish",
|
||||
},
|
||||
{
|
||||
href: "/explore",
|
||||
label: "Explore",
|
||||
},
|
||||
{ href: "/dashboard/contracts/build", label: "Build" },
|
||||
{
|
||||
href: "/trending",
|
||||
label: "Trending",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</SidebarLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,51 +1,36 @@
|
||||
import { SidebarNav } from "./nav";
|
||||
import type { Route } from "./types";
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
|
||||
type SettingsSidebarProps = {
|
||||
activePage:
|
||||
| "apiKeys"
|
||||
| "apiKey"
|
||||
| "devices"
|
||||
| "usage"
|
||||
| "storage"
|
||||
| "billing"
|
||||
| "notifications"
|
||||
| "gas-credits";
|
||||
};
|
||||
|
||||
const links: Route[] = [
|
||||
{
|
||||
path: "/dashboard/settings/api-keys",
|
||||
subActivePath: true,
|
||||
title: "API Keys",
|
||||
name: "apiKeys",
|
||||
},
|
||||
{ path: "/dashboard/settings/devices", title: "Devices", name: "devices" },
|
||||
{
|
||||
path: "/dashboard/settings/billing",
|
||||
title: "Billing",
|
||||
name: "billing",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/settings/gas-credits",
|
||||
title: "Gas Credits",
|
||||
name: "gas-credits",
|
||||
},
|
||||
{ path: "/dashboard/settings/usage", title: "Usage", name: "usage" },
|
||||
{
|
||||
path: "/dashboard/settings/storage",
|
||||
title: "Storage",
|
||||
name: "storage",
|
||||
},
|
||||
{
|
||||
path: "/dashboard/settings/notifications",
|
||||
title: "Notifications",
|
||||
name: "notifications",
|
||||
},
|
||||
];
|
||||
|
||||
export const SettingsSidebar: React.FC<SettingsSidebarProps> = ({
|
||||
activePage,
|
||||
export const SettingsSidebarLayout = (props: {
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
return <SidebarNav links={links} activePage={activePage} title="Settings" />;
|
||||
return (
|
||||
<SidebarLayout
|
||||
sidebarLinks={[
|
||||
{
|
||||
href: "/dashboard/settings/api-keys",
|
||||
label: "API Keys",
|
||||
},
|
||||
{ href: "/dashboard/settings/devices", label: "Devices" },
|
||||
{
|
||||
href: "/dashboard/settings/billing",
|
||||
label: "Billing",
|
||||
},
|
||||
{
|
||||
href: "/dashboard/settings/gas-credits",
|
||||
label: "Gas Credits",
|
||||
},
|
||||
{ href: "/dashboard/settings/usage", label: "Usage" },
|
||||
{
|
||||
href: "/dashboard/settings/storage",
|
||||
label: "Storage",
|
||||
},
|
||||
{
|
||||
href: "/dashboard/settings/notifications",
|
||||
label: "Notifications",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</SidebarLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ import { SmartWalletsBillingAlert } from "components/settings/ApiKeys/Alerts";
|
||||
import { ApiKeysMenu } from "components/settings/ApiKeys/Menu";
|
||||
import { NoApiKeys } from "components/settings/ApiKeys/NoApiKeys";
|
||||
import { SmartWallets } from "components/smart-wallets";
|
||||
import { ConnectSidebar } from "core-ui/sidebar/connect";
|
||||
import { getAbsoluteUrl } from "lib/vercel-utils";
|
||||
import { CircleAlertIcon } from "lucide-react";
|
||||
import { NextSeo } from "next-seo";
|
||||
@@ -23,6 +22,7 @@ import { useMemo, useState } from "react";
|
||||
import { useActiveWalletChain } from "thirdweb/react";
|
||||
import {} from "tw-components";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { ConnectSidebarLayout } from "../../../app/(dashboard)/dashboard/connect/DashboardConnectLayout";
|
||||
import { AAFooterSection } from "../../../app/team/[team_slug]/[project_slug]/connect/account-abstraction/AAFooterSection";
|
||||
import { isOpChainId } from "../../../app/team/[team_slug]/[project_slug]/connect/account-abstraction/isOpChain";
|
||||
|
||||
@@ -181,9 +181,12 @@ const DashboardConnectAccountAbstraction: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
DashboardConnectAccountAbstraction.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ConnectSidebar activePage="account-abstraction" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ConnectSidebarLayout>{page}</ConnectSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ import { type ApiKey, useApiKeys } from "@3rdweb-sdk/react/hooks/useApi";
|
||||
import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser";
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { ApiKeysMenu } from "components/settings/ApiKeys/Menu";
|
||||
import { ConnectSidebar } from "core-ui/sidebar/connect";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { PageId } from "page-id";
|
||||
import { useMemo, useState } from "react";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { ConnectSidebarLayout } from "../../../app/(dashboard)/dashboard/connect/DashboardConnectLayout";
|
||||
import { ConnectAnalyticsDashboard } from "../../../app/team/[team_slug]/[project_slug]/connect/analytics/ConnectAnalyticsDashboard";
|
||||
import { ConnectSDKCard } from "../../../app/team/[team_slug]/[project_slug]/connect/analytics/_components/ConnectSDKCard";
|
||||
|
||||
@@ -101,9 +101,12 @@ function NoAPIFoundCard() {
|
||||
}
|
||||
|
||||
DashboardConnectAnalytics.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ConnectSidebar activePage="analytics" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ConnectSidebarLayout>{page}</ConnectSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@ import { AppLayout } from "components/app-layouts/app";
|
||||
import { EmbeddedWallets } from "components/embedded-wallets";
|
||||
import { ApiKeysMenu } from "components/settings/ApiKeys/Menu";
|
||||
import { NoApiKeys } from "components/settings/ApiKeys/NoApiKeys";
|
||||
import { ConnectSidebar } from "core-ui/sidebar/connect";
|
||||
// import { ConnectSidebar } from "core-ui/sidebar/connect";
|
||||
import { useRouter } from "next/router";
|
||||
import { PageId } from "page-id";
|
||||
import { useMemo, useState } from "react";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { ConnectSidebarLayout } from "../../../app/(dashboard)/dashboard/connect/DashboardConnectLayout";
|
||||
import { AnalyticsCallout } from "../../../app/team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/AnalyticsCallout";
|
||||
import { InAppWaletFooterSection } from "../../../app/team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/footer";
|
||||
|
||||
@@ -122,9 +123,12 @@ const DashboardConnectEmbeddedWallets: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
DashboardConnectEmbeddedWallets.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ConnectSidebar activePage="embedded-wallets" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ConnectSidebarLayout>{page}</ConnectSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Flex, ListItem, UnorderedList } from "@chakra-ui/react";
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { ContractsSidebar } from "core-ui/sidebar/contracts";
|
||||
import { ContractsSidebarLayout } from "core-ui/sidebar/contracts";
|
||||
import { PageId } from "page-id";
|
||||
import {
|
||||
CodeBlock,
|
||||
@@ -83,9 +83,12 @@ const DashboardContractsBuild: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
DashboardContractsBuild.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ContractsSidebar activePage="build" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ContractsSidebarLayout> {page} </ContractsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
DashboardContractsBuild.pageId = PageId.DashboardContractsBuild;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Spinner } from "@/components/ui/Spinner/Spinner";
|
||||
import { useAllContractList } from "@3rdweb-sdk/react/hooks/useRegistry";
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { DeployedContracts } from "components/contract-components/tables/deployed-contracts";
|
||||
import { ContractsSidebar } from "core-ui/sidebar/contracts";
|
||||
import { ContractsSidebarLayout } from "core-ui/sidebar/contracts";
|
||||
import { PageId } from "page-id";
|
||||
import { useActiveAccount } from "thirdweb/react";
|
||||
import { GetStartedWithContractsDeploy } from "../../../app/team/[team_slug]/[project_slug]/contracts/_components/GetStartedWithContractsDeploy";
|
||||
@@ -31,9 +31,12 @@ const Contracts: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
Contracts.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ContractsSidebar activePage="deploy" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ContractsSidebarLayout> {page} </ContractsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
Contracts.pageId = PageId.Contracts;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { usePublishedContractsQuery } from "components/contract-components/hooks
|
||||
import { PublishedContracts } from "components/contract-components/tables/published-contracts";
|
||||
import { StepsCard } from "components/dashboard/StepsCard";
|
||||
import { PublisherSDKContext } from "contexts/custom-sdk-context";
|
||||
import { ContractsSidebar } from "core-ui/sidebar/contracts";
|
||||
import { ContractsSidebarLayout } from "core-ui/sidebar/contracts";
|
||||
import { PageId } from "page-id";
|
||||
import { useMemo } from "react";
|
||||
import { useActiveAccount } from "thirdweb/react";
|
||||
@@ -79,9 +79,12 @@ const Published: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
Published.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<ContractsSidebar activePage="publish" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ContractsSidebarLayout> {page} </ContractsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
Published.pageId = PageId.Contracts;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser";
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { ApiKeyDetails } from "components/settings/ApiKeys/Details";
|
||||
import { EditApiKey } from "components/settings/ApiKeys/Edit";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { useRouter } from "next/router";
|
||||
import { PageId } from "page-id";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
@@ -43,9 +43,12 @@ const SettingsApiKeyPage: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
SettingsApiKeyPage.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="apiKey" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AppLayout } from "components/app-layouts/app";
|
||||
import { ApiKeys } from "components/settings/ApiKeys";
|
||||
import { SmartWalletsBillingAlert } from "components/settings/ApiKeys/Alerts";
|
||||
import { CreateApiKeyButton } from "components/settings/ApiKeys/Create";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import { useMemo } from "react";
|
||||
import { Link } from "tw-components";
|
||||
@@ -74,9 +74,12 @@ const SettingsApiKeysPage: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
SettingsApiKeysPage.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="apiKeys" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { SettingsBillingPage } from "../../../app/team/[team_slug]/(team)/~/settings/billing/BillingSettingsPage";
|
||||
@@ -11,10 +11,12 @@ const Page: ThirdwebNextPage = () => {
|
||||
Page.pageId = PageId.SettingsUsage;
|
||||
|
||||
Page.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="billing" />
|
||||
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useAuthorizedWallets } from "@3rdweb-sdk/react/hooks/useApi";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { AuthorizedWalletsTable } from "components/settings/AuthorizedWallets/AuthorizedWalletsTable";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import { Heading, Text } from "tw-components";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
@@ -38,10 +38,12 @@ const SettingsDevicesPage: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
SettingsDevicesPage.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="devices" />
|
||||
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import {} from "tw-components";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
@@ -10,9 +10,12 @@ const Page: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
Page.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="gas-credits" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { SettingsNotificationsPage } from "../../../app/team/[team_slug]/(team)/~/settings/notifications/NotificationsPage";
|
||||
import { SettingsSidebarLayout } from "../../../core-ui/sidebar/settings";
|
||||
|
||||
const Page: ThirdwebNextPage = () => {
|
||||
return <SettingsNotificationsPage />;
|
||||
};
|
||||
|
||||
Page.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="notifications" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ import type { CodeEnvironment } from "components/contract-tabs/code/types";
|
||||
import { RelevantDataSection } from "components/dashboard/RelevantDataSection";
|
||||
import { IpfsUploadDropzone } from "components/ipfs-upload/dropzone";
|
||||
import { YourFilesSection } from "components/storage/your-files";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { NextSeo } from "next-seo";
|
||||
import { PageId } from "page-id";
|
||||
import { useState } from "react";
|
||||
import { Card, Heading, Link, Text, TrackedCopyButton } from "tw-components";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { SettingsSidebarLayout } from "../../../core-ui/sidebar/settings";
|
||||
|
||||
const TRACKING_CATEGORY = "storage";
|
||||
|
||||
@@ -247,7 +247,7 @@ function App() {
|
||||
);
|
||||
}`,
|
||||
javascript: `// Check out the latest docs here: https://portal.thirdweb.com/typescript/v5/storage
|
||||
|
||||
|
||||
import { upload } from "thirdweb/storage";
|
||||
|
||||
// Here we get the IPFS URI of where our metadata has been uploaded
|
||||
@@ -289,9 +289,12 @@ var response = await ThirdwebManager.Instance.SDK.storage.UploadText(metaJson);`
|
||||
};
|
||||
|
||||
DashboardSettingsStorage.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="storage" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
DashboardSettingsStorage.pageId = PageId.DashboardSettingsStorage;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AppLayout } from "components/app-layouts/app";
|
||||
import { SettingsSidebar } from "core-ui/sidebar/settings";
|
||||
import { SettingsSidebarLayout } from "core-ui/sidebar/settings";
|
||||
import { PageId } from "page-id";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { SettingsUsagePage } from "../../../app/team/[team_slug]/(team)/~/usage/UsagePage";
|
||||
@@ -9,9 +9,12 @@ const Page: ThirdwebNextPage = () => {
|
||||
};
|
||||
|
||||
Page.getLayout = (page, props) => (
|
||||
<AppLayout {...props} hasSidebar={true}>
|
||||
<SettingsSidebar activePage="usage" />
|
||||
{page}
|
||||
<AppLayout
|
||||
{...props}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<SettingsSidebarLayout>{page}</SettingsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import { ContractRow } from "components/explore/contract-row";
|
||||
import { DeployUpsellCard } from "components/explore/upsells/deploy-your-own";
|
||||
import { PublishUpsellCard } from "components/explore/upsells/publish-submit";
|
||||
import { PublisherSDKContext } from "contexts/custom-sdk-context";
|
||||
import { ContractsSidebar } from "core-ui/sidebar/contracts";
|
||||
import {
|
||||
EXPLORE_PAGE_DATA,
|
||||
type ExploreCategory,
|
||||
@@ -15,6 +14,7 @@ import { NextSeo } from "next-seo";
|
||||
import { PageId } from "page-id";
|
||||
import { Fragment } from "react";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { ContractsSidebarLayout } from "../../core-ui/sidebar/contracts";
|
||||
|
||||
const ExplorePage: ThirdwebNextPage = (
|
||||
props: InferGetStaticPropsType<typeof getStaticProps>,
|
||||
@@ -40,8 +40,10 @@ const ExplorePage: ThirdwebNextPage = (
|
||||
/>
|
||||
|
||||
<div>
|
||||
<h1 className="mb-3 text-5xl font-bold tracking-tighter">Explore</h1>
|
||||
<p className="text-lg text-muted-foreground max-w-screen-md">
|
||||
<h1 className="mb-3 text-3xl lg:text-5xl font-bold tracking-tighter">
|
||||
Explore
|
||||
</h1>
|
||||
<p className="text-base lg:text-lg text-muted-foreground max-w-screen-md">
|
||||
The best place for web3 developers to explore smart contracts from
|
||||
world-class web3 protocols & engineers — all deployable with one
|
||||
click.
|
||||
@@ -72,9 +74,15 @@ const ExplorePage: ThirdwebNextPage = (
|
||||
// );
|
||||
|
||||
ExplorePage.getLayout = (page, props) => (
|
||||
<AppLayout {...props} noSEOOverride hasSidebar>
|
||||
<ContractsSidebar activePage="explore" />
|
||||
<PublisherSDKContext>{page}</PublisherSDKContext>
|
||||
<AppLayout
|
||||
{...props}
|
||||
noSEOOverride
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
<ContractsSidebarLayout>
|
||||
<PublisherSDKContext>{page}</PublisherSDKContext>
|
||||
</ContractsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { PageId } from "page-id";
|
||||
import { polygon } from "thirdweb/chains";
|
||||
import { getAddress, isAddress } from "thirdweb/utils";
|
||||
import type { ThirdwebNextPage } from "utils/types";
|
||||
import { ContractsSidebar } from "../../core-ui/sidebar/contracts";
|
||||
import { ContractsSidebarLayout } from "../../core-ui/sidebar/contracts";
|
||||
|
||||
type PublishPageProps = {
|
||||
dehydratedState: DehydratedState;
|
||||
@@ -49,13 +49,12 @@ PublishPage.getLayout = (page, props: PublishPageProps) => {
|
||||
return (
|
||||
<AppLayout
|
||||
dehydratedState={props.dehydratedState}
|
||||
noOverflowX
|
||||
pageContainerClassName={props.isDeploy ? "!container" : ""}
|
||||
mainClassName={props.isDeploy ? "!pt-0" : ""}
|
||||
hasSidebar={!props.isDeploy}
|
||||
pageContainerClassName="!max-w-full !px-0"
|
||||
mainClassName="!pt-0"
|
||||
>
|
||||
{!props.isDeploy && <ContractsSidebar />}
|
||||
{page}
|
||||
<ContractsSidebarLayout mobileSidebarClassName="hidden">
|
||||
{page}
|
||||
</ContractsSidebarLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user