4.8 KiB
Reference: Task 7 — DashboardLayout
Overview
Create the main layout component that replaces PMRInterface.tsx. This is the container that houses TopBar, Sidebar, and the scrollable card grid of tiles.
File: src/components/DashboardLayout.tsx
Layout Structure
┌────────────────────────────────────────────────────┐
│ TopBar (fixed, z-100, height: 48px) │
├──────────┬─────────────────────────────────────────┤
│ │ │
│ Sidebar │ <main> — scrollable card grid │
│ (272px) │ padding: 24px 28px 40px │
│ fixed │ │
│ │ grid: 1fr 1fr, gap: 16px │
│ │ │
│ │ [PatientSummary — full] │
│ │ [LatestResults] [CoreSkills] │
│ │ [LastConsultation — full] │
│ │ [CareerActivity — full] │
│ │ [Education — full] │
│ │ [Projects — full] │
│ │ │
└──────────┴─────────────────────────────────────────┘
CSS Layout
.layout {
display: flex;
margin-top: var(--topbar-height); /* 48px */
height: calc(100vh - var(--topbar-height));
}
.sidebar {
/* See ref-03-topbar-sidebar.md for sidebar specs */
width: var(--sidebar-width);
min-width: var(--sidebar-width);
/* ... */
}
.main {
flex: 1;
overflow-y: auto;
padding: 24px 28px 40px;
}
.card-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
@media (max-width: 900px) {
.card-grid {
grid-template-columns: 1fr;
}
}
Use Tailwind classes for all of this — the CSS above is for reference only.
Framer Motion Entrance Animations
Staggered entrance when dashboard first renders (after login):
- TopBar: slides down from
-48px, 200ms ease-out - Sidebar: slides from
-272pxleft, 250ms ease-out, 50ms delay - Main content: fades in (opacity 0→1), 300ms, 150ms delay
const topbarVariants = {
hidden: { y: -48, opacity: 0 },
visible: { y: 0, opacity: 1, transition: { duration: 0.2, ease: 'easeOut' } }
}
const sidebarVariants = {
hidden: { x: -272, opacity: 0 },
visible: { x: 0, opacity: 1, transition: { duration: 0.25, ease: 'easeOut', delay: 0.05 } }
}
const contentVariants = {
hidden: { opacity: 0 },
visible: { opacity: 1, transition: { duration: 0.3, delay: 0.15 } }
}
With prefers-reduced-motion: all durations → 0, no delays.
Tile Ordering in Grid
The card grid renders tiles in this order:
PatientSummaryTile—grid-column: 1 / -1(full width)LatestResultsTile— single column (left)CoreSkillsTile— single column (right)LastConsultationTile—grid-column: 1 / -1(full width)CareerActivityTile—grid-column: 1 / -1(full width)EducationTile—grid-column: 1 / -1(full width)ProjectsTile—grid-column: 1 / -1(full width)
App.tsx Wiring
In src/App.tsx, the PMR phase currently renders <PMRInterface />. Change it to render <DashboardLayout />.
// In App.tsx phase switch:
case 'pmr':
return <DashboardLayout />
Keep all other phases (boot, ecg, login) unchanged. The SkipButton that skips to login should still work.
Scrollbar Styling
Main content area scrollbar (matches concept):
- Width: 6px
- Track: transparent
- Thumb: var(--border) (#D4E0DE), border-radius 3px
Command Palette Integration
The DashboardLayout should render the CommandPalette component (from Task 18) at the layout level, so it overlays the entire dashboard when triggered. For now (Task 7), just add a placeholder comment or empty div where it will go. The TopBar search bar's click handler should be wired to open the palette (but the palette itself comes in Task 18).
Background Color Transition
The login screen has background #1E293B. The dashboard has background #F0F5F4. This transition should happen smoothly. Options:
- The DashboardLayout entrance animation covers the transition (content fades in over the dark background, replacing it)
- A brief CSS transition on the body/root background color
- Handle it in App.tsx with a state-based background
The simplest approach is option 1 — the dashboard's entrance animation effectively replaces the dark login background with the light dashboard.