From 41dbb368c308a50dac69f4308c54e0422e23fcfd Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 17 Apr 2025 17:20:12 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=93=B1?= =?UTF-8?q?=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 --- .../contents/register/page.tsx | 2 + apps/cs/middleware.ts | 5 +- .../entities/contents/api/contents-service.ts | 2 +- apps/cs/src/entities/contents/index.ts | 7 +- .../contents/model/contents-interface.ts | 8 +- apps/cs/src/pages/contents/index.ts | 1 + .../src/pages/contents/ui/contents-form.tsx | 198 ++++++++++++++++++ apps/cs/src/pages/contents/ui/create-page.tsx | 43 ++++ apps/cs/src/pages/template/ui/create-page.tsx | 3 +- apps/cs/src/shared/config/api.ts | 1 + 10 files changed, 265 insertions(+), 5 deletions(-) create mode 100644 apps/cs/app/(with-base-layout)/contents/register/page.tsx create mode 100644 apps/cs/src/pages/contents/ui/contents-form.tsx create mode 100644 apps/cs/src/pages/contents/ui/create-page.tsx diff --git a/apps/cs/app/(with-base-layout)/contents/register/page.tsx b/apps/cs/app/(with-base-layout)/contents/register/page.tsx new file mode 100644 index 000000000..fc33228e2 --- /dev/null +++ b/apps/cs/app/(with-base-layout)/contents/register/page.tsx @@ -0,0 +1,2 @@ +import { CreatePage } from "@/pages/contents"; +export default CreatePage; diff --git a/apps/cs/middleware.ts b/apps/cs/middleware.ts index 923069eb9..d56c1f8ab 100644 --- a/apps/cs/middleware.ts +++ b/apps/cs/middleware.ts @@ -13,7 +13,7 @@ export function middleware(req: NextRequest) { const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${ queryParams ? `?${queryParams}` : "" }`; - console.log("Rewriting to >>>>", newUrl); + console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); } @@ -26,6 +26,9 @@ export function middleware(req: NextRequest) { if (token) requestHeaders.set(CLAIM_NAME, token); if (userId) requestHeaders.set(AUTH_USER_ID, userId); + console.log( + `[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`, + ); return NextResponse.rewrite(new URL(newUrl), { headers: requestHeaders, }); diff --git a/apps/cs/src/entities/contents/api/contents-service.ts b/apps/cs/src/entities/contents/api/contents-service.ts index 8d73d2bf0..06f141fae 100644 --- a/apps/cs/src/entities/contents/api/contents-service.ts +++ b/apps/cs/src/entities/contents/api/contents-service.ts @@ -26,7 +26,7 @@ export class ContentsApiService implements ContentsService { public async createContents(data: ContentsFormData): Promise { const response = await client.post( - `${ENDPOINT.CMS_SERVICE.CONTENTS}`, + `${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}`, data, ); return response.data; diff --git a/apps/cs/src/entities/contents/index.ts b/apps/cs/src/entities/contents/index.ts index 6c612996c..5df94d667 100644 --- a/apps/cs/src/entities/contents/index.ts +++ b/apps/cs/src/entities/contents/index.ts @@ -1,2 +1,7 @@ export { ContentsApi } from "./api/contents-service"; -export type { Contents, ContentsParams } from "./model/contents-interface"; +export { + contentsFormSchema, + type Contents, + type ContentsParams, + type ContentsFormData, +} from "./model/contents-interface"; diff --git a/apps/cs/src/entities/contents/model/contents-interface.ts b/apps/cs/src/entities/contents/model/contents-interface.ts index 7eddaad30..7a7c6dcf0 100644 --- a/apps/cs/src/entities/contents/model/contents-interface.ts +++ b/apps/cs/src/entities/contents/model/contents-interface.ts @@ -23,9 +23,15 @@ export const contentsSchema = z.object({ }); export const contentsFormSchema = z.object({ + contsSn: z.number().nullish(), contsTtl: z.string(), + contsCn: z.string(), + contsRmrk: z.string().nullish(), + aprvCd: z.string().nullish(), + cclCd: z.string().nullish(), + koglCd: z.string().nullish(), + tag: z.string().nullish(), useYn: z.string(), - rgtr: z.string().nullish(), }); export type Contents = z.infer; diff --git a/apps/cs/src/pages/contents/index.ts b/apps/cs/src/pages/contents/index.ts index c14f174e2..f6dc4a528 100644 --- a/apps/cs/src/pages/contents/index.ts +++ b/apps/cs/src/pages/contents/index.ts @@ -1 +1,2 @@ export { ContentsPage } from "./ui/contents-page"; +export { CreatePage } from "./ui/create-page"; diff --git a/apps/cs/src/pages/contents/ui/contents-form.tsx b/apps/cs/src/pages/contents/ui/contents-form.tsx new file mode 100644 index 000000000..0294dff74 --- /dev/null +++ b/apps/cs/src/pages/contents/ui/contents-form.tsx @@ -0,0 +1,198 @@ +import dynamic from "next/dynamic"; +import { type UseFormReturn } from "react-hook-form"; +import { + Input, + Label, + RadioGroup, + RadioGroupItem, + Table, + TableBody, + TableCell, + TableHead, + TableRow, +} from "@common/components"; +import { FormWrapper } from "@/widgets/form-wrapper"; +import { FormItem, FormControl, FormField } from "@/shared/ui/form"; +import type { ContentsFormData } from "@/entities/contents"; + +const Editor = dynamic( + () => import("@/entities/editor").then((module) => module.Editor), + { ssr: false }, +); + +interface ContentsFormProps { + form: UseFormReturn; + contsSn?: number; + handleSave: (data: ContentsFormData) => Promise; + handleDelete?: () => Promise; +} + +function ContentsForm({ form, contsSn, ...props }: ContentsFormProps) { + return ( + +
+ + + + + + + + 콘텐츠 제목 + + ( + + + + + + )} + /> + + + + 콘텐츠 내용 + + ( + + + + + + )} + /> + + + + CCL + + ( + + + +
+ + +
+
+ + +
+
+
+
+ )} + /> +
+
+ + 공공누리 + + ( + + + +
+ + +
+
+ + +
+
+
+
+ )} + /> +
+
+ + 태그 + + ( + + + + + + )} + /> + + + + 사용여부 + + ( + + + +
+ + +
+
+ + +
+
+
+
+ )} + /> +
+
+
+
+
+
+ ); +} + +export { ContentsForm }; diff --git a/apps/cs/src/pages/contents/ui/create-page.tsx b/apps/cs/src/pages/contents/ui/create-page.tsx new file mode 100644 index 000000000..947ea10c9 --- /dev/null +++ b/apps/cs/src/pages/contents/ui/create-page.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { useForm } from "react-hook-form"; +import { useRouter } from "next/navigation"; +import { useMutation } from "@tanstack/react-query"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { + ContentsApi, + contentsFormSchema, + type ContentsFormData, +} from "@/entities/contents"; +import { useAlertStore } from "@/shared/lib/use-alert-store"; +import { ContentsForm } from "./contents-form"; + +function CreatePage() { + const router = useRouter(); + const { setMessage: alert } = useAlertStore((state) => state); + + const { mutateAsync: createContents } = useMutation({ + mutationFn: (data: ContentsFormData) => ContentsApi.createContents(data), + onSuccess: () => { + alert("등록되었습니다.", router.back); + }, + }); + + const form = useForm({ + resolver: zodResolver(contentsFormSchema), + defaultValues: { + useYn: "Y", + }, + }); + + return ( +
+
+

콘텐츠 등록

+
+ +
+ ); +} + +export { CreatePage }; diff --git a/apps/cs/src/pages/template/ui/create-page.tsx b/apps/cs/src/pages/template/ui/create-page.tsx index 8057ddd00..f3b445809 100644 --- a/apps/cs/src/pages/template/ui/create-page.tsx +++ b/apps/cs/src/pages/template/ui/create-page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useRouter } from "next/navigation"; import { useForm } from "react-hook-form"; +import { useRouter } from "next/navigation"; import { useMutation } from "@tanstack/react-query"; import { zodResolver } from "@hookform/resolvers/zod"; import { TemplateApi } from "../api/template-service"; @@ -15,6 +15,7 @@ import { TemplateForm } from "./template-form"; function CreatePage() { const router = useRouter(); const { setMessage: alert } = useAlertStore((state) => state); + const { mutateAsync: createTemplate } = useMutation({ mutationFn: (data: TemplateFormData) => TemplateApi.createTemplate(data), onSuccess: () => { diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index 2b98fb4e5..1a77bbb10 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -26,6 +26,7 @@ export const ENDPOINT = { MENU_ROLES: "/cms-service/api/v1/menu-roles", MENU_AUTHRTS: "/cms-service/api/v1/menu-authrts", CONTENTS: "/cms-service/api/v1/contents", + CONTENTS_DETAILS: "/cms-service/api/v1/contents-details", USER_ORGANIZATION: "/cms-service/api/v1/user-ognz", IMAGES: "/cms-service/api/v1/images", BANNERS: "/cms-service/api/v1/bnrs",