From 5376d21901ae7950b4863867097103e80e96be25 Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 3 Jul 2025 15:17:56 +0900 Subject: [PATCH] =?UTF-8?q?[common/features]=20feat:=20=EC=BD=98=ED=85=90?= =?UTF-8?q?=EC=B8=A0=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/(with-base-layout)/(pst)/layout.tsx | 30 --------------- .../cntns/[contsSn]/page.tsx | 10 +++++ .../app/(with-base-layout)/layout.tsx | 22 +++++++++-- .../entities/content/api/contents-service.ts | 9 +++++ .../content/model/contents-interface.ts | 1 + .../src/entities/menu/lib/menu-wrapper.tsx | 2 +- .../features/src/pages/contents/index.ts | 1 + .../src/pages/contents/ui/contents-page.tsx | 38 +++++++++++++++++++ 8 files changed, 78 insertions(+), 35 deletions(-) delete mode 100644 apps/common/features/app/(with-base-layout)/(pst)/layout.tsx create mode 100644 apps/common/features/app/(with-base-layout)/cntns/[contsSn]/page.tsx create mode 100644 apps/common/features/src/pages/contents/index.ts create mode 100644 apps/common/features/src/pages/contents/ui/contents-page.tsx diff --git a/apps/common/features/app/(with-base-layout)/(pst)/layout.tsx b/apps/common/features/app/(with-base-layout)/(pst)/layout.tsx deleted file mode 100644 index f181eb64f..000000000 --- a/apps/common/features/app/(with-base-layout)/(pst)/layout.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client"; - -import { useQuery } from "@tanstack/react-query"; -import { MenuApi } from "@/entities/menu"; -import { ENDPOINT } from "@/shared/config"; -import { getCookie, useMenuStore } from "@/shared/lib"; -import { PageLayout } from "@/shared/ui/page-layout"; - -export default function PostLayout({ - children, -}: { - children: React.ReactNode; -}) { - const menuCd = getCookie("menu-code-key"); - const bbsInfo = useMenuStore((state) => state.bbsInfo); - - const { data } = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.MENUS, menuCd], - queryFn: () => MenuApi.getMenuInfo(menuCd!), - enabled: !!menuCd, - }); - - const menuPaths = data?.menuPath?.split(">").map((path) => path.trim()); - - return ( - - {children} - - ); -} diff --git a/apps/common/features/app/(with-base-layout)/cntns/[contsSn]/page.tsx b/apps/common/features/app/(with-base-layout)/cntns/[contsSn]/page.tsx new file mode 100644 index 000000000..e8f07bc6b --- /dev/null +++ b/apps/common/features/app/(with-base-layout)/cntns/[contsSn]/page.tsx @@ -0,0 +1,10 @@ +import { ContentsPage as VContentsPage } from "@/pages/contents"; + +export default async function ContentsPage({ + params, +}: { + params: Promise<{ contsSn: string }>; +}) { + const { contsSn } = await params; + return ; +} diff --git a/apps/common/features/app/(with-base-layout)/layout.tsx b/apps/common/features/app/(with-base-layout)/layout.tsx index 5bbd7d024..d357094ae 100644 --- a/apps/common/features/app/(with-base-layout)/layout.tsx +++ b/apps/common/features/app/(with-base-layout)/layout.tsx @@ -1,10 +1,12 @@ "use client"; import { usePathname, useRouter } from "next/navigation"; -import { useQueryClient } from "@tanstack/react-query"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; import { BaseLayout } from "@common/components"; -import type { MenuRole } from "@/entities/menu"; -import { useMenuStore } from "@/shared/lib"; +import { MenuApi, type MenuRole } from "@/entities/menu"; +import { ENDPOINT } from "@/shared/config"; +import { getCookie, useMenuStore } from "@/shared/lib"; +import { PageLayout } from "@/shared/ui/page-layout"; export default function WithBaseLayout({ children, @@ -14,6 +16,16 @@ export default function WithBaseLayout({ const router = useRouter(); const pathname = usePathname(); const queryClient = useQueryClient(); + const bbsInfo = useMenuStore((state) => state.bbsInfo); + + const menuCd = getCookie("menu-code-key"); + const { data } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, menuCd], + queryFn: () => MenuApi.getMenuInfo(menuCd!), + enabled: !!menuCd, + }); + + const menuPaths = data?.menuPath?.split(">").map((path) => path.trim()); const setCurrentMenuInfo = useMenuStore((state) => state.setCurrentMenuInfo); @@ -28,7 +40,9 @@ export default function WithBaseLayout({ currentPath={pathname ?? ""} handleMenuClick={handleMenuClick} > - {children} + + {children} + ); } diff --git a/apps/common/features/src/entities/content/api/contents-service.ts b/apps/common/features/src/entities/content/api/contents-service.ts index 00d2a8c67..f1822ce77 100644 --- a/apps/common/features/src/entities/content/api/contents-service.ts +++ b/apps/common/features/src/entities/content/api/contents-service.ts @@ -19,6 +19,15 @@ export class ContentsApiService implements ContentsService { return response.data; } + public async getLatestApprovedContentsInfo( + contsSn: number, + ): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.CONTENTS}/${contsSn}`, + ); + return response.data; + } + public async getContentsVersionList( params: ContentsVersionParams, ): Promise { diff --git a/apps/common/features/src/entities/content/model/contents-interface.ts b/apps/common/features/src/entities/content/model/contents-interface.ts index 72456149b..9e906d5f1 100644 --- a/apps/common/features/src/entities/content/model/contents-interface.ts +++ b/apps/common/features/src/entities/content/model/contents-interface.ts @@ -81,6 +81,7 @@ export type ContentsVersionList = PageableList; export interface ContentsService { getContentsList(params: ContentsParams): Promise; + getLatestApprovedContentsInfo(contsSn: number): Promise; getContentsVersionList( params: ContentsVersionParams, ): Promise; diff --git a/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx b/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx index e3007f8be..1dafbde35 100644 --- a/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx +++ b/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx @@ -45,7 +45,7 @@ const MenuWrapper = ({ children }: { children: React.ReactNode }) => { if (pageMenuAuthority?.length) setPageMenuAuthority(pageMenuAuthority[0]!); })(); - }, []); + }, [pathname]); useEffect(() => { if (!pageMenuAuthority) return; diff --git a/apps/common/features/src/pages/contents/index.ts b/apps/common/features/src/pages/contents/index.ts new file mode 100644 index 000000000..c14f174e2 --- /dev/null +++ b/apps/common/features/src/pages/contents/index.ts @@ -0,0 +1 @@ +export { ContentsPage } from "./ui/contents-page"; diff --git a/apps/common/features/src/pages/contents/ui/contents-page.tsx b/apps/common/features/src/pages/contents/ui/contents-page.tsx new file mode 100644 index 000000000..c0c8a4f74 --- /dev/null +++ b/apps/common/features/src/pages/contents/ui/contents-page.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { ContentsApi } from "@/entities/content"; +import { ENDPOINT } from "@/shared/config"; + +function ContentsPage({ contsSn }: { contsSn: number }) { + const shadowRootRef = useRef(null); + + const { data: contentsDetail } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS, contsSn], + queryFn: () => ContentsApi.getLatestApprovedContentsInfo(contsSn), + enabled: !!contsSn, + }); + + useEffect(() => { + if (!shadowRootRef.current || !contentsDetail?.contsCn) return; + + const shadowRoot = shadowRootRef.current.attachShadow({ mode: "open" }); + + const styleElement = document.createElement("style"); + styleElement.textContent = `div { font-size: 16px; line-height: 1.5; }`; + shadowRoot.appendChild(styleElement); + + const contentElement = document.createElement("div"); + contentElement.innerHTML = contentsDetail.contsCn; + shadowRoot.appendChild(contentElement); + }, [contentsDetail?.contsCn]); + + return ( +
+
+
+ ); +} + +export { ContentsPage };