diff --git a/frontend/index.html b/frontend/index.html index 1dedc41..0141da7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ - + Pulse diff --git a/frontend/src/components/insights/InsightsFilters.tsx b/frontend/src/components/insights/InsightsFilters.tsx index 8fa3ea8..54296b8 100644 --- a/frontend/src/components/insights/InsightsFilters.tsx +++ b/frontend/src/components/insights/InsightsFilters.tsx @@ -99,9 +99,9 @@ export function InsightsFiltersBar({ const hasActiveFilters = selectedDepts.length > 0 || selectedBranches.length > 0 || filters.employee; return ( -
+
{/* Date range presets */} -
+
{PRESETS.map(({ id, label }) => ( - + Name - Role - Branch + Role + Branch Own Team Combined @@ -239,8 +239,8 @@ export function Insights() { onClick={() => navigate(`/operations/${row.userId}`)} > {row.user?.name} - {row.user?.role ?? '—'} - {row.user?.branch ?? '—'} + {row.user?.role ?? '—'} + {row.user?.branch ?? '—'} {Math.round((row.own_score ?? 0) * 100)}% {Math.round((row.team_score ?? 0) * 100)}% {Math.round((row.combined_score ?? 0) * 100)}% @@ -303,7 +303,7 @@ export function Insights() { -
+
Dept Avg @@ -513,8 +513,8 @@ export function Insights() { Item - Template - Department + Template + Department Misses @@ -522,8 +522,8 @@ export function Insights() { {mostMissed.map((m) => ( {m.checklist_item} - {m.template_title} - {m.department} + {m.template_title} + {m.department} {m.misses} ))} diff --git a/frontend/src/pages/MyTasks.tsx b/frontend/src/pages/MyTasks.tsx index e2d6c8e..fc1db02 100644 --- a/frontend/src/pages/MyTasks.tsx +++ b/frontend/src/pages/MyTasks.tsx @@ -35,7 +35,7 @@ export function MyTasks() { return (
-

My Tasks

+

My Tasks

Manage your active operations and standard operating procedures.

@@ -188,8 +188,8 @@ function ChecklistRunner({ return ( - -
+ +
@@ -219,12 +219,12 @@ function ChecklistRunner({
-
-
+
+
{details.items.map((item) => (
{!isReadOnly && ( -
+
diff --git a/frontend/src/pages/Operations.tsx b/frontend/src/pages/Operations.tsx index 7b81183..5ab1db8 100644 --- a/frontend/src/pages/Operations.tsx +++ b/frontend/src/pages/Operations.tsx @@ -55,7 +55,7 @@ export function Operations() {
-

Operations Overview

+

Operations Overview

Hierarchical roll-up of organizational execution.

@@ -91,17 +91,15 @@ export function Operations() { Organization Health ({periodType})
-
Select a row to drill down
+
Select a row to drill down
-
-
+
navigate(`/operations/${u.id}`)} /> -
) : null} @@ -132,26 +130,26 @@ function OperationNode({ else scoreColor = 'text-rose-400 bg-rose-400/10 border-rose-400/20'; return ( -
+
onUserClick(node.user)} > {level > 0 && (
)} {level > 0 && (
)}
{ if (hasChildren) { e.stopPropagation(); @@ -160,18 +158,18 @@ function OperationNode({ }} > {hasChildren ? ( - isExpanded ? : + isExpanded ? : ) : (
)}
- + {node.user.name?.charAt(0) ?? '?'} -
+
{node.user.name} @@ -179,15 +177,15 @@ function OperationNode({ {node.user.role} {node.user.branch ? `• ${node.user.branch}` : ''}
-
-
+
+
Own Score {Math.round(ownScore * 100)}%
-
-
- Combined KPI -
+
+
+ Combined KPI +
{node.children!.map((child) => (
-

Team

+

Team

{showAllTeamsTab ? 'Your direct reports and organization-wide team view.' : 'Operational performance for your direct reports.'}

-
+
{showAllTeamsTab && (
) : ( -
+ {/* Mobile card view */} +
+ {teamScores.map((member) => ( +
navigate(`/operations/${member.employee}`)} + > +
+
+ {member.user?.name?.charAt(0) ?? '?'} +
+
+ + {member.user?.name ?? member.employee} + + + {member.user?.role ?? '—'} • {member.completed_items}/{member.total_items} items + +
+
+ {member.combined_score < 0.5 && } + {member.combined_score >= 0.8 && } + +
+
+
+
+ Own + +
+
+ Team + +
+
+
+ ))} +
+ {/* Desktop table view */} +
@@ -230,7 +270,50 @@ export function Team() {

No employees in scope for this period.

) : ( -
+ {/* Mobile card view */} +
+ {allTeamScores.map((member) => ( +
navigate(`/operations/${member.employee}`)} + > +
+
+ {member.user?.name?.charAt(0) ?? '?'} +
+
+ + {member.user?.name ?? member.employee} + + + {member.user?.role ?? '—'} • {member.department ?? '—'} + +
+
+ {member.combined_score < 0.5 && } + {member.combined_score >= 0.8 && } + +
+
+
+
+ Own + +
+
+ Team + +
+ {member.user?.branch && ( + {member.user.branch} + )} +
+
+ ))} +
+ {/* Desktop table view */} +
diff --git a/frontend/src/pages/Templates.tsx b/frontend/src/pages/Templates.tsx index ac45ee9..979c920 100644 --- a/frontend/src/pages/Templates.tsx +++ b/frontend/src/pages/Templates.tsx @@ -53,9 +53,9 @@ export function Templates() { return (
-
+
-

SOP Templates

+

SOP Templates

Master definitions of all operational checklists.

-
- - - {user.name?.charAt(0) ?? '?'} - -
-

{user.name}

-

- {user.role} {user.branch ? `• ${user.branch}` : ''} -

+
+
+ + + {user.name?.charAt(0) ?? '?'} + +
+

{user.name}

+

+ {user.role} {user.branch ? `• ${user.branch}` : ''} +

+
-
+
{(['Day', 'Week', 'Month'] as const).map((p) => (
` with stacked cards: + - Each card shows: avatar + name, role badge, score indicators + - Use `hidden md:block` for the table, `md:hidden` for the cards + - Cards are clickable with the same navigate behavior +- **All Teams tab**: Same approach — card-based on mobile + - Show name, role, combined score on card; hide department/branch to save space or show as secondary text +- **Controls row**: Tab switcher + period selector — wrap to two rows on mobile: + - `flex flex-col gap-2 sm:flex-row sm:items-center` + - Each button group takes full width on mobile + +--- + +### Step 6: Operations Tree — Simplified Mobile Layout + +**Files:** `Operations.tsx` + +- Remove `min-w-[600px]` constraint +- Remove `min-w-max` from `OperationNode` +- On mobile: + - Reduce left indentation per level: `level * 1.25rem` instead of `level * 2rem` + - Hide "Own Score" column, show only "Combined KPI" badge + - Truncate name to available width + - Reduce avatar size from `h-8 w-8` to `h-7 w-7` + - Score display: stack vertically or show single combined badge only +- The tree lines (border-l/border-t connectors): simplify or hide on mobile for cleaner look + +--- + +### Step 7: Templates Page & Sheet — Responsive Grid + Full-Width Sheet + +**Files:** `Templates.tsx` + +- Template grid: already has `md:grid-cols-2 lg:grid-cols-3` — add `grid-cols-1` base (already implied) — OK +- Header row: "Create Template" button — on mobile, use icon-only or stack below heading + - `flex flex-col gap-3 sm:flex-row sm:justify-between sm:items-center` +- **Template detail Sheet**: + - Change fixed `w-[500px] sm:w-[640px]` to responsive: `w-full sm:w-[640px]` + - On mobile, sheet takes full width + - Reduce padding: `p-4 sm:p-8` + - Signature grid at bottom: `grid-cols-1 sm:grid-cols-2` on mobile + - Print button: hide on mobile or keep as secondary action + +--- + +### Step 8: Global Spacing, Scaling & Viewport Meta + +**Files:** `index.css`, `AppLayout.tsx`, `index.html` + +- Ensure `` is set in `index.html` +- Reduce main content padding on mobile: `p-3 sm:p-6 md:p-8 lg:p-10` (currently `p-6 md:p-8 lg:p-10`) +- Page titles: `text-2xl sm:text-3xl` instead of fixed `text-3xl` +- Add `overflow-x-hidden` to prevent any accidental horizontal scroll on body/main +- Ensure `max-w-6xl` container doesn't add unnecessary side gutters on mobile +- Login page: add proper mobile padding, larger tap target for login link + +--- + +## Implementation Order + +1. **Step 1** (Bottom Nav + Hide Sidebar) — foundational, everything else depends on navigation working +2. **Step 8** (Global spacing/viewport) — sets the stage for all screens +3. **Step 2** (Topbar) — completes the navigation/chrome layer +4. **Step 3** (Dashboard) — most-visited screen, gauge scaling +5. **Step 4** (My Tasks / Checklist) — primary mobile use case for field staff +6. **Step 5** (Team) — table-to-card conversion +7. **Step 6** (Operations) — tree simplification +8. **Step 7** (Templates) — sheet width fix + +--- + +## Design Principles + +- **No horizontal scroll anywhere** — every screen must fit within viewport width +- **Touch-friendly** — minimum 44px tap targets for all interactive elements +- **Bottom nav pattern** — standard mobile app UX, keeps thumb accessible +- **Full-screen sheets on mobile** — checklist runner and template viewer become full-page overlays +- **Progressive disclosure** — show less data on mobile (e.g., fewer table columns), user taps for detail +- **Dark theme maintained** — all mobile styles stay within the existing zinc/indigo palette +- **No new dependencies** — pure Tailwind responsive utilities + existing Shadcn components