From daf9a52aecfc09b1787642fab2cf7c19f5cf1944 Mon Sep 17 00:00:00 2001 From: bicochan Date: Fri, 14 Mar 2025 19:35:57 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=82=AC=EC=9D=B4=ED=8A=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/package.json | 1 + apps/cs/src/entities/site/api/site-service.ts | 17 +- apps/cs/src/pages/site/ui/modify-page.tsx | 21 +- apps/cs/src/pages/site/ui/site-form.tsx | 657 ++++++++++-------- apps/cs/src/shared/provider/app-provider.tsx | 5 +- pnpm-lock.yaml | 48 ++ 6 files changed, 430 insertions(+), 319 deletions(-) diff --git a/apps/cs/package.json b/apps/cs/package.json index 05c224ea3..402f0d414 100644 --- a/apps/cs/package.json +++ b/apps/cs/package.json @@ -11,6 +11,7 @@ "dependencies": { "@common/assets": "workspace:*", "@common/components": "workspace:*", + "@frontend-opensource/use-react-hooks": "^1.1.4", "@hookform/resolvers": "^4.1.3", "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2", diff --git a/apps/cs/src/entities/site/api/site-service.ts b/apps/cs/src/entities/site/api/site-service.ts index 478143392..1c9d34361 100644 --- a/apps/cs/src/entities/site/api/site-service.ts +++ b/apps/cs/src/entities/site/api/site-service.ts @@ -25,6 +25,15 @@ export class SiteApiService implements SiteService { return response.data; } + public async createSite(data: SiteFormData): Promise { + const validatedData = siteFormSchema.parse(data); + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.SITES}`, + validatedData, + ); + return response.data; + } + public async modifySite(siteId: string, data: SiteFormData): Promise { const validatedData = siteFormSchema.parse(data); const response = await client.put( @@ -34,11 +43,9 @@ export class SiteApiService implements SiteService { return response.data; } - public async createSite(data: SiteFormData): Promise { - const validatedData = siteFormSchema.parse(data); - const response = await client.post( - `${ENDPOINT.CMS_SERVICE.SITES}`, - validatedData, + public async deleteSite(siteId: string): Promise { + const response = await client.delete( + `${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, ); return response.data; } diff --git a/apps/cs/src/pages/site/ui/modify-page.tsx b/apps/cs/src/pages/site/ui/modify-page.tsx index 5534c75bc..982f12472 100644 --- a/apps/cs/src/pages/site/ui/modify-page.tsx +++ b/apps/cs/src/pages/site/ui/modify-page.tsx @@ -40,11 +40,17 @@ function ModifyPage({ siteId }: { siteId: string }) { const { mutateAsync: modifySite } = useMutation({ mutationFn: (data: SiteFormData) => SiteApi.modifySite(siteId, data), onSuccess: () => { - setIsModifySuccess(true); + setMessage("수정되었습니다."); }, }); - const [isModifySuccess, setIsModifySuccess] = useState(false); + const { mutateAsync: deleteSite } = useMutation({ + mutationFn: () => SiteApi.deleteSite(siteId), + onSuccess: () => { + setMessage("삭제되었습니다."); + }, + }); + const [message, setMessage] = useState(""); const form = useForm({ resolver: zodResolver(siteFormSchema), @@ -64,11 +70,16 @@ function ModifyPage({ siteId }: { siteId: string }) { return ( - - router.back()}> + + router.back()}>
-

수정되었습니다.

+

{message}

diff --git a/apps/cs/src/pages/site/ui/site-form.tsx b/apps/cs/src/pages/site/ui/site-form.tsx index c1a5dfc02..2178befca 100644 --- a/apps/cs/src/pages/site/ui/site-form.tsx +++ b/apps/cs/src/pages/site/ui/site-form.tsx @@ -1,8 +1,13 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { type UseFormReturn } from "react-hook-form"; import { Button, + Dialog, + DialogClose, + DialogContent, + DialogFooter, Input, Label, RadioGroup, @@ -32,10 +37,12 @@ type SiteFormProps = { form: UseFormReturn; siteId?: string; handleSave: (data: SiteFormData) => void; + handleDelete: () => void; }; -function SiteForm({ form, siteId, handleSave }: SiteFormProps) { +function SiteForm({ form, siteId, handleSave, handleDelete }: SiteFormProps) { const router = useRouter(); + const { message, confirm, onConfirm, onCancel } = useConfirm(); const [viewState, setViewState] = useState>({}); const [representativeDomain, setRepresentativeDomain] = useState(""); @@ -56,334 +63,368 @@ function SiteForm({ form, siteId, handleSave }: SiteFormProps) { handleSave(data); }; + const onDelete = async () => { + if (await confirm("정말 삭제하시겠습니까?")) { + handleDelete(); + } + }; + return ( -
- -
-
-

- 사이트 등록/수정 -

-
-
- - - - - - - - 사이트 코드 - - ( - - - - - - - )} - /> - - - - 사이트 구분 - -
+ <> + + +
+
+

+ 사이트 등록/수정 +

+
+
+
+ + + + + + + 사이트 코드 + ( - { - handleViewStateChange("siteKndCd")(value); - field.onChange(value); - }} + className="w-[12rem] !text-[1.3rem]" + disabled={isModifyMode} /> )} /> - {isModifyMode && ( - - )} - - - - - 사이트 디자인 - - ( - - - - - - - )} - /> - - - - 사이트명 - - ( - - - - - - - )} - /> - - - - 사이트 설명 - - ( - - - - - - - )} - /> - - - {isModifyMode && ( + + - 사이트 도메인 + 사이트 구분
-
- {representativeDomain} -
- + ( + + + { + handleViewStateChange("siteKndCd")(value); + field.onChange(value); + }} + /> + + + + )} + /> + {isModifyMode && ( + + )}
- )} - - 사이트 하단 표기 주소 - - ( - - - - - - - )} - /> - - - - 사이트 하단 표기 전화번호 - - ( - - - - - - - )} - /> - - - - 사이트 하단 표기 팩스번호 - - ( - - - - - - - )} - /> - - - - 사이트 하단 표기 내용 - - ( - - - - - - - )} - /> - - - - 북마크 아이콘 - - ( - - - - - - - )} - /> - - - - 기본 사이트 여부 - - ( - - - -
- - -
-
- - -
-
-
- -
- )} - /> -
-
- - 사용 여부 - - ( - - - -
- - -
-
- - -
-
-
- -
- )} - /> -
-
-
-
+ + 사이트 디자인 + + ( + + + + + + + )} + /> + + + + 사이트명 + + ( + + + + + + + )} + /> + + + + 사이트 설명 + + ( + + + + + + + )} + /> + + + {isModifyMode && ( + + 사이트 도메인 + +
+
+ {representativeDomain} +
+ +
+
+
+ )} + + 사이트 하단 표기 주소 + + ( + + + + + + + )} + /> + + + + 사이트 하단 표기 전화번호 + + ( + + + + + + + )} + /> + + + + 사이트 하단 표기 팩스번호 + + ( + + + + + + + )} + /> + + + + 사이트 하단 표기 내용 + + ( + + + + + + + )} + /> + + + + 북마크 아이콘 + + ( + + + + + + + )} + /> + + + + 기본 사이트 여부 + + ( + + + +
+ + +
+
+ + +
+
+
+ +
+ )} + /> +
+
+ + 사용 여부 + + ( + + + +
+ + +
+
+ + +
+
+
+ +
+ )} + /> +
+
+ + +
- -
- - - {isModifyMode && ( - - )} -
-
- + + {isModifyMode && ( + + )} + + + + + +
+

