137 lines
4.8 KiB
Markdown
137 lines
4.8 KiB
Markdown
# 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):
|
|
|
|
1. **TopBar**: slides down from `-48px`, 200ms ease-out
|
|
2. **Sidebar**: slides from `-272px` left, 250ms ease-out, 50ms delay
|
|
3. **Main content**: fades in (opacity 0→1), 300ms, 150ms delay
|
|
|
|
```typescript
|
|
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:
|
|
1. `PatientSummaryTile` — `grid-column: 1 / -1` (full width)
|
|
2. `LatestResultsTile` — single column (left)
|
|
3. `CoreSkillsTile` — single column (right)
|
|
4. `LastConsultationTile` — `grid-column: 1 / -1` (full width)
|
|
5. `CareerActivityTile` — `grid-column: 1 / -1` (full width)
|
|
6. `EducationTile` — `grid-column: 1 / -1` (full width)
|
|
7. `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 />`.
|
|
|
|
```typescript
|
|
// 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:
|
|
1. The DashboardLayout entrance animation covers the transition (content fades in over the dark background, replacing it)
|
|
2. A brief CSS transition on the body/root background color
|
|
3. 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.
|