From c221a4537e3706c7b8335deb0e37ba1a828c3a78 Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 27 Mar 2025 18:20:29 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20=EB=93=B1=EB=A1=9D=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/content-service.ts | 19 +++++ .../src/pages/menu/model/content-interface.ts | 23 ++++++ .../cs/src/pages/menu/model/menu-interface.ts | 12 +-- apps/cs/src/pages/menu/model/table-colums.tsx | 32 ++++++++ apps/cs/src/pages/menu/ui/content-dialog.tsx | 73 +++++++++++++++++++ .../src/pages/menu/ui/content-menu-form.tsx | 46 ++++-------- apps/cs/src/shared/config/api.ts | 1 + .../common/components/src/ui/table/index.tsx | 11 +-- 8 files changed, 169 insertions(+), 48 deletions(-) create mode 100644 apps/cs/src/pages/menu/api/content-service.ts create mode 100644 apps/cs/src/pages/menu/model/content-interface.ts create mode 100644 apps/cs/src/pages/menu/model/table-colums.tsx create mode 100644 apps/cs/src/pages/menu/ui/content-dialog.tsx diff --git a/apps/cs/src/pages/menu/api/content-service.ts b/apps/cs/src/pages/menu/api/content-service.ts new file mode 100644 index 000000000..2f76baec8 --- /dev/null +++ b/apps/cs/src/pages/menu/api/content-service.ts @@ -0,0 +1,19 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { + ContentService, + ContentParams, + ContentList, +} from "../model/content-interface"; + +export class ContentApiService implements ContentService { + public async getContentList(params: ContentParams): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.CONTENTS}`, + { params }, + ); + return response.data; + } +} + +export const ContentApi = new ContentApiService(); diff --git a/apps/cs/src/pages/menu/model/content-interface.ts b/apps/cs/src/pages/menu/model/content-interface.ts new file mode 100644 index 000000000..dc789d059 --- /dev/null +++ b/apps/cs/src/pages/menu/model/content-interface.ts @@ -0,0 +1,23 @@ +import type { PageableList, PageableParams } from "@/shared/model"; + +export interface ContentParams extends PageableParams { + siteId?: string; + menuKornNm?: string; + urlPath?: string; + useYn?: string; +} + +export interface Content { + contsSn: number; + contsTtl: string; + aprvContsVer: number; + useYn: string; + rgtr: string; + regDt: string; +} + +export type ContentList = PageableList; + +export interface ContentService { + getContentList(params: ContentParams): Promise; +} diff --git a/apps/cs/src/pages/menu/model/menu-interface.ts b/apps/cs/src/pages/menu/model/menu-interface.ts index 47df6f749..fcee4c505 100644 --- a/apps/cs/src/pages/menu/model/menu-interface.ts +++ b/apps/cs/src/pages/menu/model/menu-interface.ts @@ -1,12 +1,12 @@ import { z } from "zod"; export const MENU_TYPE = { - EMPTY: "empty", - CONTENTS: "contents", - BOARD: "board", - INSIDE: "inside", - OUTSIDE: "outside", - BOTTOM: "bottom", + EMPTY: "EMPTY", + CONTENTS: "CONTENTS", + BOARD: "BOARD", + INSIDE: "INSIDE", + OUTSIDE: "OUTSIDE", + BOTTOM: "BOTTOM", } as const; export type MenuType = (typeof MENU_TYPE)[keyof typeof MENU_TYPE]; diff --git a/apps/cs/src/pages/menu/model/table-colums.tsx b/apps/cs/src/pages/menu/model/table-colums.tsx new file mode 100644 index 000000000..b24b506fd --- /dev/null +++ b/apps/cs/src/pages/menu/model/table-colums.tsx @@ -0,0 +1,32 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { Checkbox } from "@common/components/ui"; +import type { Content } from "../model/content-interface"; + +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor((_, index) => index + 1, { + id: "no", + header: "NO", + }), + columnHelper.accessor("contsTtl", { + id: "contsTtl", + header: "콘텐츠명", + }), + // TODO: 최종수정자, 최종수정일, 승인일시 추가 + columnHelper.display({ + id: "select", + header: "선택", + cell: ({ row }) => { + return ( + + ); + }, + }), +]; + +export { columns }; diff --git a/apps/cs/src/pages/menu/ui/content-dialog.tsx b/apps/cs/src/pages/menu/ui/content-dialog.tsx new file mode 100644 index 000000000..e6aedbb00 --- /dev/null +++ b/apps/cs/src/pages/menu/ui/content-dialog.tsx @@ -0,0 +1,73 @@ +import { useEffect, useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { + getCoreRowModel, + useReactTable, + type RowSelectionState, +} from "@tanstack/react-table"; +import { + Button, + DataTable, + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogTitle, +} from "@common/components/ui"; +import { ENDPOINT } from "@/shared/config"; +import { ContentApi } from "../api/content-service"; +import type { Content } from "../model/content-interface"; +import { columns } from "../model/table-colums"; + +type ContentDialogProps = { + handleContentSelect: (content: Content) => void; +} & React.ComponentProps; + +function ContentDialog({ handleContentSelect, ...props }: ContentDialogProps) { + const [rowSelection, setRowSelection] = useState({}); + + const { data: contentList } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.CONTENTS], + queryFn: () => + ContentApi.getContentList({ useYn: "Y", page: 0, size: 100 }), + }); + + const table = useReactTable({ + data: contentList?.content ?? [], + columns, + state: { + rowSelection, + }, + enableMultiRowSelection: false, + getCoreRowModel: getCoreRowModel(), + onRowSelectionChange: setRowSelection, + }); + + useEffect(() => { + const contentData = table.getSelectedRowModel().rows[0] + ?.original as Content; + if (!contentData) return; + handleContentSelect(contentData); + }, [table.getSelectedRowModel().rows]); + + return ( + + + + + + + 콘텐츠 선택 + +
+ +
+
+
+ ); +} + +export { ContentDialog }; diff --git a/apps/cs/src/pages/menu/ui/content-menu-form.tsx b/apps/cs/src/pages/menu/ui/content-menu-form.tsx index 0905a594b..7ce40d940 100644 --- a/apps/cs/src/pages/menu/ui/content-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/content-menu-form.tsx @@ -16,9 +16,16 @@ import { FormMessage, } from "@/shared/ui/form"; import type { MenuFormData } from "../model/menu-interface"; +import type { Content } from "../model/content-interface"; import { BaseTypeMenuForm } from "./base-type-menu-form"; +import { ContentDialog } from "./content-dialog"; function ContentMenuForm({ form }: { form: UseFormReturn }) { + const handleContentSelect = (content: Content) => { + form.setValue("menuLnkgSn", content.contsSn); + form.setValue("menuLnkgSnNm", content.contsTtl); + }; + return ( @@ -29,42 +36,15 @@ function ContentMenuForm({ form }: { form: UseFormReturn }) { 콘텐츠 -
- {form.watch("menuLnkgSn")} +
+
+ {form.watch("menuLnkgSnNm")} +
+
- - 연결 형태 - - ( - - - -
-
- - -
-
- - -
-
-
-
- -
- )} - /> -
-
+ {/* TODO: 연결 형태 추가 */} 메뉴 평가 사용 여부 diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index e07b6c9ff..b938ceaa9 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -14,6 +14,7 @@ export const ENDPOINT = { IPS: "/cms-service/api/v1/site-ips", DOMAINS: "/cms-service/api/v1/site-dmns", MENUS: "/cms-service/api/v1/menus", + CONTENTS: "/cms-service/api/v1/contents", }, }; diff --git a/packages/common/components/src/ui/table/index.tsx b/packages/common/components/src/ui/table/index.tsx index 797f48dfd..46c8db39c 100644 --- a/packages/common/components/src/ui/table/index.tsx +++ b/packages/common/components/src/ui/table/index.tsx @@ -79,11 +79,7 @@ const TableHead = React.forwardRef< HTMLTableCellElement, React.ThHTMLAttributes >(({ className, ...props }, ref) => ( -
+ )); TableHead.displayName = "TableHead"; @@ -93,10 +89,7 @@ const TableCell = React.forwardRef< >(({ className, ...props }, ref) => ( ));