From 8f1b4ff6eeb21114aad5f39125cc9c4ac17810b1 Mon Sep 17 00:00:00 2001 From: luiznwz Date: Sat, 29 Aug 2026 12:58:36 -0300 Subject: [PATCH] feat: flat nav links, softer header radius, dashboard glyph above buttons --- src/components/nav/menus.tsx | 244 ------------------ src/components/navbar.tsx | 43 ++- .../dashboard/components/dashboard-view.tsx | 2 +- 3 files changed, 35 insertions(+), 254 deletions(-) delete mode 100644 src/components/nav/menus.tsx diff --git a/src/components/nav/menus.tsx b/src/components/nav/menus.tsx deleted file mode 100644 index 826e7e4..0000000 --- a/src/components/nav/menus.tsx +++ /dev/null @@ -1,244 +0,0 @@ -'use client' - -import { useT } from '@/lib/i18n' -import { cn } from '@/lib/utils' -import { ChevronDown, Code2, Library, Network, Trophy, Users } from 'lucide-react' -import { AnimatePresence, motion } from 'motion/react' -import Link from 'next/link' -import * as React from 'react' -import { copy } from './copy' - -type MenuItem = { - href: string - icon: typeof Code2 - title: string - desc: string - question: string -} - -// One open panel at a time: hovering another trigger switches instantly -// instead of letting the close-delay stack two panels on top of each other. -type MenuGroupCtx = { - active: string | null - open: (id: string) => void - scheduleClose: (id: string) => void - close: () => void -} - -const MenuGroupContext = React.createContext(null) - -export function NavMenuGroup({ children }: { children: React.ReactNode }) { - const [active, setActive] = React.useState(null) - const timer = React.useRef(null) - - const cancelClose = React.useCallback(() => { - if (timer.current !== null) { - window.clearTimeout(timer.current) - timer.current = null - } - }, []) - const open = React.useCallback( - (id: string) => { - cancelClose() - setActive(id) - }, - [cancelClose], - ) - const scheduleClose = React.useCallback( - (id: string) => { - cancelClose() - timer.current = window.setTimeout(() => { - setActive((cur) => (cur === id ? null : cur)) - }, 140) - }, - [cancelClose], - ) - const close = React.useCallback(() => { - cancelClose() - setActive(null) - }, [cancelClose]) - - React.useEffect(() => cancelClose, [cancelClose]) - - const ctx = React.useMemo( - () => ({ active, open, scheduleClose, close }), - [active, open, scheduleClose, close], - ) - return ( - - {children} - - ) -} - -function NavMenu({ - id, - label, - items, - footer, -}: { - id: string - label: string - items: MenuItem[] - footer: { href: string; label: string } -}) { - const group = React.useContext(MenuGroupContext) - const ref = React.useRef(null) - const open = group?.active === id - - React.useEffect(() => { - if (!open || !group) return - function onPointerDown(e: PointerEvent) { - if (ref.current && !ref.current.contains(e.target as Node)) { - group?.close() - } - } - function onKeyDown(e: KeyboardEvent) { - if (e.key === 'Escape') group?.close() - } - document.addEventListener('pointerdown', onPointerDown) - document.addEventListener('keydown', onKeyDown) - return () => { - document.removeEventListener('pointerdown', onPointerDown) - document.removeEventListener('keydown', onKeyDown) - } - }, [open, group]) - - if (!group) return null - - return ( -
group.open(id)} - onMouseLeave={() => group.scheduleClose(id)} - > - - - {open && ( - -
- {items.map((item) => ( - - - - - - - {item.title} - - - {item.desc} - - - {item.question} - - - - ))} -
- - {footer.label} → - -
- )} -
-
- ) -} - -export function TrainMenu({ loggedIn }: { loggedIn: boolean }) { - const t = useT(copy) - return ( - - ) -} - -export function CommunityMenu() { - const t = useT(copy) - return ( - - ) -} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 3d4eacd..1a189d6 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -15,7 +15,6 @@ import Link from 'next/link' import * as React from 'react' import { Logo } from './logo' import { copy } from './nav/copy' -import { CommunityMenu, NavMenuGroup, TrainMenu } from './nav/menus' import { MobileMenu } from './nav/mobile-menu' import { StatusCluster, @@ -25,11 +24,22 @@ import { } from './nav/status-cluster' import { Button } from './ui/button' -function NavLink({ href, label }: { href: string; label: string }) { +function NavLink({ + href, + label, + className, +}: { + href: string + label: string + className?: string +}) { return ( {label} @@ -80,7 +90,7 @@ export function Navbar() { >
-
diff --git a/src/features/dashboard/components/dashboard-view.tsx b/src/features/dashboard/components/dashboard-view.tsx index c01dec3..2b66800 100644 --- a/src/features/dashboard/components/dashboard-view.tsx +++ b/src/features/dashboard/components/dashboard-view.tsx @@ -279,7 +279,7 @@ export function DashboardView({ user }: { user: User }) { transition={{ duration: 0.6, ease: EASE }} className='relative mb-12 overflow-hidden rounded-lg bg-pastel-greige/60 px-6 py-10 sm:px-10 lg:px-12 lg:py-12' > -
+
_', 1.5)} ambient