import { useState } from 'react'; import { createEmptyReport, type ReportType, type Jurisdiction } from './OilSpillReportTemplate'; import { useAuthStore } from '@common/store/authStore'; import { templateTypes } from './reportTypes'; import { generateReportHTML, exportAsPDF, exportAsHWP } from './reportUtils'; import { saveReport } from '../services/reportsApi'; interface TemplateFormEditorProps { onSave: () => void; onBack: () => void; } function TemplateFormEditor({ onSave, onBack }: TemplateFormEditorProps) { const user = useAuthStore((s) => s.user); const [selectedType, setSelectedType] = useState('초기보고서'); const [formData, setFormData] = useState>({}); const [reportMeta, setReportMeta] = useState(() => { const now = new Date(); return { title: '', author: '', jurisdiction: (user?.org?.abbr || '') as Jurisdiction, writeTime: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`, }; }); const [autoSave, setAutoSave] = useState(false); const [showPreview, setShowPreview] = useState(false); const template = templateTypes.find((t) => t.id === selectedType)!; const getVal = (key: string) => { if (key === 'author') return reportMeta.author; if (key === 'incident.writeTime') return reportMeta.writeTime; return formData[key] || ''; }; const setVal = (key: string, val: string) => { if (key === 'author') { setReportMeta((p) => ({ ...p, author: val })); return; } if (key === 'incident.writeTime') { setReportMeta((p) => ({ ...p, writeTime: val })); return; } setFormData((p) => ({ ...p, [key]: val })); }; const handleSave = async () => { const report = createEmptyReport(reportMeta.jurisdiction); report.reportType = selectedType; report.author = reportMeta.author; report.title = formData['incident.name'] || `${selectedType} ${reportMeta.writeTime}`; report.status = '완료'; report.incident.writeTime = reportMeta.writeTime; // Map all incident fields const incFields = [ 'name', 'occurTime', 'location', 'shipName', 'accidentType', 'pollutant', 'spillAmount', 'lat', 'lon', 'depth', 'seabed', ] as const; incFields.forEach((f) => { const val = formData[`incident.${f}`]; // eslint-disable-next-line @typescript-eslint/no-explicit-any if (val) (report.incident as any)[f] = val; }); report.analysis = formData['spreadAnalysis'] || formData['initialResponse'] || formData['responseStatus'] || formData['responseDetail'] || ''; try { await saveReport(report); onSave(); } catch (err) { console.error('[reports] 저장 오류:', err); alert('보고서 저장 중 오류가 발생했습니다.'); } }; const doExport = (format: 'pdf' | 'hwp') => { const meta = { writeTime: reportMeta.writeTime, author: reportMeta.author, jurisdiction: reportMeta.jurisdiction, }; const filename = formData['incident.name'] || `${template.label}_${reportMeta.writeTime.replace(/[\s:]/g, '_')}`; if (format === 'pdf') { const html = generateReportHTML(template.label, meta, template.sections, getVal); exportAsPDF(html, filename); } else { exportAsHWP(template.label, meta, template.sections, getVal, filename); } }; return (
{/* Left Sidebar - Template Selection */}

표준보고서 템플릿 선택

템플릿을 선택하면 오른쪽에 작성 양식이 표시됩니다.

{templateTypes.map((t) => ( ))}
{/* Right - Form */}
{/* Form Header */}
{template.icon} {template.label} 작성중
자동저장: {autoSave ? 'ON' : 'OFF'}
{/* Form Content */}
{template.sections.map((section, sIdx) => (

{section.title}

{section.fields.map((field, fIdx) => ( {field.label ? ( <> ) : (
{field.label} {field.type === 'text' && ( setVal(field.key, e.target.value)} placeholder={`${field.label} 입력`} className="w-full bg-transparent text-label-1 text-fg font-korean outline-none placeholder-fg-disabled" /> )} {field.type === 'checkbox-group' && field.options && (
{field.options.map((opt) => ( ))}
)}