Sidebar and team header cleanups (#4612)
## Problem solved
Short description of the bug fixed or feature added
<!-- start pr-codex -->
---
## PR-Codex overview
The focus of this PR is to refactor layout components and improve sidebar navigation in the dashboard app.
### Detailed summary
- Refactored layout components for better structure
- Updated sidebar navigation in various pages
- Improved handling of sidebar links and layout components
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
This commit is contained in:
@@ -18,7 +18,7 @@ export function SettingsCard(props: {
|
||||
};
|
||||
}) {
|
||||
return (
|
||||
<div className="border rounded-lg bg-muted/50 relative">
|
||||
<div className="border border-border rounded-lg bg-muted/50 relative">
|
||||
<div
|
||||
className={cn(
|
||||
"border-b border-border px-4 lg:px-6 py-6 relative",
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ export function AccountAbstractionPage(props: {
|
||||
const isOpChain = chain?.id ? isOpChainId(chain.id) : false;
|
||||
|
||||
return (
|
||||
<div className="max-sm:pt-6 pb-10">
|
||||
<div>
|
||||
<h1 className="text-2xl lg:text-3xl font-semibold tracking-tight mb-1">
|
||||
Account Abstraction
|
||||
</h1>
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function Page(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pb-10 max-sm:pt-6">
|
||||
<div>
|
||||
<div>
|
||||
<h1 className="text-2xl md:text-3xl font-semibold tracking-tight mb-1">
|
||||
Connect Analytics
|
||||
|
||||
@@ -5,11 +5,9 @@ export default async function Page(props: {
|
||||
}) {
|
||||
const { team_slug, project_slug } = props.params;
|
||||
return (
|
||||
<div className="max-sm:pt-6">
|
||||
<EcosystemLandingPage
|
||||
ecosystemLayoutPath={`/team/${team_slug}/${project_slug}/connect/ecosystem`}
|
||||
/>
|
||||
</div>
|
||||
<EcosystemLandingPage
|
||||
ecosystemLayoutPath={`/team/${team_slug}/${project_slug}/connect/ecosystem`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ export default async function Page(props: {
|
||||
const TRACKING_CATEGORY = "team/in-app-wallets";
|
||||
|
||||
return (
|
||||
<div className="pb-10 max-sm:pt-6">
|
||||
<div>
|
||||
<h1 className="font-semibold text-2xl md:text-3xl tracking-tight mb-3">
|
||||
In-App Wallets
|
||||
</h1>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
|
||||
export default function Layout(props: {
|
||||
params: {
|
||||
@@ -37,13 +36,5 @@ export default function Layout(props: {
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="h-full container flex gap-4">
|
||||
<Sidebar links={links} />
|
||||
<div className="grow py-6 max-sm:w-full">
|
||||
<MobileSidebar links={links} triggerClassName="max-sm:mb-6" />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <SidebarLayout sidebarLinks={links}>{props.children}</SidebarLayout>;
|
||||
}
|
||||
|
||||
@@ -19,35 +19,33 @@ export default async function Page(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-sm:pt-6 pb-10">
|
||||
<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-[700px]">
|
||||
<h1 className="text-3xl md:text-4xl tracking-tight font-bold mb-3">
|
||||
Pay
|
||||
</h1>
|
||||
<p className="text-sm md:text-base text-muted-foreground leading-relaxed">
|
||||
Pay allows your users to purchase cryptocurrencies and execute
|
||||
transactions with their credit card or debit card, or with any
|
||||
token via cross-chain routing.{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://portal.thirdweb.com/connect/pay/overview"
|
||||
className="!text-link-foreground"
|
||||
>
|
||||
Learn more
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
<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-[700px]">
|
||||
<h1 className="text-3xl md:text-4xl tracking-tight font-bold mb-3">
|
||||
Pay
|
||||
</h1>
|
||||
<p className="text-sm md:text-base text-muted-foreground leading-relaxed">
|
||||
Pay allows your users to purchase cryptocurrencies and execute
|
||||
transactions with their credit card or debit card, or with any token
|
||||
via cross-chain routing.{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://portal.thirdweb.com/connect/pay/overview"
|
||||
className="!text-link-foreground"
|
||||
>
|
||||
Learn more
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<PayPageUI
|
||||
apiKey={{
|
||||
...project,
|
||||
key: project.publishableKey, // clientId
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PayPageUI
|
||||
apiKey={{
|
||||
...project,
|
||||
key: project.publishableKey, // clientId
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
import type { SidebarLink } from "@/components/blocks/Sidebar";
|
||||
|
||||
export function getEngineGeneralSidebarLinks(
|
||||
linkPrefix: string,
|
||||
): SidebarLink[] {
|
||||
return [
|
||||
{
|
||||
label: "Overview",
|
||||
href: `${linkPrefix}`,
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
label: "Create",
|
||||
href: `${linkPrefix}/create`,
|
||||
},
|
||||
{
|
||||
label: "Import",
|
||||
href: `${linkPrefix}/import`,
|
||||
},
|
||||
];
|
||||
}
|
||||
+18
-11
@@ -1,6 +1,5 @@
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar } from "@/components/blocks/Sidebar";
|
||||
import { getEngineGeneralSidebarLinks } from "./getEngineGeneralSidebarLinks";
|
||||
import type { SidebarLink } from "@/components/blocks/Sidebar";
|
||||
import { SidebarLayout } from "@/components/blocks/SidebarLayout";
|
||||
|
||||
export default function Layout(props: {
|
||||
params: {
|
||||
@@ -11,15 +10,23 @@ export default function Layout(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const linkPrefix = `/team/${props.params.team_slug}/${props.params.project_slug}/engine`;
|
||||
const sidebarLinks = getEngineGeneralSidebarLinks(linkPrefix);
|
||||
const sidebarLinks: SidebarLink[] = [
|
||||
{
|
||||
label: "Overview",
|
||||
href: `${linkPrefix}`,
|
||||
exactMatch: true,
|
||||
},
|
||||
{
|
||||
label: "Create",
|
||||
href: `${linkPrefix}/create`,
|
||||
},
|
||||
{
|
||||
label: "Import",
|
||||
href: `${linkPrefix}/import`,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="container flex gap-6">
|
||||
<Sidebar links={sidebarLinks} />
|
||||
<div className="pt-6 grow max-sm:w-full">
|
||||
<MobileSidebar links={sidebarLinks} triggerClassName="max-sm:mb-6" />
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
<SidebarLayout sidebarLinks={sidebarLinks}>{props.children}</SidebarLayout>
|
||||
);
|
||||
}
|
||||
|
||||
+9
-1
@@ -34,7 +34,15 @@ export function ProjectSelectorMobileMenuButton(
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent dialogCloseClassName="hidden" className="p-0">
|
||||
<DialogContent
|
||||
dialogCloseClassName="hidden"
|
||||
className="p-0"
|
||||
onClick={(e) => {
|
||||
if (e.target instanceof HTMLAnchorElement) {
|
||||
setOpen(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DynamicHeight>
|
||||
<ProjectSelectorUI
|
||||
currentProject={props.currentProject}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function ProjectSelectorUI(props: {
|
||||
: projects;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col border-l fade-in-0 animate-in duration-300">
|
||||
<div className="flex flex-col border-l border-border fade-in-0 animate-in duration-300">
|
||||
<SearchInput
|
||||
placeholder="Search Projects"
|
||||
value={searchProjectTerm}
|
||||
@@ -74,7 +74,7 @@ export function ProjectSelectorUI(props: {
|
||||
</div>
|
||||
</ScrollShadow>
|
||||
|
||||
<div className="p-2 border-t">
|
||||
<div className="p-2 border-t border-border">
|
||||
<Button
|
||||
className="px-2 w-full gap-2 justify-start disabled:opacity-100 disabled:pointer-events-auto disabled:cursor-not-allowed"
|
||||
variant="ghost"
|
||||
|
||||
+5
@@ -65,6 +65,11 @@ export function TeamAndProjectSelectorPopoverButton(props: TeamSwitcherProps) {
|
||||
sideOffset={5}
|
||||
className="p-0 w-auto rounded-xl shadow-xl"
|
||||
align={props.focus === "project-selection" ? "center" : "start"}
|
||||
onClick={(e) => {
|
||||
if (e.target instanceof HTMLAnchorElement) {
|
||||
setOpen(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DynamicHeight>
|
||||
<div className="flex [&>div]:min-w-[280px] no-scrollbar">
|
||||
|
||||
@@ -109,7 +109,7 @@ export function TeamSelectionUI(props: {
|
||||
{/* TODO - what do we do on this button click? */}
|
||||
{/* Bottom */}
|
||||
{teamPlan && teamPlan !== "pro" && (
|
||||
<div className="p-2 border-t">
|
||||
<div className="p-2 border-t border-border">
|
||||
<Button
|
||||
variant="primary"
|
||||
className="w-full"
|
||||
|
||||
@@ -21,15 +21,13 @@ export function createEnginePage(
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container px-4">
|
||||
<EngineSidebarLayout rootPath="/dashboard/engine" engineId={engineId}>
|
||||
<WithEngineInstance
|
||||
engineId={engineId}
|
||||
content={PageContent}
|
||||
rootPath="/dashboard/engine"
|
||||
/>
|
||||
</EngineSidebarLayout>
|
||||
</div>
|
||||
<EngineSidebarLayout rootPath="/dashboard/engine" engineId={engineId}>
|
||||
<WithEngineInstance
|
||||
engineId={engineId}
|
||||
content={PageContent}
|
||||
rootPath="/dashboard/engine"
|
||||
/>
|
||||
</EngineSidebarLayout>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { MobileSidebar } from "@/components/blocks/MobileSidebar";
|
||||
import { Sidebar, type SidebarLink } from "@/components/blocks/Sidebar";
|
||||
import type { SidebarLink } from "@/components/blocks/Sidebar";
|
||||
import { CopyTextButton } from "@/components/ui/CopyTextButton";
|
||||
import { Spinner } from "@/components/ui/Spinner/Spinner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -11,10 +10,10 @@ import {
|
||||
type EngineInstance,
|
||||
useEngineInstances,
|
||||
} from "@3rdweb-sdk/react/hooks/useEngine";
|
||||
import { ArrowLeftIcon, ChevronDownIcon, CircleAlertIcon } from "lucide-react";
|
||||
import { ArrowLeftIcon, CircleAlertIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import invariant from "tiny-invariant";
|
||||
import { SidebarLayout } from "../../@/components/blocks/SidebarLayout";
|
||||
import { EngineVersionBadge } from "./badges/version";
|
||||
import { useHasEnginePermission } from "./useHasEnginePermission";
|
||||
|
||||
@@ -64,7 +63,6 @@ export function EngineSidebarLayout(props: {
|
||||
rootPath: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const links: SidebarLink[] = sidebarLinkMeta.map((linkMeta) => {
|
||||
return {
|
||||
href: `${props.rootPath}/${props.engineId}${linkMeta.pathId === "" ? "" : `/${linkMeta.pathId}`}`,
|
||||
@@ -78,29 +76,7 @@ export function EngineSidebarLayout(props: {
|
||||
};
|
||||
});
|
||||
|
||||
const activeLink = links.find((link) => pathname === link.href);
|
||||
|
||||
return (
|
||||
<div className="flex gap-6">
|
||||
<Sidebar links={links} />
|
||||
<div className="grow max-sm:w-full pt-6 pb-10">
|
||||
<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>
|
||||
}
|
||||
/>
|
||||
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <SidebarLayout sidebarLinks={links}>{props.children}</SidebarLayout>;
|
||||
}
|
||||
|
||||
export function WithEngineInstance(props: {
|
||||
|
||||
Reference in New Issue
Block a user