Mobile overview changes

This commit is contained in:
2026-02-18 12:25:53 +00:00
parent 8b79f7b273
commit 9baa6e605b
56 changed files with 3956 additions and 7000 deletions
+92 -79
View File
@@ -1,103 +1,116 @@
# Task: Portfolio UX Improvements — GP Clinical System Theme Polish
# Task: Replace Mobile Banner with Inline Overview Section
Implement 11 prioritised UX improvements to the portfolio site. This is an interactive CV/portfolio themed as a GP primary care clinical system (like EMIS Web / SystmOne). The site should feel like a real GP system but function as a portfolio.
Remove the sticky `MobilePatientBanner` and replace it with a static inline section at the top of the mobile dashboard. Remove the "More" drawer from the bottom nav, since its content now lives inline at the top of the page.
**Important constraints:**
- Do NOT change the overall structure or architecture
- Preserve the GP clinical system theme — improvements should reinforce it, not break it
- Respect existing conventions: TypeScript strict, Tailwind + CSS custom properties, Framer Motion with `prefers-reduced-motion`
- Path alias: `@/*``src/*`
- Quality gates: `npm run lint && npm run typecheck && npm run build`
## Files
## Improvements (ordered by priority)
| File | Role |
|------|------|
| `src/components/MobilePatientBanner.tsx` | DELETE — replaced by new inline section |
| `src/components/MobileBottomNav.tsx` | Remove "More" button + entire drawer; add Overview item; rename old Overview to "Summary" |
| `src/components/DashboardLayout.tsx` | Swap MobilePatientBanner for new MobileOverviewHeader; pass onSearchClick |
| `src/components/MobileOverviewHeader.tsx` | NEW — inline mobile header section |
| `src/components/ReferralFormModal.tsx` | Already exists — opened from the new section's Contact button |
| `src/components/Sidebar.tsx` | Reference only — button styles, URLs |
### 1. Restructure Profile Summary Text
**File:** `src/components/tiles/PatientSummaryTile.tsx` (or wherever the narrative renders)
**Problem:** The patient summary narrative is a dense ~80-word paragraph — a wall of text. It's the first substantive content visitors see and doesn't match the structured clinical aesthetic.
**Change:** Break into structured clinical-style data:
- Brief 1-2 sentence summary (like a presenting complaint)
- Key facts as labeled fields below: Specialisation, Current System, Population, Focus Areas
- Or collapse behind "Read more" with first sentence visible
- Must feel like GP system structured data, not a LinkedIn About section
## What to Build
### 2. Surface Impact Metrics on Project Cards
**File:** `src/components/tiles/ProjectsTile.tsx` (or the project card component)
**Problem:** `resultSummary` exists in the data (e.g., "14,000 patients identified", "£2.6M savings") but is not rendered on project card faces. Recruiters scan for numbers.
**Change:** Render `resultSummary` prominently on each project card — below the title, styled as a bold stat. If a project has no `resultSummary`, don't show a placeholder.
### 1. New `MobileOverviewHeader.tsx`
### 3. Add Prominent Contact/Download CV CTA
**Problem:** No visible "Get in touch" or "Download CV" button in the main content area. These actions only exist in the sidebar or command palette.
**Change:** Add a small, visible row of action buttons (Email, LinkedIn, GitHub, Download CV) in the Patient Summary section. Style them as GP system action buttons to reinforce the theme. Keep it compact — not a hero CTA, but unmissable.
A static (not sticky) section rendered at the top of mobile `<main>` content, before `PatientSummaryTile`. Visible only when `useIsMobileNav()` is true. Must have `data-tile-id="mobile-overview"` so the bottom nav Overview button can scroll to it.
### 4. Reduce Boot + Login Sequence Time
**Files:** `src/components/BootSequence.tsx`, `src/components/LoginScreen.tsx`
**Problem:** Boot (~6-8s) + Login (~4s) = ~10 seconds before content. Too slow for repeat visitors.
**Change:** Reduce `TYPING_SPEED` multiplier to ~1.2 (from 2). Add `sessionStorage` detection — if user has visited before in this session, auto-skip directly to dashboard. Ensure skip button still appears early for first-time visitors.
**Layout (top to bottom), matching the existing "More" drawer layout in `MobileBottomNav.tsx` lines 273381:**
### 5. Resolve Last Consultation / Timeline Duplication
**Files:** `src/components/tiles/LastConsultationCard.tsx`, `src/components/tiles/TimelineInterventionsSubsection.tsx`
**Problem:** Current role appears twice — once as LastConsultationCard and again as first timeline accordion entry. Redundant.
**Change:** Differentiate LastConsultationCard as a summary-only card (role, org, band, date range, one-line summary) without the full bullet points. The full details should only appear in the timeline accordion. Add a "Current" badge to the first timeline accordion entry.
1. **Logo + Search row**`CvmisLogo` (cssHeight "40px") + search button (full-width, `minHeight: 44px`, shows search label text). Search button calls `onSearchClick` prop.
### 6. Fix Text-Tertiary Contrast Ratio
**File:** `src/index.css`
**Problem:** `--text-tertiary: #8DA8A5` on `--bg-dashboard: #F0F5F4` yields ~2.8:1 contrast, failing WCAG AA.
**Change:** Darken `--text-tertiary` to at least `#6B8886` (achieves ~4.5:1 on `#F0F5F4`). Verify the change looks good across dates, helper text, and monospace metadata.
2. **Patient info section** (bordered bottom with `2px solid var(--accent)`):
- Avatar circle (44px, gradient, "AC") + name + role title — same layout as drawer lines 301327
- Data rows: GPhC, Education, Location, Registered, Phone (PhoneCaptcha), Email — same as drawer lines 329356
### 7. Add Mobile Identity Bar
**Problem:** On mobile, no name or identity marker is visible without opening the drawer. Recruiters on mobile have no visual anchor.
**Change:** Add a compact identity bar at the top of mobile layout showing "CHARLWOOD, Andrew" and brief role title. Only visible on mobile (below `lg` breakpoint where sidebar is hidden). Style it like a GP system patient banner strip.
3. **Tags section** — tag pills, same as drawer lines 360369
### 8. Simplify KPI Section Header Language
**File:** The KPI/metrics section component
**Problem:** "LATEST RESULTS (CLICK TO VIEW FULL REFERENCE RANGE)" is deep medical jargon that non-healthcare visitors won't understand.
**Change:** Change to "KEY METRICS" or "IMPACT HIGHLIGHTS". Update the helper text to "Select a metric to inspect methodology, impact, and outcomes" (if not already). Keep the excellent metric cards unchanged.
4. **Action buttons** (replacing the alerts section):
- **Download CV** — full-width button with icon + text label. `<a>` to `/References/CV_v4.md`, new tab. Style: accent-bordered, matches sidebar's download button.
- **Three icon-only buttons in a row** (equal-width grid, 3 columns):
- **Contact Patient** — `Send` icon. Opens `ReferralFormModal`.
- **LinkedIn** — `Linkedin` icon. Links to `https://linkedin.com/in/andycharlwood`, new tab.
- **GitHub** — `Github` icon. Links to `https://github.com/andycharlwood`, new tab.
- Use the same button styles as the existing `MobilePatientBanner.tsx` action buttons (lines 228323). Icon-only for the 3 buttons, accessible `aria-label` on each.
### 9. Add Detail Panel Exit Animation
**Files:** `src/components/DetailPanel.tsx`
**Problem:** Panel has `panel-slide-in` animation but closes instantly. `panel-slide-out` keyframe exists in CSS but is unused.
**Change:** Implement exit animation — either wire up the existing `panel-slide-out` keyframe via a closing state, or use Framer Motion's `AnimatePresence`. The panel should slide out before unmounting.
5. **ReferralFormModal** — render it inside this component, controlled by local `showReferralForm` state.
### 10. Fix marginBottom Typo
**File:** `src/components/tiles/LastConsultationCard.tsx` (around line 89)
**Problem:** `marginBottom: '1=px'` — typo, should be `'1px'` or appropriate value.
**Change:** Fix the typo. Check surrounding styles for the correct intended value.
**Style notes:**
- Use `padding: 16px` internally (it sits within the main content's `p-3 xs:p-5` padding)
- Background: `var(--sidebar-bg)` to match the drawer look
- Bottom margin to separate from PatientSummaryTile
- Border-radius: `var(--radius-sm)` on the whole container
- Border: `1px solid var(--border)`
### 11. Add Arrow Navigation to Desktop Projects Carousel
**File:** `src/components/tiles/ProjectsTile.tsx``ContinuousScrollCarousel` component (lines ~356480)
**Problem:** The ContinuousScrollCarousel (desktop ≥1024px) auto-scrolls but offers no manual browsing.
**Change:**
- Add prev/next arrow buttons (ChevronLeft, ChevronRight from lucide-react) positioned absolutely at left/right edges, vertically centered
- Style following the existing FullscreenButton pattern: `var(--surface)` background, `var(--border)` border, opacity hover effect, subtle shadow
- Arrow click handler: jump one card width + gap = `((viewportWidth - 36) / 4) + 12` pixels
- Apply temporary CSS transition on the track (`transform 0.4s ease`) for smooth animated jump; remove transition after completion so rAF loop isn't fighting CSS
- Handle wrapping: keep offset within `[0, firstSetWidth)` using modulo
- Pause/resume: on arrow click set `isPausedRef = true`, clear existing timeout, start 6-second timeout to resume auto-scroll
- Existing hover pause/resume still works independently
- Rapid clicks: each click resets the 6s timeout; transition handles overlapping clicks by snapping to current offset
- Reduced motion: arrows still work (instant jump, no transition), auto-scroll stays disabled per existing logic
### 2. Modify `MobileBottomNav.tsx`
- **Remove** the "More" `<button>` from the bottom tab bar (lines 178199)
- **Remove** the entire drawer — the `<AnimatePresence>` block (lines 203385) and all drawer state/handlers (`drawerOpen`, `setDrawerOpen`, `handleDrawerKeyDown`)
- **Remove** unused imports that were only needed by the drawer: `CvmisLogo`, `PhoneCaptcha`, `patient`, `tags`, `alerts`, `getSidebarCopy`, `TagPill`, `AlertFlag`, `X`, `Menu`, `Search`, `AlertCircle`, `AlertTriangle`, `AnimatePresence`, `motion`, `prefersReducedMotion`
- **Rename** the existing "Overview" nav item to **"Summary"** with the `ClipboardList` icon (from lucide-react). It keeps its tileId `'patient-summary'`.
- **Add** a new **"Overview"** nav item at position 0 (start of the array) with the `UserRound` icon and tileId `'mobile-overview'` so it scrolls to the new header section.
- The final nav item order must be: **Overview, Summary, Experience, Skills** (4 items, no "More").
- Clean up: remove any now-unused local components (`TagPill`, `AlertFlag`)
### 3. Modify `DashboardLayout.tsx`
- **Remove** `MobilePatientBanner` import and its render (`{isMobileNav && <MobilePatientBanner />}` at line 303)
- **Add** import for new `MobileOverviewHeader`
- **Render** `{isMobileNav && <MobileOverviewHeader onSearchClick={handleSearchClick} />}` in the same position (before `<div className="dashboard-grid">`)
### 4. Delete `MobilePatientBanner.tsx`
This component is fully replaced. Delete the file.
## Success Criteria
All of the following must be true:
- [ ] Profile summary is structured data, not a text wall — feels clinical
- [ ] Project cards display `resultSummary` when available
- [ ] Contact/Download CV actions are visible in the main content area
- [ ] Boot + login sequence completes in ~5 seconds or less for first visit; instant skip for return visitors
- [ ] LastConsultationCard is a distinct summary (no duplication with timeline)
- [ ] `--text-tertiary` passes WCAG AA contrast (4.5:1) on dashboard background
- [ ] Mobile shows identity/name without opening drawer
- [ ] KPI header uses plain language, not clinical jargon
- [ ] Detail panel has exit animation (slide out, not instant disappear)
- [ ] marginBottom typo is fixed
- [ ] Desktop projects carousel has prev/next arrow buttons
- [ ] Arrow buttons pause auto-scroll for 6s then resume
### New overview section
- [ ] `MobileOverviewHeader` renders at top of mobile content (before PatientSummaryTile)
- [ ] Has `data-tile-id="mobile-overview"` attribute
- [ ] Shows logo + search bar at top
- [ ] Shows patient avatar, name, role, and all data rows
- [ ] Shows tag pills
- [ ] Shows Download CV button (full-width, icon + text)
- [ ] Shows 3 icon-only buttons (Contact, LinkedIn, GitHub) in a row
- [ ] Contact button opens ReferralFormModal
- [ ] LinkedIn and GitHub links open in new tabs
- [ ] All buttons have appropriate aria-labels
- [ ] Only visible on mobile (useIsMobileNav)
### Bottom nav changes
- [ ] "More" button is removed from bottom nav
- [ ] Drawer is completely removed (no AnimatePresence, no overlay)
- [ ] New "Overview" button (UserRound icon) is first in nav and scrolls to `mobile-overview` section
- [ ] Old "Overview" is renamed to "Summary" with ClipboardList icon, still scrolls to `patient-summary`
- [ ] Bottom nav has exactly 4 items in order: Overview, Summary, Experience, Skills
### Cleanup
- [ ] `MobilePatientBanner.tsx` is deleted
- [ ] No dead imports remain in any modified file
- [ ] No unused components (TagPill, AlertFlag) remain in MobileBottomNav
### Quality gates
- [ ] `npm run lint` passes
- [ ] `npm run typecheck` passes
- [ ] `npm run build` passes
- [ ] No regressions — existing functionality preserved
- [ ] Playwright MCP verification passes on mobile viewport (375x812)
## Constraints
- Do not add new npm dependencies
- Do not change `server.ts` or the `/api/contact` API contract
- Preserve all accessibility attributes (aria-labels, aria-expanded, etc.)
- Follow existing conventions: inline styles + Tailwind classes, TypeScript strict mode
- Icons from `lucide-react` only
- Respect `prefers-reduced-motion` for any animations
- The new section is NOT sticky — it scrolls with content
## Status
Track progress here. Mark items complete as you go.
When all success criteria are met, print LOOP_COMPLETE.
Track progress in `.ralph/plan.md`. When all success criteria are met, print LOOP_COMPLETE.