헤더생성

This commit is contained in:
kjs 2025-12-03 19:05:10 +09:00
parent e9738ce67f
commit 4569defecf
1 changed files with 77 additions and 24 deletions

View File

@ -423,28 +423,80 @@ function AppLayoutInner({ children }: AppLayoutProps) {
const uiMenus = convertMenuToUI(currentMenus, user as ExtendedUserInfo);
return (
<div className="flex h-screen bg-white">
{/* 모바일 사이드바 오버레이 */}
{sidebarOpen && isMobile && (
<div className="fixed inset-0 z-30 bg-black/50 lg:hidden" onClick={() => setSidebarOpen(false)} />
<div className="flex h-screen flex-col bg-white">
{/* 모바일 헤더 - 모바일에서만 표시 */}
{isMobile && (
<header className="fixed top-0 left-0 right-0 z-50 flex h-14 items-center justify-between border-b border-slate-200 bg-white px-4">
<div className="flex items-center gap-3">
{/* 햄버거 메뉴 버튼 */}
<SideMenu onSidebarToggle={() => setSidebarOpen(!sidebarOpen)} />
<Logo />
</div>
{/* 사용자 드롭다운 */}
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild>
<button className="flex items-center gap-2 rounded-lg px-2 py-1 transition-colors hover:bg-slate-100">
<div className="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-full">
{user.photo && user.photo.trim() !== "" && user.photo !== "null" ? (
<img
src={user.photo}
alt={user.userName || "User"}
className="aspect-square h-full w-full object-cover"
/>
) : (
<div className="flex h-full w-full items-center justify-center rounded-full bg-slate-200 text-sm font-semibold text-slate-700">
{user.userName?.substring(0, 1)?.toUpperCase() || "U"}
</div>
)}
</div>
</button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="end">
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm leading-none font-medium">
{user.userName || "사용자"}
</p>
<p className="text-muted-foreground text-xs leading-none">
{user.deptName || user.email || user.userId}
</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={openProfileModal}>
<User className="mr-2 h-4 w-4" />
<span></span>
</DropdownMenuItem>
<DropdownMenuItem onClick={handleLogout}>
<LogOut className="mr-2 h-4 w-4" />
<span></span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</header>
)}
{/* 왼쪽 사이드바 */}
<aside
className={`${
isMobile
? (sidebarOpen ? "translate-x-0" : "-translate-x-full") + " fixed top-0 left-0 z-40"
: "relative z-auto translate-x-0"
} flex h-screen w-[200px] flex-col border-r border-slate-200 bg-white transition-transform duration-300`}
>
{/* 사이드바 최상단 - 로고 + 모바일 햄버거 메뉴 */}
<div className="flex h-14 items-center justify-between border-b border-slate-200 px-4">
<Logo />
{/* 모바일 햄버거 메뉴 버튼 */}
<div className="lg:hidden">
<SideMenu onSidebarToggle={() => setSidebarOpen(!sidebarOpen)} />
</div>
</div>
{/* 메인 컨테이너 - 모바일에서는 헤더 높이만큼 패딩 */}
<div className={`flex flex-1 ${isMobile ? "pt-14" : ""}`}>
{/* 모바일 사이드바 오버레이 */}
{sidebarOpen && isMobile && (
<div className="fixed inset-0 z-30 bg-black/50 lg:hidden" onClick={() => setSidebarOpen(false)} />
)}
{/* 왼쪽 사이드바 */}
<aside
className={`${
isMobile
? (sidebarOpen ? "translate-x-0" : "-translate-x-full") + " fixed top-14 left-0 z-40 h-[calc(100vh-56px)]"
: "relative z-auto h-screen translate-x-0"
} flex w-[200px] flex-col border-r border-slate-200 bg-white transition-transform duration-300`}
>
{/* 사이드바 최상단 - 로고 (데스크톱에서만 표시) */}
{!isMobile && (
<div className="flex h-14 items-center justify-between border-b border-slate-200 px-4">
<Logo />
</div>
)}
{/* Admin/User 모드 전환 버튼 (관리자만) */}
{((user as ExtendedUserInfo)?.userType === "SUPER_ADMIN" ||
@ -565,10 +617,11 @@ function AppLayoutInner({ children }: AppLayoutProps) {
</div>
</aside>
{/* 가운데 컨텐츠 영역 - 스크롤 가능 */}
<main className="h-screen min-w-0 flex-1 overflow-auto bg-white">
{children}
</main>
{/* 가운데 컨텐츠 영역 - 스크롤 가능 */}
<main className={`min-w-0 flex-1 overflow-auto bg-white ${isMobile ? "h-[calc(100vh-56px)]" : "h-screen"}`}>
{children}
</main>
</div>
{/* 프로필 수정 모달 */}
<ProfileModal