diff --git a/docker-compose.yml b/docker-compose.yml index 9e1c88c..94fcf98 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,7 @@ services: - "localhost:host-gateway" volumes: - uploads:/uploads + - ./web:/app/web depends_on: mssql: condition: service_healthy diff --git a/web/components/shared/ui-badge.mjs b/web/components/shared/ui-badge.mjs index c1e62e8..ff97206 100644 --- a/web/components/shared/ui-badge.mjs +++ b/web/components/shared/ui-badge.mjs @@ -4,48 +4,51 @@ const STATUS_LABELS = { }; const PRIORITY_LABELS = { low: 'Low', normal: 'Normal', high: 'High', urgent: 'Urgent' }; -class UiBadge extends HTMLElement { - connectedCallback() { this.#render(); } - static get observedAttributes() { return ['type', 'value']; } - attributeChangedCallback() { this.#render(); } +const CSS = ` + :host { display: inline-flex; } + .badge { + display: inline-flex; align-items: center; gap: .35rem; + padding: .2rem .6rem; border-radius: 999px; + font-size: .7rem; font-weight: 700; text-transform: uppercase; + letter-spacing: .04em; white-space: nowrap; + } + .dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; } + .s-draft { background:var(--status-draft-bg); color:var(--status-draft); } + .s-assigned { background:var(--status-assigned-bg); color:var(--status-assigned); } + .s-scheduled { background:var(--status-scheduled-bg); color:var(--status-scheduled); } + .s-in_progress { background:var(--status-in_progress-bg); color:var(--status-in_progress); } + .s-pending_review { background:var(--status-pending_review-bg); color:var(--status-pending_review); } + .s-closed { background:var(--status-closed-bg); color:var(--status-closed); } + .p-low { background:#F1F5F9; color:var(--priority-low); } + .p-normal { background:#E0F2FE; color:var(--priority-normal); } + .p-high { background:#FFF7ED; color:var(--priority-high); } + .p-urgent { background:#FEF2F2; color:var(--priority-urgent); } +`; - #render() { +class UiBadge extends HTMLElement { + static get observedAttributes() { return ['type', 'value']; } + + connectedCallback() { + if (!this.shadowRoot) { + this.attachShadow({ mode: 'open' }); + this.shadowRoot.innerHTML = ``; + } + this.#update(); + } + + attributeChangedCallback() { + if (this.shadowRoot) this.#update(); + } + + #update() { const type = this.getAttribute('type') || 'status'; const value = this.getAttribute('value') || ''; const label = type === 'priority' ? (PRIORITY_LABELS[value] || value) : (STATUS_LABELS[value] || value.replace('_', ' ')); - - this.attachShadow({ mode: 'open' }); - this.shadowRoot.innerHTML = ` - - - - ${label} - `; + const span = this.shadowRoot.querySelector('.badge'); + span.className = `badge ${type === 'priority' ? 'p' : 's'}-${value}`; + span.innerHTML = `${label}`; } } diff --git a/web/index.html b/web/index.html index 34e25cd..3784fd3 100644 --- a/web/index.html +++ b/web/index.html @@ -4,6 +4,7 @@ Work Orders + diff --git a/web/styles/global.css b/web/styles/global.css index cee0454..97723fb 100644 --- a/web/styles/global.css +++ b/web/styles/global.css @@ -166,15 +166,15 @@ app-root.collapsed { app-mobile-nav { display: none; } @media (max-width: 768px) { - app-root { + app-root, + app-root.collapsed { grid-template-columns: 1fr; - grid-template-rows: 56px 1fr 56px; + grid-template-rows: 56px 1fr; } - .app-shell { grid-template-rows: 1fr; } - app-sidebar { display: none; } + .app-shell { grid-template-rows: 56px 1fr; } + app-sidebar { display: none !important; } app-mobile-nav { display: flex; } - app-topbar { display: none; } - #main-content { padding: 1rem; } + #main-content { padding: 1rem; padding-bottom: calc(56px + 1rem); } } /* ── Sidebar (Light DOM) ──────────────────────────────────────────────────────── */