import { sanitizeHtml } from '@common/utils/sanitize'; import type { OilSpillReportData } from './OilSpillReportTemplate'; // ─── Report Export Helpers ────────────────────────────── export function generateReportHTML( templateLabel: string, meta: { writeTime: string; author: string; jurisdiction: string }, sections: { title: string; fields: { key: string; label: string }[] }[], getVal: (key: string) => string ) { const rows = sections.map(section => { const fieldRows = section.fields.map(f => { if (f.label) { return `${f.label}${getVal(f.key) || '-'}` } return `${getVal(f.key) || '-'}` }).join('') return `

${section.title}

${fieldRows}
` }).join('') return `${templateLabel}

해양오염방제지원시스템

${templateLabel}

작성일시: ${meta.writeTime} | 작성자: ${meta.author || '-'} | 관할: ${meta.jurisdiction}

${rows}` } // eslint-disable-next-line @typescript-eslint/no-unused-vars export function exportAsPDF(html: string, _filename: string) { const sanitizedHtml = sanitizeHtml(html) const blob = new Blob([sanitizedHtml], { type: 'text/html; charset=utf-8' }) const url = URL.createObjectURL(blob) const win = window.open(url, '_blank') if (win) { win.addEventListener('afterprint', () => URL.revokeObjectURL(url)) setTimeout(() => win.print(), 500) } setTimeout(() => URL.revokeObjectURL(url), 30000) } export async function exportAsHWP( templateLabel: string, meta: { writeTime: string; author: string; jurisdiction: string }, sections: { title: string; fields: { key: string; label: string }[] }[], getVal: (key: string) => string, filename: string, ) { const { exportAsHWPX } = await import('./hwpxExport'); await exportAsHWPX(templateLabel, meta, sections, getVal, filename); } export type ViewState = | { screen: 'list' } | { screen: 'templates' } | { screen: 'generate' } | { screen: 'view'; data: OilSpillReportData } | { screen: 'edit'; data: OilSpillReportData } export const typeColors: Record = { '초기보고서': { bg: 'rgba(6,182,212,0.15)', text: '#06b6d4' }, '지휘부 보고': { bg: 'rgba(168,85,247,0.15)', text: '#a855f7' }, '예측보고서': { bg: 'rgba(59,130,246,0.15)', text: '#3b82f6' }, '종합보고서': { bg: 'rgba(249,115,22,0.15)', text: '#f97316' }, '유출유 보고': { bg: 'rgba(234,179,8,0.15)', text: '#eab308' }, } export const statusColors: Record = { '완료': { bg: 'rgba(34,197,94,0.15)', text: '#22c55e' }, '수행중': { bg: 'rgba(249,115,22,0.15)', text: '#f97316' }, '테스트': { bg: 'rgba(138,150,168,0.15)', text: '#8a96a8' }, } export const analysisCatColors: Record = { '유출유 확산예측': { bg: 'rgba(6,182,212,0.12)', text: '#06b6d4', icon: '🛢' }, 'HNS 대기확산': { bg: 'rgba(249,115,22,0.12)', text: '#f97316', icon: '🧪' }, '긴급구난': { bg: 'rgba(239,68,68,0.12)', text: '#ef4444', icon: '🚨' }, } export function inferAnalysisCategory(report: OilSpillReportData): string { if (report.analysisCategory) return report.analysisCategory const t = (report.title || '').toLowerCase() const rt = report.reportType || '' if (t.includes('hns') || t.includes('대기확산') || t.includes('화학') || t.includes('aloha')) return 'HNS 대기확산' if (t.includes('구난') || t.includes('구조') || t.includes('긴급') || t.includes('salvage') || t.includes('rescue')) return '긴급구난' if (t.includes('유출유') || t.includes('확산예측') || t.includes('민감자원') || t.includes('유출사고') || t.includes('오염') || t.includes('방제') || rt === '유출유 보고' || rt === '예측보고서') return '유출유 확산예측' return '' }