Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/dashboard/src/@/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ function useUnderline<El extends HTMLElement>() {
block: "nearest",
inline: "center",
});
} else if (lineRef.current) {
lineRef.current.style.width = "0px";
}
}

Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppFooter } from "@/components/blocks/app-footer";
import { DashboardHeader } from "app/components/Header/DashboardHeader";
import { ErrorProvider } from "../../contexts/error-handler";
import { DashboardHeader } from "../components/Header/DashboardHeader";

export default function DashboardLayout(props: { children: React.ReactNode }) {
return (
Expand Down
139 changes: 86 additions & 53 deletions apps/dashboard/src/app/components/Header/DashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,101 @@
import { ColorModeToggle } from "@/components/color-mode-toggle";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { NavLink } from "@/components/ui/NavLink";
import { Button } from "@/components/ui/button";
import { CustomConnectWallet } from "@3rdweb-sdk/react/components/connect-wallet";
import { ClientOnly } from "components/ClientOnly/ClientOnly";
import { CmdKSearch } from "components/cmd-k-search";
import { ColorModeToggle } from "components/color-mode/color-mode-toggle";
import { Logo } from "components/logo";
import { CreditsButton } from "components/settings/Account/Billing/CreditsButton";
import { UpgradeButton } from "components/settings/Account/Billing/UpgradeButton";
import { CircleHelpIcon } from "lucide-react";
import Link from "next/link";
import { ThirdwebMiniLogo } from "../ThirdwebMiniLogo";
import { NavLink } from "../nav-link.client";
import { MobileBurgerMenu } from "./MobileBurgerMenu";
import { headerLinks } from "./headerLinks";
import { Suspense } from "react";
import { DashboardHeaderTabs } from "./DashboardHeaderTabs";

export function DashboardHeader() {
export const DashboardHeader: React.FC = () => {
return (
// the "h-24" avoids layout shift when connecting wallet (connected wallet button is taller than disconnected...)
<header className="flex h-20 flex-shrink-0 flex-row items-center justify-between border-border border-b bg-muted/50 px-4 py-4 md:h-20 lg:px-6">
{/* Left */}
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<MobileBurgerMenu />
<div className="bg-muted/50">
<header className="flex items-center justify-between px-4 py-3 lg:px-6">
{/* left */}
<div className="flex items-center gap-4">
<Link href="/dashboard">
<ThirdwebMiniLogo className="h-6" />
<Logo hideWordmark />
</Link>
<CmdKSearch />
</div>

<div className="hidden items-center gap-2 md:flex">
{headerLinks.left.map((link) => (
<NavLink
key={link.href}
href={link.href}
target={link.href.startsWith("https") ? "_blank" : undefined}
className="px-[10px] py-2 font-normal text-muted-foreground text-sm hover:text-foreground"
activeClassName="font-medium text-foreground"
>
{link.name}
</NavLink>
))}
</div>
</div>
{/* Right */}
<div className="flex items-center gap-4">
<div className="items-center gap-2 lg:flex">
<div className="hidden items-center gap-2 lg:flex">
{headerLinks.right.map((link) => (
<Link
key={link.href}
href={link.href}
target={link.href.startsWith("https") ? "_blank" : undefined}
className="px-[10px] py-2 font-normal text-muted-foreground text-sm hover:text-foreground"
{/* Right */}
<div className="flex items-center gap-2">
<div className="hidden gap-2 md:flex">
<Suspense fallback={null}>
<CreditsButton />
</Suspense>
<UpgradeButton />
</div>

<HeaderNavLink
trackingLabel="chainlist"
href="/chainlist"
label="Chainlist"
/>

<HeaderNavLink
trackingLabel="docs"
href="https://portal.thirdweb.com"
label="Docs"
/>

<HeaderNavLink
trackingLabel="support"
href="/support"
label="Support"
/>

<div className="md:hidden">
<Button asChild variant="ghost">
<NavLink
className="fade-in-0 !h-auto !w-auto p-2"
href="/support"
tracking={{
category: "header",
action: "click",
label: "support",
}}
>
{link.name}
</Link>
))}
<CircleHelpIcon className="size-5" />
</NavLink>
</Button>
</div>

<ColorModeToggle />

<div className="md:ml-2">
<CustomConnectWallet />
</div>
</div>
</header>

<ClientOnly
ssr={
<div className="flex h-[48px] w-[144px] items-center justify-center rounded-lg border bg-muted/50">
<Spinner className="size-4" />
</div>
}
>
<CustomConnectWallet />
</ClientOnly>
</div>
</header>
<DashboardHeaderTabs />
</div>
);
};

function HeaderNavLink(props: {
label: string;
trackingLabel: string;
href: string;
}) {
return (
<NavLink
href={props.href}
tracking={{
category: "header",
action: "click",
label: props.trackingLabel,
}}
className="hidden px-2.5 text-muted-foreground text-sm hover:text-foreground md:block"
activeClassName="text-foreground"
>
{props.label}
</NavLink>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use client";

import { TabLinks } from "@/components/ui/tabs";
import { usePathname } from "next/navigation";

export function DashboardHeaderTabs() {
const pathname = usePathname() || "";
return (
<TabLinks
className="w-full"
tabContainerClassName="px-4"
shadowColor="transparent"
links={[
{
href: "/dashboard",
name: "Home",
isActive: pathname === "/dashboard",
},
{
href: "/dashboard/connect/analytics",
name: "Connect",
isActive: pathname.startsWith("/dashboard/connect"),
},
{
href: "/dashboard/contracts/deploy",
name: "Contracts",
isActive: pathname.startsWith("/dashboard/contracts"),
},
{
href: "/dashboard/engine",
name: "Engine",
isActive: pathname.startsWith("/dashboard/engine"),
},
{
href: "/dashboard/settings/api-keys",
name: "Settings",
isActive: pathname.startsWith("/dashboard/settings"),
},
]}
/>
);
}
66 changes: 0 additions & 66 deletions apps/dashboard/src/app/components/Header/MobileBurgerMenu.tsx

This file was deleted.

34 changes: 0 additions & 34 deletions apps/dashboard/src/app/components/Header/headerLinks.ts

This file was deleted.

29 changes: 0 additions & 29 deletions apps/dashboard/src/app/components/nav-link.client.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions apps/dashboard/src/components/cmd-k-search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ export const CmdKSearch: React.FC = () => {
</div>

<Button
className="p-2 lg:hidden"
className="!h-auto !w-auto p-2 lg:hidden"
aria-label="Search any contract"
variant="ghost"
onClick={() => setOpen(true)}
>
<SearchIcon className="size-4" />
<SearchIcon className="size-5" />
</Button>

<CmdKSearchModal open={open} setOpen={setOpen} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import { Button } from "@/components/ui/button";
import { SkeletonContainer } from "@/components/ui/skeleton";
import { useTheme } from "next-themes";
Expand All @@ -21,15 +23,15 @@ export const ColorModeToggle: React.FC = () => {
render={(v) => {
return (
<Button
className="fade-in-0 p-2 md:p-3"
className="fade-in-0 !h-auto !w-auto p-2 text-muted-foreground hover:text-foreground"
variant="ghost"
aria-label="toggle color"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
{v === "dark" ? (
<FiMoon className="size-4 md:size-5" />
<FiMoon className="size-5" />
) : (
<FiSun className="size-4 md:size-5" />
<FiSun className="size-5" />
)}
</Button>
);
Expand Down
Loading
Loading