Files
TEDI-DDP-FE/src/components/layouts/BaseLayout/BaseLayout.tsx
T
2026-10-26 16:03:54 +07:00

142 lines
4.0 KiB
TypeScript

"use client";
import React from "react";
import clsx from "clsx";
import { usePathname } from "next/navigation";
import { PropsBaseLayout, TContextBaseLayout } from "./interface";
import Header from "./componets/Header";
import Navbar from "./componets/Navbar";
import RequireAuth from "@/components/protected/RequiredAuth";
export const ContextBaseLayout = React.createContext<TContextBaseLayout>({});
const BaseLayout = ({ children, title, breadcrumb }: PropsBaseLayout) => {
const [showFull, setShowFull] = React.useState(true);
const [openMenuMobile, setOpenMenuMobile] = React.useState(false);
const pathname = usePathname();
// Blueprint layout đặc biệt
const isBlueprint = pathname.startsWith("/blueprint");
return (
<RequireAuth>
<ContextBaseLayout
value={{
showFull,
setShowFull,
openMenuMobile,
setOpenMenuMobile,
}}
>
<div className="min-h-screen bg-[#f8f8f8]">
{/* =========================
OVERLAY MOBILE
========================= */}
{!isBlueprint && (
<div
className={clsx(
"fixed inset-0 bg-black/50 backdrop-blur-sm z-[20]",
"transition-opacity duration-300 xl:hidden",
openMenuMobile ? "opacity-100 visible" : "opacity-0 invisible",
)}
onClick={() => setOpenMenuMobile(false)}
/>
)}
{/* =========================
SIDEBAR / NAVBAR
========================= */}
{!isBlueprint && (
<nav
className={clsx(
"fixed top-0 left-0 h-screen",
"bg-white border-r border-[#f4f7fa]",
"z-[30]",
"transition-all duration-300 ease-in-out",
/* DESKTOP */
showFull
? "xl:w-[240px] xl:translate-x-0"
: "xl:w-[240px] xl:-translate-x-full",
/* MOBILE + TABLET */
openMenuMobile
? "translate-x-0 w-[240px]"
: "-translate-x-full w-[240px]",
)}
>
<Navbar />
</nav>
)}
{/* =========================
HEADER
========================= */}
<header
className={clsx(
"top-0 right-0 h-[68px]",
"bg-white border-b border-[#f4f7fa]",
"z-[11]",
isBlueprint
? [
// Blueprint:
// Không fixed → scroll cùng trang
"absolute",
"left-0 w-full",
]
: [
// Các page bình thường:
// Header cố định
"fixed",
"transition-all duration-300",
showFull
? "xl:left-[240px] xl:w-[calc(100%-240px)]"
: "xl:left-0 xl:w-full",
"left-0 w-full",
],
)}
>
<Header title={title} breadcrumb={breadcrumb} />
</header>
{/* =========================
MAIN CONTENT
========================= */}
<main
className={clsx(
"transition-all duration-300 ease-in-out",
isBlueprint
? [
// Blueprint dùng toàn bộ màn hình
"ml-0",
"px-0",
"pt-[68px]",
]
: [
// Các page bình thường
"pt-[92px]",
"px-6",
showFull ? "xl:ml-[240px]" : "xl:ml-0",
"ml-0",
],
)}
>
{children}
</main>
</div>
</ContextBaseLayout>
</RequireAuth>
);
};
export default BaseLayout;