"use client" import * as React from "react" import { useState } from "react" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { useParams } from "next/navigation" import { useTranslation } from "@/i18n/client" import { toast } from "sonner" import { Loader, Check, ChevronsUpDown } 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 { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from "@/components/ui/command" import { cn } from "@/lib/utils" 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 params = useParams() const lng = (params?.lng as string) || 'ko' const { t } = useTranslation(lng, 'menu') // 안전한 번역 함수 (키가 없을 때 원본 키 반환) const safeTranslate = (key: string): string => { try { const translated = t(key) // 번역 키가 그대로 반환되는 경우 원본 키 사용 if (translated === key) { return key } return translated || key } catch (error) { console.warn(`Translation failed for key: ${key}`, error) return key } } const [isLoading, setIsLoading] = useState(false) const form = useForm({ 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 ( 새 공지사항 작성
{ const [open, setOpen] = useState(false) const [searchTerm, setSearchTerm] = useState("") const filteredOptions = React.useMemo(() => { if (!searchTerm.trim()) return pagePathOptions const lowerSearch = searchTerm.toLowerCase() return pagePathOptions.filter( (option) => safeTranslate(option.label).toLowerCase().includes(lowerSearch) || option.value.toLowerCase().includes(lowerSearch) ) }, [pagePathOptions, searchTerm]) const selectedOption = pagePathOptions.find(option => option.value === field.value) return ( 페이지 경로 * 검색 결과가 없습니다 {filteredOptions.map((option) => ( { field.onChange(option.value) setOpen(false) }} > {safeTranslate(option.label)} - {option.value} ))} ) }} /> (
활성 상태
활성화하면 해당 페이지에서 공지사항이 표시됩니다.
)} />
( 제목 * )} /> ( 내용 *
)} />
) }