diff --git a/apps/cs/src/entities/board/api/board-service.ts b/apps/cs/src/entities/board/api/board-service.ts new file mode 100644 index 000000000..9cf29599b --- /dev/null +++ b/apps/cs/src/entities/board/api/board-service.ts @@ -0,0 +1,21 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { + BoardPopupList, + BoardPopupParams, + BoardService, +} from "../model/board-interface"; + +export class BoardApiService implements BoardService { + public async getBoardPopupList( + params: BoardPopupParams, + ): Promise { + const response = await client.get( + `${ENDPOINT.BOARD_SERVICE.BBS}`, + { params }, + ); + return response.data; + } +} + +export const BoardApi = new BoardApiService(); diff --git a/apps/cs/src/entities/board/index.ts b/apps/cs/src/entities/board/index.ts new file mode 100644 index 000000000..2173bb4a0 --- /dev/null +++ b/apps/cs/src/entities/board/index.ts @@ -0,0 +1,2 @@ +export { BoardApi } from "./api/board-service"; +export { type BoardPopup } from "./model/board-interface"; diff --git a/apps/cs/src/entities/board/model/board-interface.ts b/apps/cs/src/entities/board/model/board-interface.ts new file mode 100644 index 000000000..942840d74 --- /dev/null +++ b/apps/cs/src/entities/board/model/board-interface.ts @@ -0,0 +1,42 @@ +import type { PageableList, PageableParams } from "@/shared/model"; + +export const BOARD_TYPE = { + BBSNORMAL: "BBSNORMAL", + BBSFAQ: "BBSFAQ", + BBSIMAGE: "BBSIMAGE", + BBSMOVIE: "BBSMOVIE", +} as const; + +export type BoardType = (typeof BOARD_TYPE)[keyof typeof BOARD_TYPE]; + +export interface BoardPopupParams extends PageableParams { + bbsNm?: string; +} + +export interface BoardPopup { + bbsId: number; + bbsTypeCd: BoardType; + bbsTypeNm: string; + bbsNm: string; + bbsExpln: string; + rfrncUseYn: string; + atflUseYn: string; + atflMaxCnt: number; + atflMaxFileSz: number; + ansUseYn: string; + cmntUseYn: string; + dgstfnEvlUseYn: string; + smsUseYn: string; + upndFixUseYn: string; + pstgPrdUseYn: string; + popupUseYn: string; + delYn: string; + regDt: string; + pstCnt: number; +} + +export type BoardPopupList = PageableList; + +export interface BoardService { + getBoardPopupList: (params: BoardPopupParams) => Promise; +} diff --git a/apps/cs/src/pages/menu/model/board-table-columns.tsx b/apps/cs/src/pages/menu/model/board-table-columns.tsx new file mode 100644 index 000000000..f144ac158 --- /dev/null +++ b/apps/cs/src/pages/menu/model/board-table-columns.tsx @@ -0,0 +1,43 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { Checkbox } from "@common/components/ui"; +import type { BoardPopup } from "@/entities/board"; + +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor((_, index) => index + 1, { + id: "no", + header: "NO", + }), + columnHelper.accessor("bbsNm", { + id: "bbsNm", + header: "게시판명", + }), + columnHelper.accessor("bbsTypeNm", { + id: "bbsTypeNm", + header: "게시판유형", + }), + columnHelper.accessor("regDt", { + id: "regDt", + header: "최초생성일", + }), + columnHelper.accessor("pstCnt", { + id: "pstCnt", + header: "게시물건수", + }), + columnHelper.display({ + id: "select", + header: "선택", + cell: ({ row }) => { + return ( + + ); + }, + }), +]; + +export { columns }; diff --git a/apps/cs/src/pages/menu/ui/board-search-dialog.tsx b/apps/cs/src/pages/menu/ui/board-search-dialog.tsx new file mode 100644 index 000000000..531e17c86 --- /dev/null +++ b/apps/cs/src/pages/menu/ui/board-search-dialog.tsx @@ -0,0 +1,95 @@ +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, + Input, +} from "@common/components/ui"; +import { ENDPOINT } from "@/shared/config"; +import { BoardApi, type BoardPopup } from "@/entities/board"; +import { columns } from "../model/board-table-columns"; + +type BoardSearchDialogProps = { + handleBoardSelect: (board: BoardPopup) => void; +} & React.ComponentProps; + +function BoardSearchDialog({ + handleBoardSelect, + ...props +}: BoardSearchDialogProps) { + const [rowSelection, setRowSelection] = useState({}); + const [bbsNm, setBbsNm] = useState(""); + + const { data: boardList, refetch } = useQuery({ + queryKey: [ENDPOINT.BOARD_SERVICE.BBS], + queryFn: () => BoardApi.getBoardPopupList({ bbsNm }), + enabled: false, + }); + + const table = useReactTable({ + data: boardList?.content ?? [], + columns, + state: { + rowSelection, + }, + enableMultiRowSelection: false, + getCoreRowModel: getCoreRowModel(), + onRowSelectionChange: setRowSelection, + }); + + useEffect(() => { + const boardData = table.getSelectedRowModel().rows[0] + ?.original as BoardPopup; + if (!boardData) return; + handleBoardSelect(boardData); + }, [table.getSelectedRowModel().rows]); + + useEffect(() => { + refetch(); + }, []); + + return ( + + + + + + + 게시판 조회 + +
+
+ setBbsNm(e.target.value)} + /> + +
+
+ +
+
+
+
+ ); +} + +export { BoardSearchDialog }; diff --git a/apps/cs/src/pages/menu/ui/type-menu-form.tsx b/apps/cs/src/pages/menu/ui/type-menu-form.tsx index 209cadb1a..e02d6dacc 100644 --- a/apps/cs/src/pages/menu/ui/type-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/type-menu-form.tsx @@ -19,11 +19,13 @@ import { FormField, FormMessage, } from "@/shared/ui/form"; +import type { BoardPopup } from "@/entities/board"; import type { Content } from "../model/content-interface"; import type { User } from "../model/organization-interface"; import type { MenuFormData, MenuType } from "../model/menu-interface"; import { OrganizationSearchDialog } from "./organization-search-dialog"; import { ContentSearchDialog } from "./content-search-dialog"; +import { BoardSearchDialog } from "./board-search-dialog"; type TypeMenuFormProps = { form: UseFormReturn; @@ -45,6 +47,11 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) { form.setValue("menuPicUserUnqIdNm", user.userNm); }; + const handleBoardSelect = (board: BoardPopup) => { + form.setValue("menuLnkgSn", board.bbsId); + form.setValue("menuLnkgSnNm", board.bbsNm); + }; + const handleDateSelect = (date: Date | undefined) => { if (!date) return; form.setValue("menuPicDsgnYmd", dayjs(date).format("YYYYMMDD")); @@ -63,6 +70,8 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) {
+ {!form.watch("menuLnkgSnNm") && + "메뉴에 표시될 콘텐츠를 조회 후 선택하십시오."} {form.watch("menuLnkgSnNm")}
게시판 -
- {form.watch("menuLnkgSnNm")} +
+
+ {!form.watch("menuLnkgSnNm") && + "메뉴에 표시될 게시판을 조회 후 선택하십시오."} + {form.watch("menuLnkgSnNm")} +
+
@@ -180,6 +194,7 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) {
+ {!form.watch("iconNm") && "아이콘을 조회 후 선택하십시오."} {form.watch("iconNm")}
@@ -291,6 +306,8 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) {
+ {!form.watch("menuPicUserUnqIdNm") && + "메뉴 담당자를 조회 후 선택하십시오."} {form.watch("menuPicUserUnqIdNm")}