Mobile overview changes
This commit is contained in:
@@ -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 273–381:**
|
||||
|
||||
### 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 301–327
|
||||
- Data rows: GPhC, Education, Location, Registered, Phone (PhoneCaptcha), Email — same as drawer lines 329–356
|
||||
|
||||
### 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 360–369
|
||||
|
||||
### 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 228–323). 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 ~356–480)
|
||||
**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 178–199)
|
||||
- **Remove** the entire drawer — the `<AnimatePresence>` block (lines 203–385) 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.
|
||||
|
||||
Reference in New Issue
Block a user