Task 6: Rebuild PMRInterface layout + Breadcrumb
Changes made: - Created Breadcrumb.tsx component with Patient Record > [View] > [Expanded Item] navigation - Integrated Breadcrumb into PMRInterface (desktop/tablet only, not mobile) - Breadcrumb receives currentView, expandedItem props and handles navigation callbacks - Updated all font references from font-inter to font-ui (Elvaro Grotesque) - Added shadow-pmr to default view placeholder card - Mobile back button updated to use font-ui Visual verification: - Breadcrumb renders correctly with gray-400 text, chevron separators, 13px font size - Navigation updates breadcrumb path correctly (tested Summary → Experience) - Layout: fixed sidebar, sticky banner, scrollable content all working - View switching is instant (no animation between views) - Premium font (Elvaro Grotesque) rendering throughout interface Quality checks: All passed (typecheck, lint, build — 396.39 KB bundle) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { ChevronRight } from 'lucide-react'
|
||||
import type { ViewId } from '../types/pmr'
|
||||
|
||||
interface BreadcrumbProps {
|
||||
currentView: ViewId
|
||||
expandedItem?: {
|
||||
name: string
|
||||
type: string
|
||||
}
|
||||
onNavigateToView?: (view: ViewId) => void
|
||||
onCollapseItem?: () => void
|
||||
}
|
||||
|
||||
const viewLabels: Record<ViewId, string> = {
|
||||
summary: 'Summary',
|
||||
consultations: 'Experience',
|
||||
medications: 'Skills',
|
||||
problems: 'Achievements',
|
||||
investigations: 'Projects',
|
||||
documents: 'Education',
|
||||
referrals: 'Contact',
|
||||
}
|
||||
|
||||
export function Breadcrumb({
|
||||
currentView,
|
||||
expandedItem,
|
||||
onNavigateToView,
|
||||
onCollapseItem,
|
||||
}: BreadcrumbProps) {
|
||||
const handleNavigateToPatientRecord = () => {
|
||||
if (onNavigateToView) {
|
||||
onNavigateToView('summary')
|
||||
}
|
||||
}
|
||||
|
||||
const handleNavigateToCurrentView = () => {
|
||||
if (onCollapseItem) {
|
||||
onCollapseItem()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<nav
|
||||
className="flex items-center gap-2 mb-6"
|
||||
aria-label="Breadcrumb"
|
||||
>
|
||||
<ol className="flex items-center gap-2">
|
||||
{/* Patient Record (root) */}
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleNavigateToPatientRecord}
|
||||
className="text-[13px] font-ui font-normal text-gray-400 hover:text-pmr-nhsblue transition-colors"
|
||||
>
|
||||
Patient Record
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<ChevronRight size={14} className="text-gray-300" />
|
||||
</li>
|
||||
|
||||
{/* Current view */}
|
||||
<li>
|
||||
{expandedItem ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleNavigateToCurrentView}
|
||||
className="text-[13px] font-ui font-normal text-gray-400 hover:text-pmr-nhsblue transition-colors"
|
||||
>
|
||||
{viewLabels[currentView]}
|
||||
</button>
|
||||
) : (
|
||||
<span className="text-[13px] font-ui font-normal text-gray-600">
|
||||
{viewLabels[currentView]}
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
|
||||
{/* Expanded item (if any) */}
|
||||
{expandedItem && (
|
||||
<>
|
||||
<li>
|
||||
<ChevronRight size={14} className="text-gray-300" />
|
||||
</li>
|
||||
<li>
|
||||
<span className="text-[13px] font-ui font-normal text-gray-600">
|
||||
{expandedItem.name}
|
||||
</span>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
</ol>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import type { ViewId } from '../types/pmr'
|
||||
import { ClinicalSidebar } from './ClinicalSidebar'
|
||||
import { PatientBanner } from './PatientBanner'
|
||||
import { MobileBottomNav } from './MobileBottomNav'
|
||||
import { Breadcrumb } from './Breadcrumb'
|
||||
import { SummaryView } from './views/SummaryView'
|
||||
import { ConsultationsView } from './views/ConsultationsView'
|
||||
import { MedicationsView } from './views/MedicationsView'
|
||||
@@ -130,11 +131,11 @@ function PMRContent({ children }: PMRInterfaceProps) {
|
||||
return <ReferralsView />
|
||||
default:
|
||||
return (
|
||||
<div className="bg-white border border-gray-200 rounded p-6">
|
||||
<h1 className="font-inter font-semibold text-lg text-gray-900 capitalize">
|
||||
<div className="bg-white border border-gray-200 rounded p-6 shadow-pmr">
|
||||
<h1 className="font-ui font-semibold text-lg text-gray-900 capitalize">
|
||||
{activeView} View
|
||||
</h1>
|
||||
<p className="font-inter text-sm text-gray-500 mt-2">
|
||||
<p className="font-ui text-sm text-gray-500 mt-2">
|
||||
Content for {activeView} will be implemented in a separate task.
|
||||
</p>
|
||||
</div>
|
||||
@@ -201,11 +202,26 @@ function PMRContent({ children }: PMRInterfaceProps) {
|
||||
<h1 className="sr-only">{viewLabels[activeView]}</h1>
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb (desktop/tablet only) */}
|
||||
{!isMobile && (
|
||||
<Breadcrumb
|
||||
currentView={activeView}
|
||||
expandedItem={
|
||||
expandedItemId
|
||||
? { name: expandedItemId, type: activeView }
|
||||
: undefined
|
||||
}
|
||||
onNavigateToView={handleNavigate}
|
||||
onCollapseItem={() => setExpandedItem(null)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Mobile back button (mobile only) */}
|
||||
{isMobile && activeView !== 'summary' && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleBackToSummary}
|
||||
className="flex items-center gap-1 text-pmr-nhsblue text-sm font-inter font-medium mb-4 hover:underline"
|
||||
className="flex items-center gap-1 text-pmr-nhsblue text-sm font-ui font-medium mb-4 hover:underline"
|
||||
>
|
||||
<ArrowLeft size={14} />
|
||||
Back to Summary
|
||||
@@ -246,7 +262,7 @@ function MobileSearchBar({ query, onChange }: MobileSearchBarProps) {
|
||||
placeholder="Search record..."
|
||||
value={query}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
className="w-full h-10 pl-10 pr-10 bg-white border border-gray-200 rounded text-sm font-inter text-gray-900 placeholder-gray-400 focus:outline-none focus:border-pmr-nhsblue focus:ring-1 focus:ring-pmr-nhsblue/20 transition-colors"
|
||||
className="w-full h-10 pl-10 pr-10 bg-white border border-gray-200 rounded text-sm font-ui text-gray-900 placeholder-gray-400 focus:outline-none focus:border-pmr-nhsblue focus:ring-1 focus:ring-pmr-nhsblue/20 transition-colors"
|
||||
/>
|
||||
{query && (
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user