redesign: Layout2 design-system + dashboard/tasks rework + perf

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>
This commit is contained in:
Krao Hasanee
2026-06-26 10:08:40 -04:00
parent c5f020cf44
commit c91e292066
27 changed files with 879 additions and 548 deletions
+10 -10
View File
@@ -35,7 +35,7 @@ function invoiceTotal(items) {
function TaskStatCard({ label, value, sub, iconBg, iconColor, iconPath }) {
return (
<div style={{ background: 'var(--card-bg)', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', minHeight: 120 }}>
<div style={{ background: 'var(--card-bg)', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)', border: 'var(--card-border)', borderRadius: 8, padding: '18px 21px', minHeight: 120 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
<div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5 }}>{label}</div>
<div style={{ width: 27, height: 27, borderRadius: '50%', background: iconBg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
@@ -321,32 +321,32 @@ export default function MyInvoices() {
label="Completed New Tasks"
value={stats.completedNewTasks}
sub={`${stats.completedNewTasks} completed R00 units`}
iconBg="rgba(96,165,250,0.15)"
iconColor="#60a5fa"
iconBg="color-mix(in srgb, var(--info) 15%, transparent)"
iconColor="var(--info)"
iconPath={STAT_ICONS.newTasks}
/>
<TaskStatCard
label="Completed Revisions"
value={stats.completedRevisions}
sub={`${stats.completedRevisions} completed revision units`}
iconBg="rgba(245,165,35,0.15)"
iconColor="#F5A523"
iconBg="color-mix(in srgb, var(--accent) 15%, transparent)"
iconColor="var(--accent)"
iconPath={STAT_ICONS.revisions}
/>
<TaskStatCard
label="Invoiced"
value={fmt(totalInvoiceAmount)}
sub={`${invoices.length} invoices submitted`}
iconBg="rgba(167,139,250,0.15)"
iconColor="#a78bfa"
iconBg="color-mix(in srgb, var(--violet) 15%, transparent)"
iconColor="var(--violet)"
iconPath={STAT_ICONS.invoiced}
/>
<TaskStatCard
label="Paid"
value={fmt(paidInvoiceAmount)}
sub={`${invoices.filter((invoice) => invoice.status === 'paid').length} paid invoices`}
iconBg="rgba(74,222,128,0.15)"
iconColor="#4ade80"
iconBg="color-mix(in srgb, var(--positive) 15%, transparent)"
iconColor="var(--positive)"
iconPath={STAT_ICONS.paid}
/>
</div>
@@ -430,7 +430,7 @@ export default function MyInvoices() {
{showInvoiceForm && (
<div style={popupOverlayStyle} onClick={() => setShowInvoiceForm(false)}>
<div
style={{ ...popupSurfaceStyle, background: 'var(--card-bg)', width: '80vw', height: '80vh', display: 'flex', flexDirection: 'column', gap: 0 }}
style={{ ...popupSurfaceStyle, width: '80vw', height: '80vh', display: 'flex', flexDirection: 'column', gap: 0 }}
onClick={(e) => e.stopPropagation()}
>
<SubcontractorInvoiceForm