100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
"use client";
|
|
|
|
import type { ComponentType } from "react";
|
|
import { CalendarDays, CircleUserRound, Home, Newspaper } from "lucide-react";
|
|
import { usePathname } from "next/navigation";
|
|
import { useAuth } from "@/contexts/AuthContext";
|
|
import { Link } from "@/lib/router";
|
|
import { cn } from "@/lib/utils";
|
|
import type { SiteContent } from "@/lib/content-cms";
|
|
|
|
type NavItem = {
|
|
key: string;
|
|
label: string;
|
|
href: string;
|
|
icon: ComponentType<{ className?: string }>;
|
|
matches: (pathname: string) => boolean;
|
|
};
|
|
|
|
const isProfileOrAuthPath = (pathname: string) =>
|
|
pathname === "/profile" ||
|
|
pathname.startsWith("/profile/") ||
|
|
pathname === "/auth" ||
|
|
pathname.startsWith("/auth/") ||
|
|
pathname.startsWith("/reset-password");
|
|
|
|
export default function MobileBottomNav({ siteContent }: { siteContent: SiteContent }) {
|
|
const pathname = usePathname() || "/";
|
|
const { isAuthenticated } = useAuth();
|
|
|
|
if (pathname.startsWith("/admin") || pathname === "/logout" || pathname.startsWith("/auth/google")) {
|
|
return null;
|
|
}
|
|
|
|
const items: NavItem[] = [
|
|
{
|
|
key: "home",
|
|
label: siteContent.navigation.home,
|
|
href: "/",
|
|
icon: Home,
|
|
matches: (current) => current === "/",
|
|
},
|
|
{
|
|
key: "events",
|
|
label: siteContent.navigation.events,
|
|
href: "/events",
|
|
icon: CalendarDays,
|
|
matches: (current) => current === "/events" || current.startsWith("/events/"),
|
|
},
|
|
{
|
|
key: "blog",
|
|
label: siteContent.navigation.blog,
|
|
href: "/blog",
|
|
icon: Newspaper,
|
|
matches: (current) => current === "/blog" || current.startsWith("/blog/"),
|
|
},
|
|
{
|
|
key: "account",
|
|
label: isAuthenticated ? "پروفایل" : "حساب",
|
|
href: isAuthenticated ? "/profile" : "/auth",
|
|
icon: CircleUserRound,
|
|
matches: isProfileOrAuthPath,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div
|
|
className="fixed inset-x-0 z-50 px-4 md:hidden"
|
|
style={{ bottom: "calc(env(safe-area-inset-bottom) + 0.9rem)" }}
|
|
>
|
|
<nav
|
|
aria-label="ناوبری اصلی موبایل"
|
|
className="mx-auto flex w-full max-w-md items-center justify-between rounded-2xl border border-border bg-background/95 px-1.5 py-1.5 shadow-lg backdrop-blur-xl"
|
|
dir="rtl"
|
|
>
|
|
{items.map((item) => {
|
|
const active = item.matches(pathname);
|
|
const Icon = item.icon;
|
|
|
|
return (
|
|
<Link
|
|
key={item.key}
|
|
to={item.href}
|
|
className={cn(
|
|
"flex min-h-11 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-xl px-1 py-1.5 text-[10px] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
active
|
|
? "bg-secondary text-primary"
|
|
: "text-muted-foreground hover:bg-secondary hover:text-foreground",
|
|
)}
|
|
aria-current={active ? "page" : undefined}
|
|
>
|
|
<Icon aria-hidden="true" className="h-4 w-4" />
|
|
<span className="max-w-full truncate">{item.label}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
</div>
|
|
);
|
|
}
|