From 795b4915069c44f500a91638e16ded67b9e16618 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
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-create-dialog.tsx | 216 +++++++++++++++++++++++++++++
 1 file changed, 216 insertions(+)
 create mode 100644 components/notice/notice-create-dialog.tsx

(limited to 'components/notice/notice-create-dialog.tsx')

diff --git a/components/notice/notice-create-dialog.tsx b/components/notice/notice-create-dialog.tsx
new file mode 100644
index 00000000..e3ce16a1
--- /dev/null
+++ b/components/notice/notice-create-dialog.tsx
@@ -0,0 +1,216 @@
+"use client"
+
+import * as React from "react"
+import { useState } from "react"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { useForm } from "react-hook-form"
+import { toast } from "sonner"
+import { Loader } from "lucide-react"
+import { Button } from "@/components/ui/button"
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+} from "@/components/ui/dialog"
+import {
+  Form,
+  FormControl,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from "@/components/ui/form"
+import { Input } from "@/components/ui/input"
+import { Switch } from "@/components/ui/switch"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import TiptapEditor from "@/components/qna/tiptap-editor"
+import { createNotice } from "@/lib/notice/service"
+import { createNoticeSchema, type CreateNoticeSchema } from "@/lib/notice/validations"
+
+interface NoticeCreateDialogProps {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+  pagePathOptions: Array<{ value: string; label: string }>
+  currentUserId?: number
+  onSuccess?: () => void
+}
+
+export function NoticeCreateDialog({
+  open,
+  onOpenChange,
+  pagePathOptions,
+  currentUserId,
+  onSuccess,
+}: NoticeCreateDialogProps) {
+  const [isLoading, setIsLoading] = useState(false)
+
+  const form = useForm<CreateNoticeSchema>({
+    resolver: zodResolver(createNoticeSchema),
+    defaultValues: {
+      pagePath: "",
+      title: "",
+      content: "",
+      authorId: currentUserId,
+      isActive: true,
+    },
+  })
+
+  React.useEffect(() => {
+    if (open) {
+      // 다이얼로그가 열릴 때마다 폼 초기화
+      form.reset({
+        pagePath: "",
+        title: "",
+        content: "",
+        authorId: currentUserId,
+        isActive: true,
+      })
+    }
+  }, [open, currentUserId, form])
+
+  const onSubmit = async (values: CreateNoticeSchema) => {
+    setIsLoading(true)
+    console.log("Form values:", values) // 디버깅용
+    try {
+      const result = await createNotice(values)
+      console.log("Create result:", result) // 디버깅용
+
+      if (result.success) {
+        toast.success(result.message || "공지사항이 성공적으로 생성되었습니다.")
+        if (onSuccess) onSuccess()
+        onOpenChange(false)
+      } else {
+        toast.error(result.message || "공지사항 생성에 실패했습니다.")
+        console.error("Create failed:", result.message)
+      }
+    } catch (error) {
+      toast.error("공지사항 생성에 실패했습니다.")
+      console.error("Create error:", error)
+    } finally {
+      setIsLoading(false)
+    }
+  }
+
+
+
+  return (
+    <Dialog open={open} onOpenChange={onOpenChange}>
+      <DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
+        <DialogHeader>
+          <DialogTitle className="text-xl font-bold">
+            새 공지사항 작성
+          </DialogTitle>
+        </DialogHeader>
+
+        <Form {...form}>
+          <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
+            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
+              <FormField
+                control={form.control}
+                name="pagePath"
+                render={({ field }) => (
+                  <FormItem>
+                    <FormLabel>페이지 경로 *</FormLabel>
+                    <Select onValueChange={field.onChange} value={field.value}>
+                      <FormControl>
+                        <SelectTrigger>
+                          <SelectValue placeholder="페이지를 선택하세요" />
+                        </SelectTrigger>
+                      </FormControl>
+                      <SelectContent>
+                        {pagePathOptions.map((option) => (
+                          <SelectItem key={option.value} value={option.value}>
+                            {option.label}
+                          </SelectItem>
+                        ))}
+                      </SelectContent>
+                    </Select>
+                    <FormMessage />
+                  </FormItem>
+                )}
+              />
+
+              <FormField
+                control={form.control}
+                name="isActive"
+                render={({ field }) => (
+                  <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
+                    <div className="space-y-0.5">
+                      <FormLabel className="text-base">활성 상태</FormLabel>
+                      <div className="text-sm text-muted-foreground">
+                        활성화하면 해당 페이지에서 공지사항이 표시됩니다.
+                      </div>
+                    </div>
+                    <FormControl>
+                      <Switch
+                        checked={field.value}
+                        onCheckedChange={field.onChange}
+                      />
+                    </FormControl>
+                  </FormItem>
+                )}
+              />
+            </div>
+
+            <FormField
+              control={form.control}
+              name="title"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>제목 *</FormLabel>
+                  <FormControl>
+                    <Input placeholder="공지사항 제목을 입력하세요" {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            <FormField
+              control={form.control}
+              name="content"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>내용 *</FormLabel>
+                  <FormControl>
+                    <div className="min-h-[400px]">
+                      <TiptapEditor
+                        content={field.value}
+                        setContent={field.onChange}
+                        disabled={isLoading}
+                        height="300px"
+                      />
+                    </div>
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            <div className="flex justify-end gap-2 pt-4">
+              <Button
+                type="button"
+                variant="outline"
+                onClick={() => onOpenChange(false)}
+                disabled={isLoading}
+              >
+                취소
+              </Button>
+              <Button type="submit" disabled={isLoading}>
+                {isLoading && <Loader className="mr-2 h-4 w-4 animate-spin" />}
+                생성
+              </Button>
+            </div>
+          </form>
+        </Form>
+      </DialogContent>
+    </Dialog>
+  )
+} 
\ No newline at end of file
-- 
cgit v1.2.3

