diff --git a/Ralph/prd.json b/Ralph/prd.json index c21592a..e9b36da 100644 --- a/Ralph/prd.json +++ b/Ralph/prd.json @@ -138,7 +138,7 @@ "Verify in browser: NHS roles show blue-tinted cards, Tesco roles red-tinted, Paydens green, education purple" ], "priority": 7, - "passes": false, + "passes": true, "notes": "All changes in WorkExperienceSubsection.tsx (~299 lines). consultation.orgColor already exists on each consultation object but is not currently used for card styling. Create a helper function hexToRgba(hex: string, opacity: number): string that converts hex to rgba — needed for tinted backgrounds and borders. Replace hardcoded values: '#0D6E6E' for dot (line ~82), 'rgba(10,128,128,0.03)' for highlight bg, 'var(--accent-border)' for border, 'var(--accent)' for links/text. Each RoleItem already receives its consultation — use consultation.orgColor. For coded entry tags: text in orgColor, bg in hexToRgba(orgColor, 0.08), border in hexToRgba(orgColor, 0.2). Also update LastConsultationSubsection in DashboardLayout.tsx if it has hardcoded teal colours. The WORK EXPERIENCE CardHeader dot stays teal. Use the d3-viz skill." }, { diff --git a/Ralph/progress.txt b/Ralph/progress.txt index 8c34ec6..d307a07 100644 --- a/Ralph/progress.txt +++ b/Ralph/progress.txt @@ -31,6 +31,8 @@ - Constellation role nodes, skill mappings, and links are in constellation.ts — adding nodes there automatically extends yScale domain and screen reader description - Mobile accordion (coarse pointer): pinnedNodeId drives both graph highlight AND accordion visibility. Accordion only shows for role-type nodes (not skills) - SVG background rect has class `.bg-rect` — used for "tap elsewhere to close" handler on touch devices +- consultation.orgColor is the source of per-employer colour for cards, dots, borders, and coded entries. Use hexToRgba(orgColor, opacity) for tinted variants +- hexToRgba(hex, opacity) helper exists in both WorkExperienceSubsection.tsx and DashboardLayout.tsx for converting hex to rgba ## 2026-02-16 - US-001 - Added Duty Pharmacy Manager (2016-2017, Tesco PLC) and Pre-Registration Pharmacist (2015-2016, Paydens Pharmacy) role nodes to constellation.ts @@ -133,3 +135,26 @@ - Not all consultations have >3 examination items — the "Show more" button only renders conditionally, and plan items are only shown when expanded - Browser testing for coarse pointer features requires touch emulation — Playwright's default Chromium reports fine pointer, so the accordion won't appear without explicit touch device emulation --- + +## 2026-02-16 - US-007 +- Created hexToRgba(hex, opacity) helper function in both WorkExperienceSubsection.tsx and DashboardLayout.tsx +- WorkExperienceSubsection.tsx: replaced all hardcoded teal/accent colour references with consultation.orgColor: + - Dot indicator: '#0D6E6E' → consultation.orgColor + - Highlight background: 'rgba(10,128,128,0.03)' → hexToRgba(orgColor, 0.03) + - Expanded/highlighted border: 'var(--accent-border)' → hexToRgba(orgColor, 0.2) + - Hover border: 'var(--accent-border)' → hexToRgba(orgColor, 0.2) + - Left border on expanded detail: 'var(--accent)' → orgColor + - Bullet dots: 'var(--accent)' → orgColor at 0.5 opacity + - Coded entry tags: bg hexToRgba(orgColor, 0.08), text orgColor, border hexToRgba(orgColor, 0.2) + - "View full record" link: 'var(--accent)' → orgColor, hover uses opacity 0.7 instead of accent-hover +- DashboardLayout.tsx LastConsultationSubsection: same pattern applied: + - Highlight border/bg, hover bg, role title, bullet dots, "View full record" link all use consultation.orgColor +- CardHeader dot for "WORK EXPERIENCE" section title remains teal (unchanged) +- Files changed: src/components/WorkExperienceSubsection.tsx, src/components/DashboardLayout.tsx, Ralph/prd.json, Ralph/progress.txt +- Browser verified: NHS roles show blue dots/borders, Tesco roles show red, Paydens shows green, education shows purple. Expanded Tesco card shows red left border, red bullet dots, and red-tinted coded entries +- **Learnings for future iterations:** + - consultation.orgColor exists on every Consultation object — it's the single source for per-employer colour throughout the UI + - hexToRgba(hex, opacity) is needed in both WorkExperienceSubsection.tsx and DashboardLayout.tsx — not extracted to a shared utility since it's a small helper and only used in two files + - For hover effects on org-coloured links, use opacity change (0.7) instead of a separate --accent-hover variable, since each employer has a different base colour + - The hover mouseenter/mouseleave pattern using parentElement!.style is used for border/shadow effects — it directly mutates the parent wrapper's inline styles +--- diff --git a/src/components/DashboardLayout.tsx b/src/components/DashboardLayout.tsx index ca82ddf..a6290d7 100644 --- a/src/components/DashboardLayout.tsx +++ b/src/components/DashboardLayout.tsx @@ -55,6 +55,13 @@ const contentVariants = { }, } +function hexToRgba(hex: string, opacity: number): string { + const r = parseInt(hex.slice(1, 3), 16) + const g = parseInt(hex.slice(3, 5), 16) + const b = parseInt(hex.slice(5, 7), 16) + return `rgba(${r},${g},${b},${opacity})` +} + interface LastConsultationSubsectionProps { highlightedRoleId?: string | null } @@ -114,8 +121,8 @@ function LastConsultationSubsection({ highlightedRoleId }: LastConsultationSubse marginTop: '24px', borderRadius: 'var(--radius-sm)', border: '1px solid', - borderColor: isHighlighted ? 'var(--accent-border)' : 'transparent', - background: isHighlighted ? 'rgba(10,128,128,0.03)' : 'transparent', + borderColor: isHighlighted ? hexToRgba(consultation.orgColor ?? '#0D6E6E', 0.2) : 'transparent', + background: isHighlighted ? hexToRgba(consultation.orgColor ?? '#0D6E6E', 0.03) : 'transparent', transition: 'border-color 150ms ease-out, background-color 150ms ease-out', padding: '8px', margin: '-8px', @@ -142,7 +149,7 @@ function LastConsultationSubsection({ highlightedRoleId }: LastConsultationSubse transition: 'background-color 150ms ease-out', }} onMouseEnter={(e) => { - e.currentTarget.style.backgroundColor = 'rgba(10,128,128,0.04)' + e.currentTarget.style.backgroundColor = hexToRgba(consultation.orgColor ?? '#0D6E6E', 0.04) }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent' @@ -171,7 +178,7 @@ function LastConsultationSubsection({ highlightedRoleId }: LastConsultationSubse style={{ fontSize: '15px', fontWeight: 600, - color: 'var(--accent)', + color: consultation.orgColor ?? 'var(--accent)', marginBottom: '12px', }} > @@ -209,7 +216,7 @@ function LastConsultationSubsection({ highlightedRoleId }: LastConsultationSubse width: '5px', height: '5px', borderRadius: '50%', - backgroundColor: 'var(--accent)', + backgroundColor: consultation.orgColor ?? 'var(--accent)', opacity: 0.5, }} /> @@ -226,19 +233,19 @@ function LastConsultationSubsection({ highlightedRoleId }: LastConsultationSubse gap: '6px', fontSize: '13px', fontWeight: 500, - color: 'var(--accent)', + color: consultation.orgColor ?? 'var(--accent)', background: 'transparent', border: 'none', padding: '6px 0', minHeight: '44px', cursor: 'pointer', - transition: 'color 150ms ease-out', + transition: 'opacity 150ms ease-out', }} onMouseEnter={(e) => { - e.currentTarget.style.color = 'var(--accent-hover)' + e.currentTarget.style.opacity = '0.7' }} onMouseLeave={(e) => { - e.currentTarget.style.color = 'var(--accent)' + e.currentTarget.style.opacity = '1' }} aria-label="View full consultation record" > diff --git a/src/components/WorkExperienceSubsection.tsx b/src/components/WorkExperienceSubsection.tsx index 5a55574..be5617c 100644 --- a/src/components/WorkExperienceSubsection.tsx +++ b/src/components/WorkExperienceSubsection.tsx @@ -7,6 +7,13 @@ import { useDetailPanel } from '@/contexts/DetailPanelContext' const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches +function hexToRgba(hex: string, opacity: number): string { + const r = parseInt(hex.slice(1, 3), 16) + const g = parseInt(hex.slice(3, 5), 16) + const b = parseInt(hex.slice(5, 7), 16) + return `rgba(${r},${g},${b},${opacity})` +} + interface RoleItemProps { consultation: typeof consultations[0] isExpanded: boolean @@ -34,9 +41,9 @@ function RoleItem({ consultation, isExpanded, isHighlightedFromGraph, onToggle, return (
{ if (!isExpanded) { - e.currentTarget.parentElement!.style.borderColor = 'var(--accent-border)' + e.currentTarget.parentElement!.style.borderColor = hexToRgba(consultation.orgColor ?? '#0D6E6E', 0.2) e.currentTarget.parentElement!.style.boxShadow = 'var(--shadow-md)' } }} @@ -72,14 +79,14 @@ function RoleItem({ consultation, isExpanded, isHighlightedFromGraph, onToggle, } }} > - {/* Teal dot */} + {/* Org colour dot */}