From ae5597b1f330fcca8dcc61c310162afa2b548c40 Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 27 Mar 2025 15:23:01 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A9=94=EB=89=B4=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/menu/api/menu-service.ts | 7 + .../cs/src/pages/menu/model/menu-interface.ts | 1 + apps/cs/src/pages/menu/ui/menu-form.tsx | 4 +- apps/cs/src/pages/menu/ui/menu-node.tsx | 5 +- apps/cs/src/pages/menu/ui/menu-page.tsx | 159 ++++++++++-------- 5 files changed, 105 insertions(+), 71 deletions(-) diff --git a/apps/cs/src/pages/menu/api/menu-service.ts b/apps/cs/src/pages/menu/api/menu-service.ts index cdb64b521..4e03f6cdf 100644 --- a/apps/cs/src/pages/menu/api/menu-service.ts +++ b/apps/cs/src/pages/menu/api/menu-service.ts @@ -35,6 +35,13 @@ export class MenuApiService implements MenuService { return response.data; } + public async deleteMenu(menuCd: number): Promise { + const response = await client.delete( + `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`, + ); + return response.data; + } + public async getTreeMenuList(siteId: string): Promise { const response = await client.get( `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`, diff --git a/apps/cs/src/pages/menu/model/menu-interface.ts b/apps/cs/src/pages/menu/model/menu-interface.ts index 91043a76c..2498dde5f 100644 --- a/apps/cs/src/pages/menu/model/menu-interface.ts +++ b/apps/cs/src/pages/menu/model/menu-interface.ts @@ -75,6 +75,7 @@ export interface MenuService { menuCd: number, data: Omit, ) => Promise; + deleteMenu: (menuCd: number) => Promise; getTreeMenuList: (siteId: string) => Promise; modifyTreeMenu: (siteId: string, data: TreeNode[]) => Promise; modifyMenuName: (menuCd: number, name: string) => Promise; diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index 13a910c23..922c2bb78 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -25,7 +25,7 @@ interface MenuFormProps { menuCd: number; data: Omit; }) => void; - handleDelete?: () => void; + handleDelete?: (menuCd: number) => void; } function MenuForm({ @@ -73,7 +73,7 @@ function MenuForm({ const onDelete = () => { handleConfirm(async () => { if (await confirm("삭제하시겠습니까?")) { - handleDelete?.(); + handleDelete?.(menuCd!); } }); }; diff --git a/apps/cs/src/pages/menu/ui/menu-node.tsx b/apps/cs/src/pages/menu/ui/menu-node.tsx index bce0f8ac2..b2e595923 100644 --- a/apps/cs/src/pages/menu/ui/menu-node.tsx +++ b/apps/cs/src/pages/menu/ui/menu-node.tsx @@ -90,7 +90,10 @@ function MenuNode({ "diveicon di-arrow-forward mr-2 text-base text-label", isOpen && "rotate-90", )} - onClick={handleToggle} + onClick={(e) => { + e.stopPropagation(); + handleToggle(); + }} /> )} {text} diff --git a/apps/cs/src/pages/menu/ui/menu-page.tsx b/apps/cs/src/pages/menu/ui/menu-page.tsx index 18837dc26..12b4de492 100644 --- a/apps/cs/src/pages/menu/ui/menu-page.tsx +++ b/apps/cs/src/pages/menu/ui/menu-page.tsx @@ -4,6 +4,7 @@ import { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import type { NodeModel } from "@minoru/react-dnd-treeview"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Button, @@ -16,6 +17,7 @@ import { import { SiteApi } from "@/entities/site"; import { ENDPOINT } from "@/shared/config"; import { PageLayout } from "@/shared/ui/page-layout"; +import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; import { useAlertStore } from "@/shared/lib/use-alert-store"; import type { TreeMenu } from "../model/menu-interface"; import { MenuApi } from "../api/menu-service"; @@ -31,8 +33,10 @@ import { generateTreeData } from "../lib/utils"; function MenuPage() { const queryClient = useQueryClient(); const { setMessage: alert } = useAlertStore((state) => state); + const { confirm } = useConfirm(); const [siteId, setSiteId] = useState(""); + const [onConfirm, setOnConfirm] = useState(false); const [selectedMenu, setSelectedMenu] = useState(null); const [additionalNode, setAdditionalNode] = useState | null>(null); @@ -72,7 +76,7 @@ function MenuPage() { onSuccess: () => { alert("저장되었습니다."); queryClient.invalidateQueries({ - queryKey: [ENDPOINT.CMS_SERVICE.MENUS], + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId], }); }, }); @@ -88,7 +92,17 @@ function MenuPage() { onSuccess: () => { alert("수정되었습니다."); queryClient.invalidateQueries({ - queryKey: [ENDPOINT.CMS_SERVICE.MENUS], + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId], + }); + }, + }); + + const { mutate: deleteMenu } = useMutation({ + mutationFn: (menuCd: number) => MenuApi.deleteMenu(menuCd), + onSuccess: () => { + alert("삭제되었습니다."); + queryClient.invalidateQueries({ + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId], }); }, }); @@ -132,17 +146,14 @@ function MenuPage() { ...additionalNodeForm.getValues(), prntMenuCd, }); + resetAdditionalNode(); + }; + + const resetAdditionalNode = () => { additionalNodeForm.setValue("menuKornNm", ""); setAdditionalNode(null); }; - const handleAdditionalNodeCancel = () => { - additionalNodeForm.setValue("menuKornNm", ""); - setAdditionalNode(null); - }; - - const handleDelete = async () => {}; - const handleSiteIdChange = (value: string) => { form.setValue("siteId", value); additionalNodeForm.setValue("siteId", value); @@ -162,6 +173,14 @@ function MenuPage() { additionalNodeForm.setValue("levelNo", (node.data.levelNo ?? 0) + 1); }; + const handleNodeDelete = async () => { + setOnConfirm(true); + if (await confirm("삭제하시겠습니까?")) { + setOnConfirm(false); + deleteMenu(selectedMenu!.menuCd!); + } + }; + const handleAddMenu = () => { if (additionalNode) return; setAdditionalNode({ @@ -176,66 +195,70 @@ function MenuPage() { : (treeData ?? []); return ( - -
-
- - {siteId && ( - <> -
- - -
-
- -
- - )} + <> + +
+
+ + {siteId && ( + <> +
+ + +
+
+ +
+ + )} +
+
+ +
-
- -
-
- + + + ); }