{message}

+
+ + + + + + + + +
+
+ ); } diff --git a/apps/cs/src/shared/provider/app-provider.tsx b/apps/cs/src/shared/provider/app-provider.tsx index 6c1d45410..49e9ead2a 100644 --- a/apps/cs/src/shared/provider/app-provider.tsx +++ b/apps/cs/src/shared/provider/app-provider.tsx @@ -1,5 +1,6 @@ "use client"; +import { ConfirmProvider } from "@frontend-opensource/use-react-hooks"; import { BaseLayout } from "@common/components/ui"; import { AuthProvider } from "./auth-provider"; import { CookieProvider } from "./cookie-provider"; @@ -10,7 +11,9 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { - {children} + + {children} + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5fe9f771..58b9fe203 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,9 @@ importers: '@common/components': specifier: workspace:* version: link:../../packages/common/components + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 '@hookform/resolvers': specifier: ^4.1.3 version: 4.1.3(react-hook-form@7.54.2) @@ -1140,6 +1143,15 @@ packages: resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} dev: false + /@frontend-opensource/use-react-hooks@1.1.4: + resolution: {integrity: sha512-otCSyciL5MVCNNYmdDdg2lEL6rbZ3XX1meYQCzapUSC4V6qx2YxMk1kUbhwEM/+vdxhYzBHsVBGD0rZWl5cgrw==} + dependencies: + async-wave: 1.8.6 + fast-deep-equal: 3.1.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@hookform/resolvers@4.1.3(react-hook-form@7.54.2): resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} peerDependencies: @@ -3703,6 +3715,17 @@ packages: engines: {node: '>= 0.4'} dev: true + /async-wave@1.8.6: + resolution: {integrity: sha512-wqWvr0Mrc1TrY92hN9MV0Xebxa6kt+T7QtjZ7FEMv+RUBa/Hfpz/UOgz0rB+7uqVK8TuBSXykOyU/k9gogdLkw==} + dependencies: + is-promise: 4.0.0 + lodash.add: 3.7.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.size: 4.2.0 + dev: false + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false @@ -5476,6 +5499,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + /is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + dev: false + /is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -5724,10 +5751,31 @@ packages: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: true + /lodash.add@3.7.0: + resolution: {integrity: sha512-/uxUZkB6vYiPoGSXADJJE+Ee4W2vU+bxZOFdvJdx+mDgv+qyAO76sWD84Q4FxsMgTjC1+gVFC9YNhdG243QRDw==} + dev: false + + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + dev: false + + /lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + dev: false + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.size@4.2.0: + resolution: {integrity: sha512-wbu3SF1XC5ijqm0piNxw59yCbuUf2kaShumYBLWUrcCvwh6C8odz6SY/wGVzCWTQTFL/1Ygbvqg2eLtspUVVAQ==} + dev: false + /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true