diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000..c60a041 Binary files /dev/null and b/public/icon-192.png differ diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000..0de1452 Binary files /dev/null and b/public/icon-512.png differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest new file mode 100644 index 0000000..6e0f6dd --- /dev/null +++ b/public/manifest.webmanifest @@ -0,0 +1,14 @@ +{ + "name": "top-tickets", + "short_name": "top-tickets", + "description": "Helpdesk for support@top-sysops.ru, Telegram, and the web.", + "start_url": "/dashboard", + "scope": "/", + "display": "standalone", + "background_color": "#f8f7fb", + "theme_color": "#6d28d9", + "icons": [ + { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, + { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" } + ] +} diff --git a/src/app/(admin)/layout.tsx b/src/app/(admin)/layout.tsx index 50f1fcc..5320b16 100644 --- a/src/app/(admin)/layout.tsx +++ b/src/app/(admin)/layout.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { Ticket } from "lucide-react"; import { getCurrentSession } from "@/lib/auth/session"; import { LogoutButton } from "./logout-button"; -import { NavLinks } from "./nav-links"; +import { NavShell } from "./nav-shell"; import { ThemeToggle } from "./theme-toggle"; import { SettingsMenu } from "./settings-menu"; import { NotificationToggle } from "./notification-toggle"; @@ -21,18 +21,18 @@ export default async function AdminLayout({ children }: { children: React.ReactN return (
-
-
- +
+
+
- top-tickets + top-tickets -
- +
+
-
+
{isAdmin && } @@ -41,7 +41,10 @@ export default async function AdminLayout({ children }: { children: React.ReactN
-
{children}
+ {/* pb: clears the fixed mobile bottom-tab bar (~52px + safe-area) so it never covers the last bit of scrolled content */} +
+ {children} +
diff --git a/src/app/(admin)/mobile-nav.tsx b/src/app/(admin)/mobile-nav.tsx new file mode 100644 index 0000000..0a0d049 --- /dev/null +++ b/src/app/(admin)/mobile-nav.tsx @@ -0,0 +1,34 @@ +"use client"; + +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { links } from "./nav-data"; + +/** Bottom tab bar for mobile — mirrors top-buh/top-finance's pattern. Only 2 links here, both fit as primary tabs, no overflow "Ещё" needed. */ +export function MobileNav({ isAdmin }: { isAdmin: boolean }) { + const pathname = usePathname(); + const visibleLinks = links.filter((link) => !link.adminOnly || isAdmin); + + return ( + + ); +} diff --git a/src/app/(admin)/nav-data.ts b/src/app/(admin)/nav-data.ts new file mode 100644 index 0000000..db568aa --- /dev/null +++ b/src/app/(admin)/nav-data.ts @@ -0,0 +1,13 @@ +import { LayoutDashboard, BarChart3 } from "lucide-react"; + +export interface NavLink { + href: string; + label: string; + icon: typeof LayoutDashboard; + adminOnly: boolean; +} + +export const links: NavLink[] = [ + { href: "/dashboard", label: "Заявки", icon: LayoutDashboard, adminOnly: false }, + { href: "/stats", label: "Статистика", icon: BarChart3, adminOnly: true }, +]; diff --git a/src/app/(admin)/nav-links.tsx b/src/app/(admin)/nav-links.tsx index 9448482..42e8ba6 100644 --- a/src/app/(admin)/nav-links.tsx +++ b/src/app/(admin)/nav-links.tsx @@ -2,12 +2,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; -import { LayoutDashboard, BarChart3 } from "lucide-react"; - -const links = [ - { href: "/dashboard", label: "Заявки", icon: LayoutDashboard, adminOnly: false }, - { href: "/stats", label: "Статистика", icon: BarChart3, adminOnly: true }, -]; +import { links } from "./nav-data"; export function NavLinks({ isAdmin }: { isAdmin: boolean }) { const pathname = usePathname(); diff --git a/src/app/(admin)/nav-shell.tsx b/src/app/(admin)/nav-shell.tsx new file mode 100644 index 0000000..f055262 --- /dev/null +++ b/src/app/(admin)/nav-shell.tsx @@ -0,0 +1,16 @@ +"use client"; + +import { NavLinks } from "./nav-links"; +import { MobileNav } from "./mobile-nav"; + +/** Desktop top nav (>=lg) + mobile bottom tab bar ( +
+ +
+ + + ); +} diff --git a/src/app/(admin)/ticket-toasts.tsx b/src/app/(admin)/ticket-toasts.tsx index 47a8a54..6550c13 100644 --- a/src/app/(admin)/ticket-toasts.tsx +++ b/src/app/(admin)/ticket-toasts.tsx @@ -103,7 +103,7 @@ export function TicketToasts({ currentUser }: { currentUser: { id: string; role: } return ( -
+
{toasts.map((toast) => (