import { api } from '../../lib/api.mjs'; import { formatDateTime, formatDate } from '../../lib/format.mjs'; const TABS = ['Overview', 'Checklist', 'Resources', 'Photos', 'Accounting', 'Activity']; const STATUS_TRANSITIONS = { draft: ['assigned','scheduled'], assigned: ['scheduled','in_progress'], scheduled: ['in_progress'], in_progress: ['pending_review','closed'], pending_review: ['in_progress','closed'], closed: [], }; class WoDetail extends HTMLElement { #woId = null; #wo = null; #tab = 'Overview'; #loading = true; static get observedAttributes() { return ['wo-id']; } attributeChangedCallback(_, __, val) { this.#woId = val ? +val : null; if (this.shadowRoot) this.#load(); } connectedCallback() { this.attachShadow({ mode: 'open' }); if (this.#woId) this.#load(); } async #load() { this.#loading = true; this.#render(); try { this.#wo = await api.get(`/work-orders/${this.#woId}`); } catch { this.#wo = null; } this.#loading = false; this.#render(); } #render() { const s = this.shadowRoot; s.innerHTML = `${this.#html()}`; this.#bind(); if (window.lucide) lucide.createIcons({ nodes: [s] }); } #css() { return ` :host { display: block; } .page-header { display:flex; align-items:center; gap:1rem; margin-bottom:1.25rem; flex-wrap:wrap; } .back-btn { background:none; border:1px solid var(--border); color:var(--text); border-radius:var(--radius); padding:.4rem .75rem; font-size:.813rem; font-weight:500; cursor:pointer; display:flex; align-items:center; gap:.3rem; transition:background .15s; flex-shrink:0; } .back-btn:hover { background:var(--surface-2); } .header-info { flex:1; min-width:0; } .wo-number { font-family:monospace; font-size:.813rem; color:var(--text-muted); margin-bottom:.15rem; } h1 { font-size:1.2rem; font-weight:700; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .header-badges { display:flex; align-items:center; gap:.5rem; margin-top:.35rem; flex-wrap:wrap; } .header-actions { display:flex; gap:.5rem; flex-shrink:0; } .btn { display:inline-flex; align-items:center; gap:.35rem; padding:.45rem .9rem; border:none; border-radius:var(--radius); font-size:.813rem; font-weight:600; cursor:pointer; transition:opacity .15s,background .15s; white-space:nowrap; } .btn-primary { background:var(--teal); color:#fff; } .btn-primary:hover { opacity:.88; } .btn-ghost { background:transparent; border:1px solid var(--border); color:var(--text); } .btn-ghost:hover { background:var(--surface-2); } .meta-strip { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:.9rem 1.25rem; margin-bottom:1rem; display:flex; gap:2rem; flex-wrap:wrap; box-shadow:var(--shadow-sm); } .meta-item { display:flex; flex-direction:column; gap:.15rem; } .meta-label { font-size:.7rem; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.06em; } .meta-value { font-size:.875rem; color:var(--text); font-weight:500; } .tab-bar { display:flex; gap:0; border-bottom:2px solid var(--border); margin-bottom:1rem; overflow-x:auto; } .tab { padding:.65rem 1rem; font-size:.875rem; font-weight:500; color:var(--text-muted); border:none; background:none; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-2px; white-space:nowrap; transition:color .15s,border-color .15s; } .tab.active { color:var(--teal); border-bottom-color:var(--teal); font-weight:600; } .tab:hover:not(.active) { color:var(--text); } .tab-content { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:1.25rem; box-shadow:var(--shadow-sm); } .detail-grid { display:grid; grid-template-columns:1fr 1fr; gap:1.25rem; } .detail-field { display:flex; flex-direction:column; gap:.25rem; } .field-label { font-size:.7rem; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.06em; } .field-value { font-size:.875rem; color:var(--text); line-height:1.5; } .field-value.empty { color:var(--text-muted); font-style:italic; } .text-block { background:var(--surface-2); border-radius:var(--radius-sm); padding:.75rem 1rem; font-size:.875rem; line-height:1.6; color:var(--text); white-space:pre-wrap; } .phase-badge { display:inline-flex; align-items:center; gap:.3rem; padding:.2rem .6rem; border-radius:999px; font-size:.7rem; font-weight:700; background:var(--surface-2); color:var(--text-muted); } .status-menu { position:relative; } .status-dropdown { position:absolute; top:calc(100% + .25rem); right:0; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow-md); z-index:50; min-width:160px; overflow:hidden; } .status-opt { display:flex; align-items:center; gap:.5rem; padding:.6rem 1rem; font-size:.875rem; cursor:pointer; border:none; background:none; width:100%; text-align:left; transition:background .15s; color:var(--text); } .status-opt:hover { background:var(--surface-2); } .status-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; } .placeholder { text-align:center; padding:3rem; color:var(--text-muted); } .placeholder i { margin-bottom:.75rem; } @media (max-width:768px) { .detail-grid { grid-template-columns:1fr; } .meta-strip { gap:1rem; } } `; } #html() { if (this.#loading) return `
${this.#tab} — Coming in Phase 2
This section will be available in the next phase of development.