diff --git a/apps/common/features/src/widgets/post/ui/general-file-uploader.tsx b/apps/common/features/src/widgets/post/ui/general-file-uploader.tsx index 99088aa3e..90edbc58b 100644 --- a/apps/common/features/src/widgets/post/ui/general-file-uploader.tsx +++ b/apps/common/features/src/widgets/post/ui/general-file-uploader.tsx @@ -4,10 +4,9 @@ import type { HttpResponse, Upload } from "tus-js-client"; import { Button, FileUploader } from "@common/components"; import { handleTusUpload } from "@/entities/tus"; import { type Attachment } from "@/entities/attachment"; -import type { PostFormData, PostUpdateFormData } from "@/entities/post"; import { setCookie, useAlertStore, useMenuStore } from "@/shared/lib"; -function GeneralFileUploader({ +function GeneralFileUploader({ form, attachmentData, deleteAttachmentIds, @@ -89,10 +88,10 @@ function GeneralFileUploader({ +
{Object.entries(attachments).map(([atflId, attachment]) => { if (deleteAttachmentIds.includes(atflId)) return null; return ( diff --git a/apps/cs/app/(with-base-layout)/popup/register/[popupSn]/page.tsx b/apps/cs/app/(with-base-layout)/popup/register/[popupSn]/page.tsx new file mode 100644 index 000000000..e7388967f --- /dev/null +++ b/apps/cs/app/(with-base-layout)/popup/register/[popupSn]/page.tsx @@ -0,0 +1,10 @@ +import { ModifyPage as VModifyPage } from "@/pages/popup"; + +export default async function ModifyPage({ + params, +}: { + params: Promise<{ popupSn: string }>; +}) { + const { popupSn } = await params; + return ; +} diff --git a/apps/cs/src/pages/popup/api/popup-service.ts b/apps/cs/src/pages/popup/api/popup-service.ts index 59b67ea9b..d32c7c0cc 100644 --- a/apps/cs/src/pages/popup/api/popup-service.ts +++ b/apps/cs/src/pages/popup/api/popup-service.ts @@ -1,10 +1,13 @@ import { ENDPOINT } from "@/shared/config"; import { popupFormSchema, + popupUpdateFormSchema, type PopupFormData, + type PopupInfo, type PopupList, type PopupParams, type PopupService, + type PopupUpdateFormData, } from "../model/popup-interface"; import { client } from "@/shared/api"; @@ -16,10 +19,25 @@ export class PopupApiService implements PopupService { return response.data; } + async getPopupInfo(popupSn: number): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.POPUPS}/${popupSn}`, + ); + return response.data; + } + async createPopup(data: PopupFormData): Promise { const validatedData = popupFormSchema.parse(data); await client.post(ENDPOINT.CMS_SERVICE.POPUPS, validatedData); } + + async updatePopup(popupSn: number, data: PopupUpdateFormData): Promise { + const validatedData = popupUpdateFormSchema.parse(data); + await client.put( + `${ENDPOINT.CMS_SERVICE.POPUPS}/${popupSn}`, + validatedData, + ); + } } export const PopupApi = new PopupApiService(); diff --git a/apps/cs/src/pages/popup/index.ts b/apps/cs/src/pages/popup/index.ts index dfc7388ff..a320768bd 100644 --- a/apps/cs/src/pages/popup/index.ts +++ b/apps/cs/src/pages/popup/index.ts @@ -1,2 +1,3 @@ export { CreatePage } from "./ui/create-page"; +export { ModifyPage } from "./ui/modify-page"; export { PopupPage } from "./ui/popup-page"; diff --git a/apps/cs/src/pages/popup/model/popup-interface.ts b/apps/cs/src/pages/popup/model/popup-interface.ts index 51d78a0fb..6952d873f 100644 --- a/apps/cs/src/pages/popup/model/popup-interface.ts +++ b/apps/cs/src/pages/popup/model/popup-interface.ts @@ -1,5 +1,5 @@ -import type { PageableList, PageableParams } from "@/shared/model"; import { z } from "zod"; +import type { PageableList, PageableParams } from "@/shared/model"; export interface PopupParams extends PageableParams { keyword?: string; @@ -24,6 +24,16 @@ export interface Popup { mdfrNm: string; } +export interface PopupInfo extends Popup { + popupCn: string; + popupVtclPstn: number; + popupHrzntltyPstn: number; + popupLnkgUrl: string; + atflCd: string; + regDt: string; + rgTrNm: string; +} + export const popupFormSchema = z.object({ popupTypeCd: z.string(), contsTypeCd: z.string(), @@ -40,10 +50,22 @@ export const popupFormSchema = z.object({ rgtr: z.string(), }); +export const popupUpdateFormSchema = popupFormSchema + .omit({ + rgtr: true, + }) + .extend({ + mdfr: z.string(), + }) + .partial(); + export type PopupList = PageableList; export type PopupFormData = z.infer; +export type PopupUpdateFormData = z.infer; export interface PopupService { getPopupList(params: PopupParams): Promise; + getPopupInfo(popupSn: number): Promise; createPopup(data: PopupFormData): Promise; + updatePopup(popupSn: number, data: PopupUpdateFormData): Promise; } diff --git a/apps/cs/src/pages/popup/ui/create-page.tsx b/apps/cs/src/pages/popup/ui/create-page.tsx index f157fb3c6..723a10090 100644 --- a/apps/cs/src/pages/popup/ui/create-page.tsx +++ b/apps/cs/src/pages/popup/ui/create-page.tsx @@ -1,5 +1,6 @@ "use client"; +import { useEffect } from "react"; import { useRouter } from "next/navigation"; import { useForm } from "react-hook-form"; import { useMutation } from "@tanstack/react-query"; @@ -8,7 +9,6 @@ import { useUserStore, useAlertStore } from "@/shared/lib"; import { popupFormSchema, type PopupFormData } from "../model/popup-interface"; import { PopupApi } from "../api/popup-service"; import { PopupForm } from "./popup-form"; -import { useEffect } from "react"; function CreatePage() { const router = useRouter(); diff --git a/apps/cs/src/pages/popup/ui/modify-page.tsx b/apps/cs/src/pages/popup/ui/modify-page.tsx new file mode 100644 index 000000000..db556a53b --- /dev/null +++ b/apps/cs/src/pages/popup/ui/modify-page.tsx @@ -0,0 +1,53 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useAlertStore, useUserStore } from "@/shared/lib"; +import { ENDPOINT } from "@/shared/config"; +import { + popupUpdateFormSchema, + type PopupUpdateFormData, +} from "../model/popup-interface"; +import { PopupApi } from "../api/popup-service"; +import { PopupForm } from "./popup-form"; + +function ModifyPage({ popupSn }: { popupSn: number }) { + const router = useRouter(); + const { userInfo } = useUserStore((state) => state); + const { setMessage: alert } = useAlertStore((state) => state); + + const { data: popupInfo } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.POPUPS, popupSn], + queryFn: () => PopupApi.getPopupInfo(popupSn), + enabled: !!popupSn, + }); + + const { mutateAsync: updatePopup } = useMutation({ + mutationFn: (data: PopupUpdateFormData) => + PopupApi.updatePopup(popupSn, data), + onSuccess: () => { + alert("수정되었습니다.", router.back); + }, + }); + + const form = useForm({ + resolver: zodResolver(popupUpdateFormSchema), + values: { + ...popupInfo, + mdfr: userInfo?.userUnqId ?? "", + }, + }); + + return ( +
+
+

팝업 수정

+
+ +
+ ); +} + +export { ModifyPage }; diff --git a/apps/cs/src/pages/popup/ui/popup-form.tsx b/apps/cs/src/pages/popup/ui/popup-form.tsx index 3e0774fab..6ab790ac4 100644 --- a/apps/cs/src/pages/popup/ui/popup-form.tsx +++ b/apps/cs/src/pages/popup/ui/popup-form.tsx @@ -1,5 +1,7 @@ import dynamic from "next/dynamic"; -import { type UseFormReturn } from "react-hook-form"; +import { useEffect, useState } from "react"; +import type { Path, UseFormReturn } from "react-hook-form"; +import { useQuery } from "@tanstack/react-query"; import { Input, Label, @@ -12,29 +14,64 @@ import { TableRow, } from "@common/components"; import { FormWrapper } from "@/widgets/form-wrapper"; -import { CodeSelect } from "@/entities/code"; -import { FormItem, FormControl, FormField } from "@/shared/ui/form"; -import type { PopupFormData } from "../model/popup-interface"; import { GeneralFileUploader } from "@/widgets/post/ui/general-file-uploader"; -import { useState } from "react"; +import { AttachmentApi } from "@/entities/attachment"; +import { CodeSelect } from "@/entities/code"; +import { ENDPOINT } from "@/shared/config"; +import { setCookie } from "@/shared/lib"; +import { FormItem, FormControl, FormField } from "@/shared/ui/form"; +import type { + PopupFormData, + PopupUpdateFormData, +} from "../model/popup-interface"; const Editor = dynamic( () => import("@/entities/editor").then((module) => module.Editor), { ssr: false }, ); -type PopupFormProps = { - form: UseFormReturn; +type PopupFormProps = { + form: UseFormReturn; popupSn?: string; - handleSave: (data: PopupFormData) => Promise; + handleSave: (data: T) => Promise; handleDelete?: () => Promise; }; -function PopupForm({ form, popupSn, ...props }: PopupFormProps) { +function PopupForm({ + form, + popupSn, + handleSave, + ...props +}: PopupFormProps) { + const atflCd = form.getValues("atflCd" as Path); const [deleteAttachmentIds, setDeleteAttachmentIds] = useState([]); + const { data: attachmentData } = useQuery({ + queryKey: [ENDPOINT.ATTACH_SERVICE.ATTACHMENTS, atflCd], + queryFn: () => AttachmentApi.getAttachmentsInfo(atflCd as string), + enabled: !!atflCd, + }); + + const saveHandlerInterceptor = async (data: T) => { + if (deleteAttachmentIds.length > 0) { + await Promise.all( + deleteAttachmentIds.map(AttachmentApi.deleteAttachmentByAtflId), + ); + } + await handleSave(data); + }; + + useEffect(() => { + setCookie("atfl-cd-key", ""); + }, []); + return ( - +
@@ -47,7 +84,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => ( @@ -69,7 +106,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) {
} render={({ field }) => ( @@ -92,7 +129,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { × } render={({ field }) => ( @@ -121,7 +158,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) {
} render={({ field }) => ( @@ -144,7 +181,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { / } render={({ field }) => ( @@ -172,7 +209,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => ( @@ -191,12 +228,13 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => ( @@ -220,7 +258,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => ( @@ -241,12 +279,12 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => ( @@ -260,6 +298,7 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { @@ -270,13 +309,14 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => (
@@ -299,13 +339,14 @@ function PopupForm({ form, popupSn, ...props }: PopupFormProps) { } render={({ field }) => (
diff --git a/apps/cs/src/widgets/post/ui/general-file-uploader.tsx b/apps/cs/src/widgets/post/ui/general-file-uploader.tsx index e6806cae8..90edbc58b 100644 --- a/apps/cs/src/widgets/post/ui/general-file-uploader.tsx +++ b/apps/cs/src/widgets/post/ui/general-file-uploader.tsx @@ -88,10 +88,10 @@ function GeneralFileUploader({ +
{Object.entries(attachments).map(([atflId, attachment]) => { if (deleteAttachmentIds.includes(atflId)) return null; return (