diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index 43331067e..a0d262b9d 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -1,7 +1,15 @@ +import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import type { UseFormReturn } from "react-hook-form"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { Button } from "@common/components"; +import { + Button, + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + LNB, +} from "@common/components"; import { MenuApi, menuFormSchema, type MenuFormData } from "@/entities/menu"; import { ManagementAuthorityDialog } from "@/entities/menu-authority"; import { Form } from "@/shared/ui/form"; @@ -33,7 +41,7 @@ function MenuForm({ handleDelete, }: MenuFormProps) { const isModifyMode = !!menuCd; - + const [open, setOpen] = useState(false); const { confirm } = useConfirm(); const alert = useAlertStore((state) => state.setMessage); @@ -96,55 +104,82 @@ function MenuForm({ const isSubmitDisabled = !form.watch("siteId"); return ( -
- -
-
-

- {isModifyMode ? "메뉴 수정" : "메뉴 등록"} -

-
- - + <> + + +
+
+

+ {isModifyMode ? "메뉴 수정" : "메뉴 등록"} +

+
+ + +
+
+
+ +
-
- - +
+ {isModifyMode && ( + + )} + {isModifyMode && ( + + )} + {isModifyMode && ( + + )} + + {isModifyMode && ( + + )}
-
-
- {isModifyMode && ( - - )} - {isModifyMode && ( - - )} - - {isModifyMode && ( - - )} -
- - + + + + + + 메뉴 미리보기 + +
+ +
+
+
+ ); } diff --git a/packages/common/components/src/api/menu.ts b/packages/common/components/src/api/menu.ts index bd8fe1599..8d58a3499 100644 --- a/packages/common/components/src/api/menu.ts +++ b/packages/common/components/src/api/menu.ts @@ -21,6 +21,10 @@ export interface MenuItem { requiredUrlPath: boolean; } +export interface TreeMenu extends MenuItem { + menuHlpCn: string; +} + const client = getApiClient(); export const getMenuList = async (siteId: string) => { @@ -29,3 +33,10 @@ export const getMenuList = async (siteId: string) => { ); return response.data; }; + +export const getPreviewTreeMenuList = async (siteId: string) => { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree/preview`, + ); + return response.data; +}; diff --git a/packages/common/components/src/config/api.ts b/packages/common/components/src/config/api.ts index 12efdd8bd..0ead6b0bc 100644 --- a/packages/common/components/src/config/api.ts +++ b/packages/common/components/src/config/api.ts @@ -1,5 +1,6 @@ export const ENDPOINT = { CMS_SERVICE: { + MENUS: "/cms-service/api/v1/menus", MENU_ROLES: "/cms-service/api/v1/menu-roles", SITES: "/cms-service/api/v1/sites", POPUPS: "/cms-service/api/v1/popups", diff --git a/packages/common/components/src/ui/index.ts b/packages/common/components/src/ui/index.ts index 8839d2298..75231add8 100644 --- a/packages/common/components/src/ui/index.ts +++ b/packages/common/components/src/ui/index.ts @@ -15,6 +15,7 @@ export * from "./icon-finder"; export * from "./input"; export * from "./label"; export * from "./layout"; +export * from "./lnb"; export * from "./loading"; export * from "./page-title"; export * from "./popover"; diff --git a/packages/common/components/src/ui/lnb/index.tsx b/packages/common/components/src/ui/lnb/index.tsx index 552a7d67a..20376af24 100644 --- a/packages/common/components/src/ui/lnb/index.tsx +++ b/packages/common/components/src/ui/lnb/index.tsx @@ -3,9 +3,7 @@ import { useState, useEffect, useRef } from "react"; import { useQuery } from "@tanstack/react-query"; import { ChevronRight } from "lucide-react"; -import { ENDPOINT } from "../../config"; -import { cn, setCookie } from "../../lib"; -import { getMenuList, type MenuItem } from "../../api"; +import { getParentIds } from "./lib"; import { Sidebar, SidebarContent, @@ -22,29 +20,47 @@ import { CollapsibleContent, CollapsibleTrigger, } from "../collapsible"; -import { getParentIds } from "./lib"; -import { getCookie } from "../../lib"; - -const siteId = getCookie("site-id-key") ?? ""; +import { ENDPOINT } from "../../config"; +import { cn, getCookie, setCookie } from "../../lib"; +import { getMenuList, getPreviewTreeMenuList, type MenuItem } from "../../api"; export function LNB({ viewOnly, currentPath, + propSiteId, + previewMode, + classNames, handleMenuClick, }: { viewOnly?: boolean; currentPath?: string; + propSiteId?: string; + previewMode?: boolean; + classNames?: { + wrapper?: string; + }; handleMenuClick?: (item: MenuItem) => void; }) { - const { data: menuList } = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES], - queryFn: () => getMenuList(siteId), - enabled: !viewOnly, - }); - const [defaultOpenMenuIds, setDefaultOpenMenuIds] = useState([]); const prevPathRef = useRef(currentPath); + const cookieSiteId = getCookie("site-id-key") ?? ""; + const siteId = propSiteId ?? cookieSiteId; + + const { data: menuListData } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES], + queryFn: () => getMenuList(siteId), + enabled: !viewOnly && !previewMode, + }); + + const { data: previewTreeMenuListData } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId, "preview"], + queryFn: () => getPreviewTreeMenuList(siteId), + enabled: previewMode, + }); + + const menuList = previewMode ? previewTreeMenuListData : menuListData; + function isPathMatched(path: string) { if (!path) return false; return currentPath?.startsWith(path); @@ -191,7 +207,10 @@ export function LNB({ return (