diff --git a/app/[lang]/dashboard/DashboardLayoutClient.tsx b/app/[lang]/dashboard/DashboardLayoutClient.tsx new file mode 100644 index 0000000..38f8101 --- /dev/null +++ b/app/[lang]/dashboard/DashboardLayoutClient.tsx @@ -0,0 +1,63 @@ +"use client"; + +import { useState } from "react"; +import Providers from "@/components/Providers"; +import Sidebar from "@/components/Sidebar"; +import { DictionaryProvider } from "@/components/DictionaryContext"; + +export default function DashboardLayout({ + children, + dict, + lang, +}: { + children: React.ReactNode; + dict: any; + lang: string; +}) { + const [isSidebarOpen, setIsSidebarOpen] = useState(false); + + return ( + + +
+ {/* Mobile Overlay */} +
setIsSidebarOpen(false)} + /> + + setIsSidebarOpen(false)} + /> + +
+ {/* Mobile Header */} +
+ +
AyrisMail
+
+ + {children} +
+
+ + + ); +} + +function MenuIcon() { + return ( + + + + + + ); +} diff --git a/app/[lang]/dashboard/layout.tsx b/app/[lang]/dashboard/layout.tsx index 98e1cec..9684d72 100644 --- a/app/[lang]/dashboard/layout.tsx +++ b/app/[lang]/dashboard/layout.tsx @@ -1,9 +1,7 @@ import { auth } from "@/auth"; import { redirect } from "next/navigation"; -import Providers from "@/components/Providers"; -import Sidebar from "@/components/Sidebar"; import { getDictionary, Locale } from "@/app/dictionaries"; -import { DictionaryProvider } from "@/components/DictionaryContext"; +import DashboardLayoutClient from "./DashboardLayoutClient"; export default async function DashboardLayout( props: { @@ -12,10 +10,7 @@ export default async function DashboardLayout( } ) { const params = await props.params; - - const { - children - } = props; + const { children } = props; const session = await auth(); if (!session) redirect(`/${params.lang}/login`); @@ -23,13 +18,8 @@ export default async function DashboardLayout( const dict = await getDictionary(params.lang as Locale); return ( - - -
- -
{children}
-
-
-
+ + {children} + ); } diff --git a/app/globals.css b/app/globals.css index a94a998..60b681e 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1085,6 +1085,46 @@ tr:hover td { background: var(--danger-dim); } +/* ── Mobile Header ── */ +.mobile-header { + display: none; + align-items: center; + gap: 16px; + padding: 12px 16px; + background: var(--bg-card); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 50; +} + +.mobile-menu-btn { + background: none; + border: none; + color: var(--text-primary); + cursor: pointer; + padding: 4px; + display: flex; + align-items: center; + justify-content: center; +} + +.mobile-logo { + font-weight: 700; + font-size: 16px; + color: var(--accent-hover); +} + +.sidebar-overlay { + display: none; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(4px); + z-index: 90; + animation: fadeIn 0.2s ease; +} + /* ── Responsive ── */ @media (max-width: 1024px) { .mail-layout { grid-template-columns: 60px 280px 1fr; } @@ -1097,12 +1137,42 @@ tr:hover td { } @media (max-width: 768px) { - .sidebar { display: none; } - .mail-layout { grid-template-columns: 1fr; } + .mobile-header { display: flex; } + + .sidebar { + position: fixed; + left: -240px; + top: 0; + bottom: 0; + z-index: 100; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 10px 0 30px rgba(0,0,0,0.5); + } + + .sidebar-open .sidebar { + transform: translateX(240px); + } + + .sidebar-open .sidebar-overlay { + display: block; + } + + .mail-layout { grid-template-columns: 1fr; height: auto; overflow: visible; } .mail-sidebar { display: none; } .mail-detail { display: none; } + + /* Show active mail view if selected */ + .mail-view-active .mail-list { display: none; } + .mail-view-active .mail-detail { display: block; } + .page-body { padding: 16px; } - .page-header { padding: 16px; } + .page-header { + padding: 16px; + flex-direction: column; + align-items: flex-start; + } + .page-header .btn { width: 100%; justify-content: center; } + .stats-grid { grid-template-columns: 1fr 1fr; } } /* ── Language Switcher ── */ diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx index 8c7ece3..84bc70a 100644 --- a/components/Sidebar.tsx +++ b/components/Sidebar.tsx @@ -5,7 +5,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import LanguageSwitcher from "./LanguageSwitcher"; -export default function Sidebar({ dict, lang }: { dict: any; lang: string }) { +export default function Sidebar({ dict, lang, onClose }: { dict: any; lang: string; onClose?: () => void }) { const { data: session } = useSession(); const pathname = usePathname(); const role = session?.user?.role ?? ""; @@ -61,6 +61,7 @@ export default function Sidebar({ dict, lang }: { dict: any; lang: string }) { key={item.href} href={item.href} className={`nav-item ${pathname === item.href ? "active" : ""}`} + onClick={onClose} > {item.label}