From 79476337094e65c67c6b9f23a92263428e09046a Mon Sep 17 00:00:00 2001 From: Oleg Date: Sun, 26 Jul 2026 15:24:26 +0000 Subject: [PATCH] Simplify top nav: 2 links + gear menu for settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nav down to Заявки (renamed from Дашборд) + Статистика. Telegram/Почта/ Виджет moved into a gear-icon dropdown next to the theme toggle instead of competing for space in the horizontal nav row. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH --- src/app/(admin)/layout.tsx | 2 + src/app/(admin)/nav-links.tsx | 7 +--- src/app/(admin)/settings-menu.tsx | 63 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/app/(admin)/settings-menu.tsx diff --git a/src/app/(admin)/layout.tsx b/src/app/(admin)/layout.tsx index 1689c4f..3b46997 100644 --- a/src/app/(admin)/layout.tsx +++ b/src/app/(admin)/layout.tsx @@ -4,6 +4,7 @@ import { getCurrentSession } from "@/lib/auth/session"; import { LogoutButton } from "./logout-button"; import { NavLinks } from "./nav-links"; import { ThemeToggle } from "./theme-toggle"; +import { SettingsMenu } from "./settings-menu"; export default async function AdminLayout({ children }: { children: React.ReactNode }) { const session = await getCurrentSession(); @@ -23,6 +24,7 @@ export default async function AdminLayout({ children }: { children: React.ReactN
{session.user.name} +
diff --git a/src/app/(admin)/nav-links.tsx b/src/app/(admin)/nav-links.tsx index c52f826..0cce590 100644 --- a/src/app/(admin)/nav-links.tsx +++ b/src/app/(admin)/nav-links.tsx @@ -2,14 +2,11 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; -import { LayoutDashboard, BarChart3, Send, Mail, Code2 } from "lucide-react"; +import { LayoutDashboard, BarChart3 } from "lucide-react"; const links = [ - { href: "/dashboard", label: "Дашборд", icon: LayoutDashboard }, + { href: "/dashboard", label: "Заявки", icon: LayoutDashboard }, { href: "/stats", label: "Статистика", icon: BarChart3 }, - { href: "/settings/telegram", label: "Telegram", icon: Send }, - { href: "/settings/email", label: "Почта", icon: Mail }, - { href: "/settings/widget", label: "Виджет", icon: Code2 }, ]; export function NavLinks() { diff --git a/src/app/(admin)/settings-menu.tsx b/src/app/(admin)/settings-menu.tsx new file mode 100644 index 0000000..b30c307 --- /dev/null +++ b/src/app/(admin)/settings-menu.tsx @@ -0,0 +1,63 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { Settings, Send, Mail, Code2 } from "lucide-react"; + +const items = [ + { href: "/settings/telegram", label: "Telegram", icon: Send }, + { href: "/settings/email", label: "Почта", icon: Mail }, + { href: "/settings/widget", label: "Виджет", icon: Code2 }, +]; + +export function SettingsMenu() { + const [open, setOpen] = useState(false); + const pathname = usePathname(); + const rootRef = useRef(null); + + useEffect(() => { + function onClickOutside(e: MouseEvent) { + if (rootRef.current && !rootRef.current.contains(e.target as Node)) { + setOpen(false); + } + } + document.addEventListener("mousedown", onClickOutside); + return () => document.removeEventListener("mousedown", onClickOutside); + }, []); + + const isActive = items.some((item) => pathname.startsWith(item.href)); + + return ( +
+ + {open && ( +
+ {items.map(({ href, label, icon: Icon }) => { + const active = pathname.startsWith(href); + return ( + setOpen(false)} + className={`flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors ${ + active ? "bg-accent-soft text-accent-soft-text" : "text-text-muted hover:bg-surface-hover hover:text-text" + }`} + > + + {label} + + ); + })} +
+ )} +
+ ); +}