/* ============================================================================= * B09_Estimation_UI_Shell.ts * 로그인 후 09: 6차 워크플로우 (원가계산) — 화면 **틀** (PLAN 12장 · 2026-09-14 브레인 판정) * * - 틀은 탭 줄과 등록만. 탭마다 파일 하나(`B09_Estimation_UI_Tab_<이름>.ts`) — 계약은 `_Shell_Types`. * - ⚠ 등록 권한 = 랩탑_서브. 다른 창은 탭 파일을 만들고 이름을 알려 등록을 부탁함. * - 탭을 고를 때마다 본문·좌측 칸을 비우고 `render(ctx, arg)`. `ctx.open(key, arg)` = 다른 탭으로 들어가기. * ========================================================================== */ import { createWorkflowLayout } from "@ui/ui_template_workflow_layout"; import { CURRENT_PROJECT_ID_KEY } from "@config/config_frontend"; import { workflowSteps } from "../A00_Common/b_page_scaffold"; import { goToWorkflowStage, WORKFLOW_STEP_ROUTES } from "../A00_Common/b_workflow_nav"; import type { B09Tab, B09TabContext } from "./B09_Estimation_UI_Shell_Types"; import { L, el, injectSheetStyles } from "./B09_Estimation_UI_Sheet"; import { costSheetTab } from "./B09_Estimation_UI_Tab_CostSheet"; import { rateTableTab } from "./B09_Estimation_UI_Tab_RateTable"; import { billTab } from "./B09_Estimation_UI_Tab_Bill"; import { unitPriceTab } from "./B09_Estimation_UI_Tab_UnitPrice"; import { priceBasisTab } from "./B09_Estimation_UI_Tab_PriceBasis"; import { machineTab } from "./B09_Estimation_UI_Tab_Machine"; import { priceCompareTab } from "./B09_Estimation_UI_Tab_PriceCompare"; import { summaryTab } from "./B09_Estimation_UI_Tab_Summary"; import { listsTab } from "./B09_Estimation_UI_Tab_Lists"; import { designDocTab } from "./B09_Estimation_UI_Tab_DesignDoc"; import { basisSheetTab } from "./B09_Estimation_UI_Tab_BasisSheet"; import { supplyTab } from "./B09_Estimation_UI_Tab_Supply"; import { baseDataTab } from "./B09_Estimation_UI_Tab_BaseData"; import { contractTab } from "./B09_Estimation_UI_Tab_Contract"; import { executionTab } from "./B09_Estimation_UI_Tab_Execution"; import { progressTab } from "./B09_Estimation_UI_Tab_Progress"; import { completionTab } from "./B09_Estimation_UI_Tab_Completion"; /** 탭 등록 — 한 줄에 탭 하나. */ const TABS: B09Tab[] = [ costSheetTab, // 랩탑_메인 rateTableTab, // 랩탑_메인 billTab, unitPriceTab, priceBasisTab, machineTab, priceCompareTab, summaryTab, listsTab, supplyTab, baseDataTab, designDocTab, basisSheetTab, contractTab, // 랩탑_메인 — 설계 뒤 계약 단계라 맨 끝 executionTab, // 랩탑_메인 — 계약 뒤 실행 단계 progressTab, // 랩탑_메인 — 실행 뒤 기성 단계 completionTab, // 랩탑_메인 — 기성 뒤 준공 단계 ]; export async function renderB09Estimation(root: HTMLElement): Promise { injectSheetStyles(); const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY); const page = el("div", "b09s-page"); const bar = el("div", "b09s-tabs"); const body = el("div", "b09s-body"); const panel = el("div"); page.append(bar, body); let active = TABS[0].key; const open = (key: string, arg?: string): void => { const tab = TABS.find((item) => item.key === key); if (!tab) return; active = key; drawBar(); body.replaceChildren(); panel.replaceChildren(); const ctx: B09TabContext = { projectId, body, panel, root, open }; tab.render(ctx, arg); }; const drawBar = (): void => { bar.replaceChildren( ...TABS.map((tab) => { const button = el( "button", `b09s-tab${tab.key === active ? " is-active" : ""}`, tab.label(), ); button.type = "button"; button.dataset.tab = tab.key; button.addEventListener("click", () => open(tab.key)); return button; }), ); }; const layout = createWorkflowLayout({ title: L("B09_Estimation_Title"), steps: workflowSteps(), activeStep: 6, leftPanel: panel, mainContent: page, routes: WORKFLOW_STEP_ROUTES, onStepClick: (stepIndex) => { if (projectId) goToWorkflowStage(projectId, WORKFLOW_STEP_ROUTES[stepIndex]); }, }); root.append(layout.root); open(active); }