mirror of
https://github.com/Such-Software/xmrcheckout.git
synced 2026-10-17 05:51:34 +02:00
ui: highlight active nav item
This commit is contained in:
@@ -4,6 +4,7 @@ import { Suspense } from "react";
|
|||||||
|
|
||||||
import "../(marketing)/marketing.css";
|
import "../(marketing)/marketing.css";
|
||||||
import DonateModal from "../../components/donate-modal";
|
import DonateModal from "../../components/donate-modal";
|
||||||
|
import NavLink from "../../components/nav-link";
|
||||||
import { logoutAction } from "./dashboard/actions";
|
import { logoutAction } from "./dashboard/actions";
|
||||||
|
|
||||||
export default function AppLayout({
|
export default function AppLayout({
|
||||||
@@ -30,10 +31,10 @@ export default function AppLayout({
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<nav className="nav">
|
<nav className="nav">
|
||||||
<Link href="/invoice">Check Invoice</Link>
|
<NavLink href="/invoice">Check Invoice</NavLink>
|
||||||
<Link href="/docs">Documentation</Link>
|
<NavLink href="/docs">Documentation</NavLink>
|
||||||
<Link href="/faq">FAQ</Link>
|
<NavLink href="/faq">FAQ</NavLink>
|
||||||
<Link href="/dashboard">Dashboard</Link>
|
<NavLink href="/dashboard">Dashboard</NavLink>
|
||||||
<form action={logoutAction}>
|
<form action={logoutAction}>
|
||||||
<button type="submit">Log out</button>
|
<button type="submit">Log out</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { cookies } from "next/headers";
|
|||||||
import "./marketing.css";
|
import "./marketing.css";
|
||||||
import DonateModal from "../../components/donate-modal";
|
import DonateModal from "../../components/donate-modal";
|
||||||
import LoginModal, { LoginTrigger } from "../../components/login-modal";
|
import LoginModal, { LoginTrigger } from "../../components/login-modal";
|
||||||
|
import NavLink from "../../components/nav-link";
|
||||||
import { logoutAction } from "../(app)/dashboard/actions";
|
import { logoutAction } from "../(app)/dashboard/actions";
|
||||||
|
|
||||||
export default async function MarketingLayout({
|
export default async function MarketingLayout({
|
||||||
@@ -42,13 +43,13 @@ export default async function MarketingLayout({
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<nav className="nav">
|
<nav className="nav">
|
||||||
<Link href="/invoice">Check Invoice</Link>
|
<NavLink href="/invoice">Check Invoice</NavLink>
|
||||||
<Link href="/tour">Tour</Link>
|
<NavLink href="/tour">Tour</NavLink>
|
||||||
<Link href="/docs">Documentation</Link>
|
<NavLink href="/docs">Documentation</NavLink>
|
||||||
<Link href="/faq">FAQ</Link>
|
<NavLink href="/faq">FAQ</NavLink>
|
||||||
{isAuthenticated ? (
|
{isAuthenticated ? (
|
||||||
<>
|
<>
|
||||||
<Link href="/dashboard">Dashboard</Link>
|
<NavLink href="/dashboard">Dashboard</NavLink>
|
||||||
<form action={logoutAction}>
|
<form action={logoutAction}>
|
||||||
<button type="submit">Log out</button>
|
<button type="submit">Log out</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -266,6 +266,24 @@ a {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav a[aria-current="page"] {
|
||||||
|
opacity: 1;
|
||||||
|
font-weight: 600;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav a[aria-current="page"]::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: -0.15rem;
|
||||||
|
right: -0.15rem;
|
||||||
|
bottom: -0.35rem;
|
||||||
|
height: 0.2rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(90deg, var(--clay), var(--sage));
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
.hero {
|
.hero {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import Link from "next/link";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
|
function normalizePath(path: string) {
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
return `/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path === "/") {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.replace(/\/+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function NavLink({
|
||||||
|
href,
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
exact,
|
||||||
|
}: {
|
||||||
|
href: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
exact?: boolean;
|
||||||
|
}) {
|
||||||
|
const pathname = usePathname() ?? "/";
|
||||||
|
const currentPath = normalizePath(pathname);
|
||||||
|
const targetPath = normalizePath(href);
|
||||||
|
|
||||||
|
const isActive = exact
|
||||||
|
? currentPath === targetPath
|
||||||
|
: currentPath === targetPath || currentPath.startsWith(`${targetPath}/`);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
href={href}
|
||||||
|
className={className}
|
||||||
|
aria-current={isActive ? "page" : undefined}
|
||||||
|
data-active={isActive ? "true" : undefined}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user