diff --git a/resources/views/document-templates/index.blade.php b/resources/views/document-templates/index.blade.php index 5f5e00fd..edb2b8d1 100644 --- a/resources/views/document-templates/index.blade.php +++ b/resources/views/document-templates/index.blade.php @@ -268,7 +268,12 @@ function handleTrashedFilter() { .then(response => response.json()) .then(data => { if (data.success) { - content.innerHTML = buildDocumentPreviewHtml(data.data); + // builder_type에 따라 적절한 렌더러 사용 + if (data.data.builder_type === 'block') { + content.innerHTML = buildBlockPreviewHtml(data.data); + } else { + content.innerHTML = buildDocumentPreviewHtml(data.data); + } } else { content.innerHTML = '

미리보기를 불러올 수 없습니다.

'; } diff --git a/resources/views/document-templates/partials/preview-modal.blade.php b/resources/views/document-templates/partials/preview-modal.blade.php index 2c4ccb8f..03a0cffa 100644 --- a/resources/views/document-templates/partials/preview-modal.blade.php +++ b/resources/views/document-templates/partials/preview-modal.blade.php @@ -122,6 +122,155 @@ function _previewFormatFrequency(item) { * @param {Array} data.columns - 테이블 컬럼 * @param {Function} [data.methodResolver] - 검사방법 코드→이름 변환 함수 (선택) */ + /** + * 블록 기반(양식 디자이너) 미리보기 HTML 생성 + * + * @param {Object} data - 템플릿 데이터 (builder_type === 'block') + * @param {Object} data.schema - 블록 스키마 { version, page, blocks[] } + */ + function buildBlockPreviewHtml(data) { + const schema = data.schema; + if (!schema || !schema.blocks || schema.blocks.length === 0) { + return '
블록이 없습니다. 양식 디자이너에서 블록을 추가하세요.
'; + } + + const page = schema.page || {}; + const orientation = page.orientation || 'portrait'; + const blocks = schema.blocks; + + function esc(text) { + if (!text) return ''; + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + function nl2br(text) { + return (text || '').replace(/\n/g, '
'); + } + + function renderBlock(block) { + const type = block.type || ''; + const props = block.props || {}; + + switch (type) { + case 'heading': { + const level = Math.min(Math.max(parseInt(props.level || 2), 1), 6); + const text = esc(props.text || ''); + const align = props.align || 'left'; + const sizes = {1:'1.5em',2:'1.25em',3:'1.1em',4:'1em',5:'0.9em',6:'0.85em'}; + return `${text}`; + } + case 'paragraph': { + const text = nl2br(esc(props.text || '')); + const align = props.align || 'left'; + return `

${text}

`; + } + case 'table': { + const headers = props.headers || []; + const rows = props.rows || []; + const showHeader = props.showHeader !== false; + let html = ''; + if (showHeader && headers.length > 0) { + html += ''; + headers.forEach(h => { html += ``; }); + html += ''; + } + html += ''; + if (rows.length > 0) { + rows.forEach(row => { + html += ''; + (row || []).forEach(cell => { html += ``; }); + html += ''; + }); + } else { + const colCount = headers.length || 3; + html += ''; + for (let i = 0; i < colCount; i++) html += ''; + html += ''; + } + html += '
${esc(h)}
${esc(cell || '')}
(입력)
'; + return html; + } + case 'columns': { + const count = parseInt(props.count || 2); + const children = props.children || []; + let html = '
'; + for (let i = 0; i < count; i++) { + html += '
'; + const colChildren = children[i] || []; + colChildren.forEach(child => { html += renderBlock(child); }); + html += '
'; + } + html += '
'; + return html; + } + case 'divider': { + const style = (props.style || 'solid') === 'dashed' ? 'dashed' : 'solid'; + return `
`; + } + case 'spacer': { + const height = Math.max(parseInt(props.height || 20), 0); + return `
`; + } + case 'text_field': { + const label = esc(props.label || ''); + const req = props.required ? ' *' : ''; + return `
(입력)
`; + } + case 'number_field': { + const label = esc(props.label || ''); + const unit = props.unit ? ` (${esc(props.unit)})` : ''; + return `
(숫자)
`; + } + case 'date_field': { + const label = esc(props.label || ''); + return `
(날짜)
`; + } + case 'select_field': { + const label = esc(props.label || ''); + const options = (props.options || []).map(o => esc(o)).join(' / '); + return `
${options || '(선택)'}
`; + } + case 'checkbox_field': { + const label = esc(props.label || ''); + const options = props.options || []; + let html = `
`; + options.forEach(opt => { html += ``; }); + html += '
'; + return html; + } + case 'textarea_field': { + const label = esc(props.label || ''); + const rows = Math.max(parseInt(props.rows || 3), 1); + const height = rows * 24; + return `
(장문 입력)
`; + } + case 'signature_field': { + const label = esc(props.label || '서명'); + return `
서명 영역
`; + } + default: + return `
[ ${esc(type)} 블록 ]
`; + } + } + + let html = `
`; + blocks.forEach(block => { html += renderBlock(block); }); + html += '
'; + + return ` +
+
+ 양식 디자이너 + ${esc(data.name || '')} + ${blocks.length}개 블록 +
+
${html}
+
+ `; + } + function buildDocumentPreviewHtml(data) { const title = data.title || '문서 양식'; const companyName = data.company_name || '';