Compare commits

...

1 Commits

Author SHA1 Message Date
AyrisAI
99f9b51db8 Improve mobile responsiveness with hamburger menu and drawer sidebar 2026-05-14 22:56:39 +03:00
4 changed files with 143 additions and 19 deletions

View File

@@ -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 (
<Providers>
<DictionaryProvider dictionary={dict}>
<div className={`app-layout ${isSidebarOpen ? "sidebar-open" : ""}`}>
{/* Mobile Overlay */}
<div
className="sidebar-overlay"
onClick={() => setIsSidebarOpen(false)}
/>
<Sidebar
dict={dict}
lang={lang}
onClose={() => setIsSidebarOpen(false)}
/>
<div className="main-content">
{/* Mobile Header */}
<header className="mobile-header">
<button
className="mobile-menu-btn"
onClick={() => setIsSidebarOpen(true)}
>
<MenuIcon />
</button>
<div className="mobile-logo">AyrisMail</div>
</header>
{children}
</div>
</div>
</DictionaryProvider>
</Providers>
);
}
function MenuIcon() {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<line x1="4" x2="20" y1="12" y2="12" />
<line x1="4" x2="20" y1="6" y2="6" />
<line x1="4" x2="20" y1="18" y2="18" />
</svg>
);
}

View File

@@ -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 (
<Providers>
<DictionaryProvider dictionary={dict}>
<div className="app-layout">
<Sidebar dict={dict} lang={params.lang} />
<div className="main-content">{children}</div>
</div>
</DictionaryProvider>
</Providers>
<DashboardLayoutClient dict={dict} lang={params.lang}>
{children}
</DashboardLayoutClient>
);
}

View File

@@ -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 ── */

View File

@@ -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.icon />
{item.label}