From 0e7bef020687ce44bce3a2e62cba6c2298aed54f Mon Sep 17 00:00:00 2001 From: Andy Charlwood Date: Sat, 14 Feb 2026 18:06:18 +0000 Subject: [PATCH] feat: US-007 - Move Last Consultation into Patient Pathway as subsection --- src/components/DashboardLayout.tsx | 191 ++++++++++++- src/components/tiles/LastConsultationTile.tsx | 255 ------------------ 2 files changed, 185 insertions(+), 261 deletions(-) delete mode 100644 src/components/tiles/LastConsultationTile.tsx diff --git a/src/components/DashboardLayout.tsx b/src/components/DashboardLayout.tsx index 5bdca7b..8127b1e 100644 --- a/src/components/DashboardLayout.tsx +++ b/src/components/DashboardLayout.tsx @@ -1,13 +1,14 @@ -import { useState, useEffect, useCallback } from 'react' +import React, { useState, useEffect, useCallback } from 'react' import { motion } from 'framer-motion' +import { ChevronRight } from 'lucide-react' import { TopBar } from './TopBar' import { SubNav } from './SubNav' import Sidebar from './Sidebar' import { CommandPalette } from './CommandPalette' import { DetailPanel } from './DetailPanel' +import { CardHeader } from './Card' import { PatientSummaryTile } from './tiles/PatientSummaryTile' import { CoreSkillsTile } from './tiles/CoreSkillsTile' -import { LastConsultationTile } from './tiles/LastConsultationTile' import { EducationTile } from './tiles/EducationTile' import { ProjectsTile } from './tiles/ProjectsTile' import { ParentSection } from './ParentSection' @@ -52,6 +53,184 @@ const contentVariants = { }, } +function LastConsultationSubsection() { + const { openPanel } = useDetailPanel() + const consultation = consultations[0] + + const handleOpenPanel = () => { + openPanel({ type: 'consultation', consultation }) + } + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + handleOpenPanel() + } + } + + const formatDate = (dateStr: string): string => { + const date = new Date(dateStr) + return date.toLocaleDateString('en-GB', { month: 'long', year: 'numeric' }) + } + + const getEmploymentType = (): string => { + if (consultation.organization.includes('ICB')) { + return 'Permanent · Full-time' + } + return 'Permanent' + } + + const getBand = (): string => { + if (consultation.role.includes('Head')) { + return '8a' + } + return '—' + } + + const fieldLabelStyle: React.CSSProperties = { + fontSize: '10px', + textTransform: 'uppercase', + letterSpacing: '0.06em', + color: 'var(--text-tertiary)', + marginBottom: '3px', + } + + const fieldValueStyle: React.CSSProperties = { + fontSize: '11.5px', + fontWeight: 600, + color: 'var(--text-primary)', + } + + return ( +
+ + +
{ + e.currentTarget.style.backgroundColor = 'rgba(10,128,128,0.04)' + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = 'transparent' + }} + aria-label={`View full details for ${consultation.role}`} + > +
+
Date
+
{formatDate(consultation.date)}
+
+
+
Organisation
+
{consultation.organization}
+
+
+
Type
+
{getEmploymentType()}
+
+
+
Band
+
{getBand()}
+
+
+ +
+ {consultation.role} +
+ +
    + {consultation.examination.map((bullet, index) => ( +
  • +
  • + ))} +
+ + +
+ ) +} + export function DashboardLayout() { const [commandPaletteOpen, setCommandPaletteOpen] = useState(false) const activeSection = useActiveSection() @@ -197,15 +376,15 @@ export function DashboardLayout() { {/* CoreSkillsTile — full width */} - {/* LastConsultationTile — full width */} - - - {/* Patient Pathway — parent section with constellation graph */} + {/* Patient Pathway — parent section with constellation graph + subsections */} + + {/* Last Consultation subsection */} + {/* EducationTile — full width */} diff --git a/src/components/tiles/LastConsultationTile.tsx b/src/components/tiles/LastConsultationTile.tsx deleted file mode 100644 index ac7363a..0000000 --- a/src/components/tiles/LastConsultationTile.tsx +++ /dev/null @@ -1,255 +0,0 @@ -import React from 'react' -import { Card, CardHeader } from '../Card' -import { consultations } from '@/data/consultations' -import { useDetailPanel } from '@/contexts/DetailPanelContext' -import { ChevronRight } from 'lucide-react' - -export const LastConsultationTile: React.FC = () => { - const { openPanel } = useDetailPanel() - - // Use the most recent consultation (first in array) - const consultation = consultations[0] - - const handleOpenPanel = () => { - openPanel({ type: 'consultation', consultation }) - } - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault() - handleOpenPanel() - } - } - - // Format date to "May 2025" format - const formatDate = (dateStr: string): string => { - const date = new Date(dateStr) - return date.toLocaleDateString('en-GB', { month: 'long', year: 'numeric' }) - } - - // Extract employment type from duration string (e.g., "May 2025 — Nov 2025") - const getEmploymentType = (): string => { - // All ICB roles are Permanent · Full-time (from CV context) - if (consultation.organization.includes('ICB')) { - return 'Permanent · Full-time' - } - return 'Permanent' - } - - // Extract band from role context - ICB senior roles are typically Band 8a - const getBand = (): string => { - if (consultation.role.includes('Head')) { - return '8a' - } - return '—' - } - - return ( - - - - {/* Header info row - clickable */} -
{ - e.currentTarget.style.backgroundColor = 'rgba(10,128,128,0.04)' - }} - onMouseLeave={(e) => { - e.currentTarget.style.backgroundColor = 'transparent' - }} - aria-label={`View full details for ${consultation.role}`} - > -
-
- Date -
-
- {formatDate(consultation.date)} -
-
- -
-
- Organisation -
-
- {consultation.organization} -
-
- -
-
- Type -
-
- {getEmploymentType()} -
-
- -
-
- Band -
-
- {getBand()} -
-
-
- - {/* Role title */} -
- {consultation.role} -
- - {/* Bullet list */} -
    - {consultation.examination.map((bullet, index) => ( -
  • - {/* Bullet dot */} - - {bullet} -
  • - ))} -
- - {/* View full record button */} - -
- ) -}