From 04ed774ff60a83c00711d4e8615cb4122954dba5 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Thu, 4 Dec 2025 19:46:55 +0900
Subject: (김준회) 메뉴 관리기능 초안 개발 (시딩 필요)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
components/layout/DynamicMenuRender.tsx | 146 ++++++++++++++++++++++++++++++++
1 file changed, 146 insertions(+)
create mode 100644 components/layout/DynamicMenuRender.tsx
(limited to 'components/layout/DynamicMenuRender.tsx')
diff --git a/components/layout/DynamicMenuRender.tsx b/components/layout/DynamicMenuRender.tsx
new file mode 100644
index 00000000..f94223ae
--- /dev/null
+++ b/components/layout/DynamicMenuRender.tsx
@@ -0,0 +1,146 @@
+"use client";
+
+import Link from "next/link";
+import { cn } from "@/lib/utils";
+import { NavigationMenuLink } from "@/components/ui/navigation-menu";
+import type { MenuTreeNode } from "@/lib/menu-v2/types";
+
+interface DynamicMenuRenderProps {
+ groups: MenuTreeNode[] | undefined;
+ lng: string;
+ getTitle: (node: MenuTreeNode) => string;
+ getDescription: (node: MenuTreeNode) => string | null;
+ onItemClick?: () => void;
+}
+
+export default function DynamicMenuRender({
+ groups,
+ lng,
+ getTitle,
+ getDescription,
+ onItemClick,
+}: DynamicMenuRenderProps) {
+ if (!groups || groups.length === 0) {
+ return (
+
+ 메뉴가 없습니다.
+
+ );
+ }
+
+ // 그룹별로 메뉴 분류
+ const groupedMenus = new Map();
+ const ungroupedMenus: MenuTreeNode[] = [];
+
+ for (const item of groups) {
+ if (item.nodeType === "group") {
+ // 그룹인 경우, 그룹의 children을 해당 그룹에 추가
+ const groupTitle = getTitle(item);
+ if (!groupedMenus.has(groupTitle)) {
+ groupedMenus.set(groupTitle, []);
+ }
+ if (item.children) {
+ groupedMenus.get(groupTitle)!.push(...item.children);
+ }
+ } else if (item.nodeType === "menu") {
+ // 직접 메뉴인 경우 (그룹 없이 직접 메뉴그룹에 속한 경우)
+ ungroupedMenus.push(item);
+ }
+ }
+
+ // 그룹이 없고 메뉴만 있는 경우 - 단순 그리드 렌더링
+ if (groupedMenus.size === 0 && ungroupedMenus.length > 0) {
+ return (
+
+ {ungroupedMenus.map((menu) => (
+
+ {getDescription(menu)}
+
+ ))}
+
+ );
+ }
+
+ // 그룹별 렌더링 - 가로 스크롤 지원
+ // 컨텐츠가 85vw를 초과할 때만 스크롤 발생
+ return (
+
+
+ {/* 그룹화되지 않은 메뉴 (있는 경우) */}
+ {ungroupedMenus.length > 0 && (
+
+
+ {ungroupedMenus.map((menu) => (
+
+ {getDescription(menu)}
+
+ ))}
+
+
+ )}
+
+ {/* 그룹별 메뉴 - 순서대로 가로 배치 */}
+ {Array.from(groupedMenus.entries()).map(([groupTitle, menus]) => (
+
+
+ {groupTitle}
+
+
+ {menus.map((menu) => (
+
+ {getDescription(menu)}
+
+ ))}
+
+
+ ))}
+
+
+ );
+}
+
+interface MenuListItemProps {
+ href: string;
+ title: string;
+ children?: React.ReactNode;
+ onClick?: () => void;
+}
+
+function MenuListItem({ href, title, children, onClick }: MenuListItemProps) {
+ return (
+
+
+
+ {title}
+ {children && (
+
+ {children}
+
+ )}
+
+
+
+ );
+}
+
--
cgit v1.2.3