From 9ceed79cf32c896f8a998399bf1b296506b2cd4a Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 8 Apr 2025 03:08:19 +0000
Subject: 로그인 및 미들웨어 처리. 구조 변경
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/layout/Header.tsx | 215 +++++++++++++++++++++++--------------------
 1 file changed, 113 insertions(+), 102 deletions(-)

(limited to 'components/layout/Header.tsx')

diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx
index 1b6c45bb..498668eb 100644
--- a/components/layout/Header.tsx
+++ b/components/layout/Header.tsx
@@ -26,19 +26,20 @@ import { SearchIcon, BellIcon, Menu } from "lucide-react";
 import { useParams, usePathname } from "next/navigation";
 import { cn } from "@/lib/utils";
 import Image from "next/image";
-import { mainNav, additionalNav, MenuSection, mainNavVendor, additionalNavVendor } from "@/config/menuConfig"; // 메뉴 구성 임포트
+import { mainNav, additionalNav, MenuSection, MenuItem, mainNavVendor, additionalNavVendor } from "@/config/menuConfig"; // 메뉴 구성 임포트
 import { MobileMenu } from "./MobileMenu";
 import { CommandMenu } from "./command-menu";
 import { useSession, signOut } from "next-auth/react";
-
+import GroupedMenuRenderer from "./GroupedMenuRender";
 
 export function Header() {
     const params = useParams();
-    const lng = params.lng as string;
+    const lng = params?.lng as string;
     const pathname = usePathname();
     const { data: session } = useSession();
 
-    const userName = session?.user?.name || ""; // 없을 수도 있으니 안전하게 처리
+    const userName = session?.user?.name || ""; 
+    const domain = session?.user?.domain || ""; 
     const initials = userName
         .split(" ")
         .map((word) => word[0]?.toUpperCase())
@@ -51,7 +52,7 @@ export function Header() {
         setIsMobileMenuOpen(!isMobileMenuOpen);
     };
 
-    const isPartnerRoute = pathname.includes("/partners");
+    const isPartnerRoute = pathname?.includes("/partners");
 
     const main = isPartnerRoute ? mainNavVendor : mainNav;
     const additional = isPartnerRoute ? additionalNavVendor : additionalNav;
@@ -60,10 +61,10 @@ export function Header() {
 
     return (
         <>
-            <header className="border-grid sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
+            <header className="border-grid sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
                 <div className="container-wrapper">
                     <div className="container flex h-14 items-center">
-
+                        {/* 햄버거 메뉴 버튼 (모바일) */}
                         <Button
                             onClick={toggleMobileMenu}
                             variant="ghost"
@@ -86,105 +87,115 @@ export function Header() {
                             <span className="sr-only">Toggle Menu</span>
                         </Button>
 
-
-                        <div className="mr-4 hidden md:flex">
-
-                            {/* 로고 영역 */}
-                            <div className="mr-4 flex items-center gap-2 lg:mr-6">
-                                <Link href={`/${lng}/evcp`} className="flex items-center gap-2">
-                                    <Image
-                                        className="dark:invert"
-                                        src="/images/vercel.svg"
-                                        alt="EVCP Logo"
-                                        width={20}
-                                        height={20}
-                                    />
-                                    <span className="hidden font-bold lg:inline-block">eVCP</span>
-                                </Link>
-                            </div>
-                            {/* 데스크탑 네비게이션 메뉴 */}
-                            <NavigationMenu className="flex items-center gap-4 text-sm xl:gap-6">
-                                <NavigationMenuList>
-                                    {main.map((section: MenuSection) => (
-                                        <NavigationMenuItem key={section.title}>
-                                            <NavigationMenuTrigger>{section.title}</NavigationMenuTrigger>
-                                            <NavigationMenuContent>
-                                                <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
-                                                    {section.items.map((item) => (
-                                                        <ListItem
-                                                            key={item.title}
-                                                            title={item.title}
-                                                            href={`/${lng}${item.href}`}
-                                                        >
-                                                            {item.description}
-                                                        </ListItem>
-                                                    ))}
-                                                </ul>
-                                            </NavigationMenuContent>
-                                        </NavigationMenuItem>
-                                    ))}
-
-
-                                    {/* 추가 네비게이션 항목 */}
-                                    {additional.map((item) => (
-                                        <NavigationMenuItem key={item.title}>
-                                            <Link href={`/${lng}${item.href}`} legacyBehavior passHref>
-                                                <NavigationMenuLink className={navigationMenuTriggerStyle()}>
-                                                    {item.title}
-                                                </NavigationMenuLink>
-                                            </Link>
-                                        </NavigationMenuItem>
-                                    ))}
-                                </NavigationMenuList>
+                        {/* 로고 영역 - 항상 표시 */}
+                        <div className="mr-4 flex-shrink-0 flex items-center gap-2 lg:mr-6">
+                            <Link href={`/${lng}/evcp`} className="flex items-center gap-2">
+                                <Image
+                                    className="dark:invert"
+                                    src="/images/vercel.svg"
+                                    alt="EVCP Logo"
+                                    width={20}
+                                    height={20}
+                                />
+                                <span className="hidden font-bold lg:inline-block">eVCP</span>
+                            </Link>
+                        </div>
+                            
+                        {/* 네비게이션 메뉴 - 내부 스크롤 적용, 드롭다운은 제약 없이 표시 */}
+                        <div className="hidden md:block flex-1 min-w-0">
+                            {/* NavigationMenu는 z-index를 높게 설정하여 드롭다운이 제대로 표시되도록 함 */}
+                            <NavigationMenu className="relative z-50">
+                                {/* 스크롤 가능한 메뉴 리스트 컨테이너 */}
+                                <div className="w-full overflow-x-auto pb-1">
+                                    <NavigationMenuList className="flex-nowrap w-max">
+                                        {main.map((section: MenuSection) => (
+                                            <NavigationMenuItem key={section.title}>
+                                                <NavigationMenuTrigger className="px-2 xl:px-3 text-sm whitespace-nowrap">
+                                                    {section.title}
+                                                </NavigationMenuTrigger>
+                                                
+                                                {/* 그룹핑이 필요한 메뉴의 경우 GroupedMenuRenderer 사용 */}
+                                                {section.useGrouping ? (
+                                                    <NavigationMenuContent>
+                                                        <GroupedMenuRenderer items={section.items} lng={lng} />
+                                                    </NavigationMenuContent>
+                                                ) : (
+                                                    <NavigationMenuContent>
+                                                        <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
+                                                            {section.items.map((item) => (
+                                                                <ListItem
+                                                                    key={item.title}
+                                                                    title={item.title}
+                                                                    href={`/${lng}${item.href}`}
+                                                                >
+                                                                    {item.description}
+                                                                </ListItem>
+                                                            ))}
+                                                        </ul>
+                                                    </NavigationMenuContent>
+                                                )}
+                                            </NavigationMenuItem>
+                                        ))}
+
+                                        {/* 추가 네비게이션 항목 */}
+                                        {additional.map((item) => (
+                                            <NavigationMenuItem key={item.title}>
+                                                <Link href={`/${lng}${item.href}`} legacyBehavior passHref>
+                                                    <NavigationMenuLink 
+                                                        className={cn(
+                                                            navigationMenuTriggerStyle(), 
+                                                            "px-2 xl:px-3 text-sm whitespace-nowrap"
+                                                        )}
+                                                    >
+                                                        {item.title}
+                                                    </NavigationMenuLink>
+                                                </Link>
+                                            </NavigationMenuItem>
+                                        ))}
+                                    </NavigationMenuList>
+                                </div>
                             </NavigationMenu>
-
-
                         </div>
 
-
-                        {/* 우측 영역 */}
-                        <div className="flex flex-1 items-center justify-between gap-2 md:justify-end">
-
-                            <CommandMenu />
-
-
-                            <div className="flex items-center space-x-4">
-                                {/* 알림 버튼 */}
-                                <Button variant="ghost" className="relative p-2" aria-label="Notifications">
-                                    <BellIcon className="h-5 w-5" />
-                                    {/* 알림 뱃지 예시 */}
-                                    <span className="absolute -top-1 -right-1 inline-flex h-2 w-2 rounded-full bg-red-500"></span>
-                                </Button>
-
-                                {/* 사용자 메뉴 (DropdownMenu) */}
-                                <DropdownMenu>
-                                    <DropdownMenuTrigger asChild>
-                                        <Avatar className="cursor-pointer">
-                                            <AvatarImage src={`/profiles/${session?.user?.image}`||"/user-avatar.jpg"} alt="User Avatar" />
-                                            <AvatarFallback>
-                                                {initials || "?"}
-                                            </AvatarFallback>
-                                        </Avatar>
-                                    </DropdownMenuTrigger>
-                                    <DropdownMenuContent className="w-48" align="end">
-                                        <DropdownMenuLabel>My Account</DropdownMenuLabel>
-                                        <DropdownMenuSeparator />
-                                        {/* <DropdownMenuItem asChild>
-                                            <Link href={`${basePath}/profile`}>Profile</Link>
-                                        </DropdownMenuItem> */}
-                                        <DropdownMenuItem asChild>
-                                            <Link href={`${basePath}/settings`}>Settings</Link>
-                                        </DropdownMenuItem>
-                                        <DropdownMenuSeparator />
-                                        <DropdownMenuItem onSelect={() => signOut({ callbackUrl: `/${lng}/login` })}>
-                                            Logout
-                                        </DropdownMenuItem>
-                                    </DropdownMenuContent>
-                                </DropdownMenu>
-
-                                {/* 모바일 햄버거 메뉴 버튼 */}
-
+                        {/* 우측 영역 - 고정 너비와 우선순위로 항상 표시되도록 함 */}
+                        <div className="ml-auto flex flex-shrink-0 items-center space-x-2">
+                            {/* 데스크탑에서는 CommandMenu, 모바일에서는 검색 아이콘만 */}
+                            <div className="hidden md:block md:w-auto">
+                                <CommandMenu />
                             </div>
+                            <Button variant="ghost" size="icon" className="md:hidden" aria-label="Search">
+                                <SearchIcon className="h-5 w-5" />
+                            </Button>
+
+                            {/* 알림 버튼 */}
+                            <Button variant="ghost" size="icon" className="relative" aria-label="Notifications">
+                                <BellIcon className="h-5 w-5" />
+                                {/* 알림 뱃지 예시 */}
+                                <span className="absolute -top-1 -right-1 inline-flex h-2 w-2 rounded-full bg-red-500"></span>
+                            </Button>
+
+                            {/* 사용자 메뉴 (DropdownMenu) */}
+                            <DropdownMenu>
+                                <DropdownMenuTrigger asChild>
+                                    <Avatar className="cursor-pointer h-8 w-8">
+                                        <AvatarImage src={`/profiles/${session?.user?.image}`||"/user-avatar.jpg"} alt="User Avatar" />
+                                        <AvatarFallback>
+                                            {initials || "?"}
+                                        </AvatarFallback>
+                                    </Avatar>
+                                </DropdownMenuTrigger>
+                                <DropdownMenuContent className="w-48" align="end">
+                                    <DropdownMenuLabel>My Account</DropdownMenuLabel>
+                                    <DropdownMenuSeparator />
+                                    <DropdownMenuItem asChild>
+                                        <Link href={`${basePath}/settings`}>Settings</Link>
+                                    </DropdownMenuItem>
+                                    <DropdownMenuSeparator />
+                                    <DropdownMenuItem onSelect={() => signOut({ callbackUrl: `/${lng}/${domain}` })}>
+                                        Logout
+                                    </DropdownMenuItem>
+                                </DropdownMenuContent>
+                            </DropdownMenu>
                         </div>
                     </div>
                 </div>
-- 
cgit v1.2.3

