/* 상황판 서식 편집기 — 공유: 아이콘 · 샘플 서식(유지보수 용역) · 원자 컴포넌트 */ /* ---- 인라인 SVG 아이콘 (lucide 경로) — design_canvas 재렌더/포커스 복제에도 안전 ---- */ const BD_PATHS = { plus: ['M5 12h14', 'M12 5v14'], minus: ['M5 12h14'], type: ['M4 7V5h16v2', 'M9 19h6', 'M12 5v14'], pencil: ['M12 20h9', 'M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z'], lock: ['rect:3,11,18,11,2', 'M7 11V7a5 5 0 0 1 10 0v4'], unlock: ['rect:3,11,18,11,2', 'M7 11V7a5 5 0 0 1 9.9-1'], school: ['M14 22v-4a2 2 0 0 0-4 0v4', 'm18 10 3.447 1.724a1 1 0 0 1 .553.894V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-7.382a1 1 0 0 1 .553-.894L6 10', 'M18 5v17', 'm4 6 7.106-3.553a2 2 0 0 1 1.788 0L20 6', 'M6 5v17', 'circle:12,9,2'], shield: ['M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'], shieldcheck: ['M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z', 'm9 12 2 2 4-4'], grip: ['circle:9,5,1', 'circle:9,12,1', 'circle:9,19,1', 'circle:15,5,1', 'circle:15,12,1', 'circle:15,19,1'], griph: ['circle:5,9,1', 'circle:12,9,1', 'circle:19,9,1', 'circle:5,15,1', 'circle:12,15,1', 'circle:19,15,1'], trash: ['M3 6h18', 'M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2', 'M10 11v6', 'M14 11v6'], copy: ['rect:8,8,14,14,2', 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'], eye: ['M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0', 'circle:12,12,3'], table: ['rect:3,3,18,18,2', 'M3 9h18', 'M3 15h18', 'M12 3v18'], filetext: ['M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z', 'M14 2v5h5', 'M9 13h6', 'M9 17h4'], layoutgrid: ['rect:3,3,7,7,1', 'rect:14,3,7,7,1', 'rect:14,14,7,7,1', 'rect:3,14,7,7,1'], chevronright: ['m9 18 6-6-6-6'], chevrondown: ['m6 9 6 6 6-6'], check: ['M20 6 9 17l-5-5'], checkcircle: ['M21.8 10A10 10 0 1 1 12 2', 'm9 11 3 3L22 4'], x: ['M18 6 6 18', 'M6 6l12 12'], history: ['M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8', 'M3 3v5h5', 'M12 7v5l4 2'], gitbranch: ['line:6,3,6,15', 'circle:18,6,3', 'circle:6,18,3', 'M18 9a9 9 0 0 1-9 9'], send: ['M14.54 7.4 4.6 10.7c-1.4.46-1.4 2.44 0 2.9l3.86 1.29 1.29 3.86c.46 1.4 2.44 1.4 2.9 0l3.3-9.94a1.54 1.54 0 0 0-1.94-1.94Z'], rocket: ['M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z', 'm12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z', 'M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0', 'M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5'], arrowright: ['M5 12h14', 'm12 5 7 7-7 7'], info: ['circle:12,12,10', 'M12 16v-4', 'M12 8h.01'], wrench: ['M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z'], sliders: ['line:21,7,11,7', 'line:7,7,3,7', 'line:21,17,15,17', 'line:11,17,3,17', 'circle:9,7,2', 'circle:13,17,2'], columns: ['rect:3,3,18,18,2', 'M12 3v18'], list: ['line:8,6,21,6', 'line:8,12,21,12', 'line:8,18,21,18', 'line:3,6,3.01,6', 'line:3,12,3.01,12', 'line:3,18,3.01,18'], calendar: ['rect:3,4,18,18,2', 'M16 2v4', 'M8 2v4', 'M3 10h18'], building: ['rect:4,2,16,20,2', 'M9 22v-4h6v4', 'M9 6h.01', 'M15 6h.01', 'M9 10h.01', 'M15 10h.01', 'M9 14h.01', 'M15 14h.01'], won: ['M3 6l3.5 12L12 8l5.5 10L21 6', 'M3 11h18', 'M3 15h18'], image: ['rect:3,3,18,18,2', 'circle:9,9,2', 'm21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21'], cart: ['circle:8,21,1', 'circle:19,21,1', 'M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12'], circledot: ['circle:12,12,10', 'circle:12,12,1'], sparkles: ['m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3z'], clipboardcheck: ['rect:8,2,8,4,1', 'M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2', 'm9 14 2 2 4-4'], alert: ['m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3', 'M12 9v4', 'M12 17h.01'], layers: ['m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.84Z', 'm22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65', 'm22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65'], settings: ['M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z', 'circle:12,12,3'], text: ['M17 6.1H3', 'M21 12.1H3', 'M15.1 18H3'], squarepen: ['M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7', 'M18.4 2.6a2 2 0 0 1 3 3L12 15l-4 1 1-4Z'], package: ['M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z', 'M3.3 7 12 12l8.7-5', 'M12 22V12'], upload: ['M12 3v12', 'm17 8-5-5-5 5', 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'], download: ['M12 15V3', 'm7 10 5 5 5-5', 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'], clock: ['circle:12,12,10', 'M12 6v6l4 2'], bus: ['M8 6v6', 'M15 6v6', 'M2 12h19.6', 'M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3', 'circle:7,18,2', 'M9 18h5', 'circle:16,18,2'], users: ['M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2', 'circle:9,7,4', 'M22 21v-2a4 4 0 0 0-3-3.87', 'M16 3.13a4 4 0 0 1 0 7.75'], userplus: ['M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2', 'circle:9,7,4', 'line:19,8,19,14', 'line:22,11,16,11'], calendarcheck: ['M8 2v4', 'M16 2v4', 'rect:3,4,18,18,2', 'M3 10h18', 'm9 16 2 2 4-4'], hardhat: ['M2 18a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1z', 'M10 10V5a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v5', 'M4 15v-3a6 6 0 0 1 6-6', 'M14 6a6 6 0 0 1 6 6v3'], }; function BDIcon({ name, size = 18, sw = 1.75, fill = false }) { const parts = BD_PATHS[name] || []; return ( {parts.map((p, i) => { if (p.startsWith('rect:')) { const [x, y, w, h, r] = p.slice(5).split(',').map(Number); return ; } if (p.startsWith('circle:')) { const [cx, cy, r] = p.slice(7).split(',').map(Number); return ; } if (p.startsWith('line:')) { const [x1, y1, x2, y2] = p.slice(5).split(',').map(Number); return ; } return ; })} ); } window.BDIcon = BDIcon; /* ---- 권한 칩 (셀별: 학교 개방 / 세이프스쿨 전용) ---- */ function PermChip({ perm, toggle, onClick, size }) { const open = perm === 'school'; return ( ); } window.PermChip = PermChip; /* ---- 셀 유형 배지 (고정 안내 / 입력 필드) ---- */ function TypeBadge({ type }) { const fixed = type === 'fixed'; return ( {fixed ? '고정' : '입력'} ); } window.TypeBadge = TypeBadge; /* ============================================================ 샘플 서식 — 「유지보수 용역」 상황판 (관리자가 편집기로 제작 중인 v2) - 셀 유형: fixed(고정 안내) / input(입력 필드) - 권한(input 한정): school(학교 개방) / safe(세이프스쿨 전용) - isNew: v1 → v2 에서 추가/변경된 칸 (마이그레이션 하이라이트 대상) ============================================================ */ window.BD_TEMPLATE = { area: '유지보수 용역', areaIcon: 'wrench', desc: '교내 시설 수선·보수 용역 관리', version: 2, base: 1, blocks: [ { id: 'intro', kind: 'text', title: '상황판 안내', text: '이 상황판은 교내 시설 수선·보수 용역의 접수부터 완료까지를 한 곳에서 관리합니다. 칸에 「학교 입력」 표시가 있는 항목만 학교에서 직접 작성하실 수 있고, 나머지는 세이프스쿨이 채웁니다.', }, { id: 'basic', kind: 'fields', title: '용역 기본 정보', fields: [ { id: 'school', label: '학교명', type: 'fixed', perm: 'safe', value: '○○중학교', full: false }, { id: 'facility', label: '시설 구분', type: 'input', perm: 'school', ph: '예) 체육관·급식실', full: false }, { id: 'item', label: '보수 항목', type: 'input', perm: 'school', ph: '예) 천장 누수 보수', full: false }, { id: 'reqdate', label: '요청일', type: 'input', perm: 'school', ph: '2026.6.3', full: false }, { id: 'vendor', label: '담당 업체', type: 'input', perm: 'safe', ph: '세이프스쿨 배정', full: false }, { id: 'cost', label: '예상 비용', type: 'input', perm: 'safe', ph: '견적 후 입력', full: false, isNew: true }, { id: 'start', label: '착수 예정일', type: 'input', perm: 'safe', ph: '', full: false }, { id: 'done', label: '완료 예정일', type: 'input', perm: 'safe', ph: '', full: false }, ], }, { id: 'worktable', kind: 'table', title: '보수 내역', cols: [ { id: 'c1', label: '항목', perm: 'safe' }, { id: 'c2', label: '위치', perm: 'school' }, { id: 'c3', label: '진행 상태', perm: 'safe' }, { id: 'c4', label: '비용', perm: 'safe' }, ], rows: [ ['배관 누수 보수', '1층 급식실', '완료', '1,200,000'], ['창호 교체', '3층 3-2 교실', '진행중', '—'], ], }, { id: 'safety', kind: 'text', title: '안전점검 확인 안내', isNew: true, text: '보수 완료 후 안전점검 확인서를 첨부해 주세요. 점검 항목은 세이프스쿨 안전관리 표준안을 따릅니다.', }, ], }; /* v2 발행 변경 요약 (diff · 학교 알림에 공용) */ window.BD_DIFF = [ { kind: 'add', label: '‘예상 비용’ 입력 칸 추가', detail: '용역 기본 정보 블록 · 세이프스쿨 전용 · 기존 학교는 빈 칸으로 추가됩니다.' }, { kind: 'add', label: '‘안전점검 확인 안내’ 블록 추가', detail: '고정 안내 텍스트 · 모든 학교 공통으로 표시됩니다.' }, { kind: 'perm', label: '‘위치’ 열을 학교 입력으로 개방', detail: '보수 내역 표 · 세이프스쿨 전용 → 학교 입력 가능.' }, { kind: 'edit', label: '‘요청일’ 라벨·예시 정리', detail: '입력 값은 칸 ID로 그대로 유지됩니다.' }, ];