feat(cortex): Epic 1 - Patient Sidebar (E1.S1-S4)

Collapsible overlay sidebar voor snelle patient selectie met search en recent patients.

E1.S1 - Store uitbreiding:
- recentPatients: Patient[] (max 5, nieuwste eerst, geen duplicaten)
- patientSidebarOpen: boolean
- addRecentPatient, togglePatientSidebar, setPatientSidebarOpen actions

E1.S2 - PatientSidebar component:
- Overlay sidebar (w-80, z-50) met backdrop
- Search input met debounce (200ms)
- Recent patients sectie
- Hergebruik usePatientSearch, usePatientSelection hooks
- Hergebruik PatientListItem component

E1.S3 - Toggle button + shortcut:
- Users icon button in ContextBar
- Cmd/Ctrl+P keyboard shortcut
- Escape sluit sidebar (prioriteit boven artifacts)

E1.S4 - Click-to-select flow:
- Selectie zet activePatient
- Voegt toe aan recentPatients
- Sluit sidebar automatisch

Bouwplan v1.3: Epic 1 compleet (10/23 SP - 43%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
colinislit
2026-01-03 11:52:13 +01:00
parent 43d4d095ce
commit 9b0352de44
6 changed files with 301 additions and 19 deletions

View File

@@ -105,6 +105,10 @@ interface CortexStore {
activePatient: Patient | null;
shift: ShiftType;
// Patient sidebar (E1)
recentPatients: Patient[];
patientSidebarOpen: boolean;
// Block state
activeBlock: BlockType | null;
prefillData: BlockPrefillData;
@@ -143,6 +147,11 @@ interface CortexStore {
setActivePatient: (patient: Patient | null) => void;
setShift: (shift: ShiftType) => void;
// Patient sidebar actions (E1)
addRecentPatient: (patient: Patient) => void;
togglePatientSidebar: () => void;
setPatientSidebarOpen: (open: boolean) => void;
// Block actions (legacy - will be replaced by artifact actions)
openBlock: (type: BlockType, prefill?: BlockPrefillData) => void;
closeBlock: () => void;
@@ -199,6 +208,10 @@ interface CortexStore {
const initialState = {
activePatient: null,
shift: getCurrentShift(),
// Patient sidebar (E1)
recentPatients: [] as Patient[],
patientSidebarOpen: false,
// Block state
activeBlock: null,
prefillData: {},
isBlockLoading: false,
@@ -231,6 +244,29 @@ export const useCortexStore = create<CortexStore>()(
setShift: (shift) => set({ shift }, false, 'setShift'),
// Patient sidebar actions (E1)
addRecentPatient: (patient) =>
set(
(state) => ({
recentPatients: [
patient,
...state.recentPatients.filter((p) => p.id !== patient.id),
].slice(0, 5),
}),
false,
'addRecentPatient'
),
togglePatientSidebar: () =>
set(
(state) => ({ patientSidebarOpen: !state.patientSidebarOpen }),
false,
'togglePatientSidebar'
),
setPatientSidebarOpen: (open) =>
set({ patientSidebarOpen: open }, false, 'setPatientSidebarOpen'),
// Block actions
openBlock: (type, prefill = {}) => {
set(