From 795b4915069c44f500a91638e16ded67b9e16618 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 1 Jul 2025 11:46:33 +0000 Subject: (최겸) 정보시스템 공지사항 개발 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/notice/notice-edit-sheet.tsx | 246 ++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 components/notice/notice-edit-sheet.tsx (limited to 'components/notice/notice-edit-sheet.tsx') diff --git a/components/notice/notice-edit-sheet.tsx b/components/notice/notice-edit-sheet.tsx new file mode 100644 index 00000000..91bcae3b --- /dev/null +++ b/components/notice/notice-edit-sheet.tsx @@ -0,0 +1,246 @@ +"use client" + +import * as React from "react" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import { toast } from "sonner" + +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { Switch } from "@/components/ui/switch" + +import { updateNoticeSchema, type UpdateNoticeSchema } from "@/lib/notice/validations" +import type { Notice } from "@/db/schema/notice" +import { updateNoticeData } from "@/lib/notice/service" +import TiptapEditor from "@/components/qna/tiptap-editor" + +type NoticeWithAuthor = Notice & { + authorName: string | null + authorEmail: string | null +} + +interface UpdateNoticeSheetProps { + open: boolean + onOpenChange: (open: boolean) => void + notice: NoticeWithAuthor | null + pagePathOptions: Array<{ value: string; label: string }> + onSuccess?: () => void +} + +export function UpdateNoticeSheet({ + open, + onOpenChange, + notice, + pagePathOptions, + onSuccess +}: UpdateNoticeSheetProps) { + const [isUpdatePending, startUpdateTransition] = React.useTransition() + + const form = useForm({ + resolver: zodResolver(updateNoticeSchema), + defaultValues: { + id: 0, + pagePath: "", + title: "", + content: "", + isActive: true, + }, + }) + + // notice 데이터가 변경될 때 폼 초기화 + React.useEffect(() => { + if (notice) { + form.reset({ + id: notice.id, + pagePath: notice.pagePath, + title: notice.title, + content: notice.content, + isActive: notice.isActive, + }) + } + }, [notice, form]) + + function onSubmit(input: UpdateNoticeSchema) { + if (!notice) return + + startUpdateTransition(async () => { + try { + const result = await updateNoticeData(input) + + if (result.success) { + toast.success(result.message || "공지사항이 성공적으로 수정되었습니다.") + if (onSuccess) onSuccess() + onOpenChange(false) + } else { + toast.error(result.message || "공지사항 수정에 실패했습니다.") + } + } catch (error) { + toast.error("예기치 못한 오류가 발생했습니다.") + console.error("공지사항 수정 오류:", error) + } + }) + } + + return ( + + + + 공지사항 수정 + + 공지사항의 제목과 내용을 수정할 수 있습니다. 수정된 내용은 즉시 반영됩니다. + + + +
+ + {/* 공지사항 정보 표시 */} + {notice && ( +
+
공지사항 정보
+
+
작성자: {notice.authorName} ({notice.authorEmail})
+
작성일: {new Date(notice.createdAt).toLocaleDateString("ko-KR")}
+
수정일: {new Date(notice.updatedAt).toLocaleDateString("ko-KR")}
+
상태: {notice.isActive ? "활성" : "비활성"}
+
+
+ )} + + {/* 페이지 경로 선택 */} + ( + + 페이지 경로 * + + + + )} + /> + + {/* 제목 입력 */} + ( + + 제목 * + + + + + + )} + /> + + {/* 활성 상태 */} + ( + +
+ 활성 상태 +
+ 활성화하면 해당 페이지에서 공지사항이 표시됩니다. +
+
+ + + +
+ )} + /> + + {/* 내용 입력 (리치텍스트 에디터) */} + ( + + 내용 * + + + + + + )} + /> + + + + + + + +
+
+ ) +} \ No newline at end of file -- cgit v1.2.3