'use client' import { useState, useTransition } from 'react' import { useRouter } from 'next/navigation' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useToast } from '@/hooks/use-toast' import { Save, RefreshCw } from 'lucide-react' import { BiddingNoticeTemplate } from '@/db/schema/bidding' import { saveBiddingNoticeTemplate, saveBiddingNotice } from './service' import TiptapEditor from '@/components/qna/tiptap-editor' interface BiddingNoticeEditorProps { initialData: BiddingNoticeTemplate | null biddingId?: number // 입찰 ID (있으면 일반 입찰공고, 없으면 템플릿) templateType?: string // 템플릿 타입 (템플릿 저장 시 사용) onSaveSuccess?: () => void // 저장 성공 시 콜백 onTemplateUpdate?: (template: BiddingNoticeTemplate) => void // 템플릿 업데이트 콜백 } export function BiddingNoticeEditor({ initialData, biddingId, templateType, onSaveSuccess, onTemplateUpdate }: BiddingNoticeEditorProps) { const getDefaultTitle = (type?: string) => { switch (type) { case 'facility': return '시설재 입찰공고문' case 'unit_price': return '단가계약 입찰공고문' default: return '표준 입찰공고문' } } const [title, setTitle] = useState(initialData?.title || getDefaultTitle(templateType)) const [content, setContent] = useState(initialData?.content || getDefaultTemplate()) const [isPending, startTransition] = useTransition() const { toast } = useToast() const router = useRouter() const handleSave = () => { if (!title.trim()) { toast({ title: '오류', description: '제목을 입력해주세요.', variant: 'destructive', }) return } if (!content.trim()) { toast({ title: '오류', description: '내용을 입력해주세요.', variant: 'destructive', }) return } startTransition(async () => { try { if (biddingId) { // 일반 입찰공고 저장 await saveBiddingNotice(biddingId, { title, content }) toast({ title: '성공', description: '입찰공고문이 저장되었습니다.', }) } else { // 템플릿 저장 if (!templateType) { toast({ title: '오류', description: '템플릿 타입이 지정되지 않았습니다.', variant: 'destructive', }) return } const savedTemplate = await saveBiddingNoticeTemplate({ title, content, type: templateType }) toast({ title: '성공', description: '입찰공고문 템플릿이 저장되었습니다.', }) // 템플릿 업데이트 콜백 호출 if (onTemplateUpdate && savedTemplate) { // 저장된 템플릿 데이터를 가져와서 콜백 호출 const updatedTemplate = { ...initialData, title, content, type: templateType, updatedAt: new Date(), } as BiddingNoticeTemplate onTemplateUpdate(updatedTemplate) } } router.refresh() // 저장 성공 시 콜백 호출 onSaveSuccess?.() } catch (error) { toast({ title: '오류', description: error instanceof Error ? error.message : '저장에 실패했습니다.', variant: 'destructive', }) } }) } // const handleReset = () => { // if (confirm('기본 템플릿으로 초기화하시겠습니까? 현재 내용은 삭제됩니다.')) { // setTitle(getDefaultTitle(templateType)) // setContent(getDefaultTemplate()) // toast({ // title: '초기화 완료', // description: '기본 템플릿으로 초기화되었습니다.', // }) // } // } return (
| 구분 | 일시 | 장소 |
|---|---|---|
| 입찰 공고 | [YYYY.MM.DD] | - |
| 현장설명 | [YYYY.MM.DD HH:MM] | [현장 주소] |
| 입찰서 접수 | [YYYY.MM.DD HH:MM까지] | [접수 장소] |
| 개찰 | [YYYY.MM.DD HH:MM] | [개찰 장소] |
`.trim() }문의처:
담당자: [담당자명]
전화: [전화번호]
이메일: [이메일주소]