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 += `| ${esc(h)} | `; });
+ html += '
';
+ }
+ html += '';
+ if (rows.length > 0) {
+ rows.forEach(row => {
+ html += '';
+ (row || []).forEach(cell => { html += `| ${esc(cell || '')} | `; });
+ html += '
';
+ });
+ } else {
+ const colCount = headers.length || 3;
+ html += '';
+ for (let i = 0; i < colCount; i++) html += '| (입력) | ';
+ html += '
';
+ }
+ html += '
';
+ 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 = `';
+ 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 || '';