Lint went from 84 problems to 0. Build passes.
Dead code:
- TeamInvoices: drop the orphaned Subcontractor PO block (updateSubcontractorPO
plus send/ready-to-pay/paid/reopen/cancel/delete/download/CPA-export handlers
and ~25 derived vars). That feature moved to the routed
TeamCreateSubcontractorPO / TeamSubcontractorPODetail pages in the Layout2
redesign; these were leftovers. 2100 -> 1880 lines.
- Tasks: drop unrendered project sort/tab/completion logic in TasksPageShell.
- Remove 59 unused vars, imports, and handlers across 12 other files.
Removed wasted queries:
- TeamInvoices ran a nested subcontractor_payments join (profiles, projects,
companies, PO items, tasks) on every page load into state nothing read.
- TeamInvoices and ExternalMyInvoices each fetched a task-type map on invoice
open and discarded it; the ExternalMyInvoices one blocked the detail popup.
- RequestForm queried sign_families on mount into unread state.
Dependencies:
- Drop heic2any (zero imports). heic-to is the one in use and already lazy-loads.
Effects and exports:
- RequestForm: remove 4 effects. Sign-row sizing and company-change resets move
into their change handlers; single-company selection is derived during render
rather than written back into form state.
- FilterDropdown: measure position on click instead of in an effect, which also
removes a one-frame stale-position flicker.
- BrandBook: latest-ref pattern so the 900ms address debounce is not reset by
handler identity.
- ClientMyInvoices: hoist MONTHS to module scope.
- Split non-component exports: POPUP_FIELD_LABEL moves to lib/popupStyles.js;
resolveProfileAvatar and useLiveClock are internal-only; getGreeting deleted
as nothing referenced it.
Companies.jsx keeps one scoped eslint-disable with a reason: load() only
setStates after awaiting its queries, so set-state-in-effect is a false positive
there, and load() is shared with the create/delete handlers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clicking the dimmed area outside a modal (+Task, +Invoice, expense,
review, etc.) accidentally dismissed it and lost in-progress input.
Every popup already has an explicit Cancel/Close/✕ button, so the
backdrop click handler is removed; also drops the now-dead
onClose/blockClose prop plumbing that only existed to support it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Design system (Layout2):
- Solid token-driven theme (no animated grid); single-source tokens for bg,
cards (bg/border/radius), popups, fonts (Inter), and full semantic +
data-viz color palette. Swept ~168 hardcoded colors to tokens.
Dashboard:
- Reflow: To Do + Calendar row (fixed right rail) over Activity / In-Progress /
Team Performance; CSS height-match (To Do = Calendar); responsive stacking.
- 'Tasks Not Started' -> 'To Do' card with R#/Assigned columns; compact money fmt.
Tasks page:
- Combined tabs into Tasks + Completed with a Status column.
- Column-header sort + filter (Status, R#/new-vs-revision, Project, Task Type,
Company) via portaled, scrollable FilterDropdown; removed toolbar filters and
the projects side panel; headers stay visible when empty; renamed to 'Tasks'.
Perf:
- FK/filter index migration; removed redundant client/external scope waterfall
(rely on RLS); parallel follow-up queries.
Mobile:
- Responsive grids; mobile topbar = hamburger only, blends with bg, proper offset.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace SubcontractorInvoiceDetailView (card-based) with flat layout
matching the original sub-invoice popup: meta strip + raw table + notes.
- InvoiceDetailPopup: add metaContent/metaActions/metaCols props + export POPUP_FIELD_LABEL
- New InvoicePopupTable: flat sortable 5-col table, no card wrapper
- All 4 popups (client, team invoice, team sub-invoice, external): use
flat meta strip (4-col grid, borderBottom) and InvoicePopupTable
- Sub-invoice + external: Submitted | Paid/Created | Items | Total
- Client invoice: Date | Due | Status | Total
- Team invoice: Date | Due | Company | Email | Total (+ stripe if paid)
with Edit Dates button in metaActions slot
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>