Files
triqura-ecd/components/swift/command-center/command-center.tsx
colinislit 33c6698870 feat(swift): Epic 5 Progress - Error Handling & Keyboard Shortcuts (E5.S2-S3)
Epic 5 deels compleet: Error handling en keyboard shortcuts geïmplementeerd.
Voortgang: 62 SP / 72 SP (86%) - Nog 1 story voor MVP compleet!

E5.S2 - Error Handling (2 SP)
- Gecentraliseerde error handler utility (lib/swift/error-handler.ts)
- isOffline(), isNetworkError(), getErrorInfo() functies
- safeFetch() wrapper met 30s timeout en retry logic
- retryFetch() met exponential backoff (max 3 retries)
- User-friendly Nederlandse error messages voor alle HTTP status codes
- OfflineBanner component met online/offline detection
- Alle blocks en CommandInput gebruiken nieuwe error handler
- Context bar margin adjustment voor offline banner
- parseErrorResponse() voor HTML error detection

E5.S3 - Keyboard Shortcuts (2 SP)
- ⌘Enter / Ctrl+Enter quick submit in CommandInput
- ⌘Enter / Ctrl+Enter quick save in DagnotatieBlock
- Visual hints (⌘↵) op submit button in DagnotatieBlock
- Geverifieerd: ⌘K focus, Escape close, 1-3 FallbackPicker
- Cross-platform support (macOS + Windows/Linux)
- preventDefault() voor browser conflict preventie

Components Updated:
- DagnotatieBlock: safeFetch, getErrorInfo, retryFetch, ⌘Enter save
- OverdrachtBlock: safeFetch, retryFetch voor AI generation
- ZoekenBlock: safeFetch, getErrorInfo voor patient search
- CommandInput: safeFetch, getErrorInfo, ⌘Enter submit
- CommandCenter: OfflineBanner integration
- ContextBar: useOffline hook voor margin adjustment

Nieuwe Files:
- lib/swift/error-handler.ts (301 regels) - Error handling utilities
- components/swift/command-center/offline-banner.tsx (72 regels)
- docs/swift/keyboard-shortcuts-reference.md (200+ regels)
- docs/swift/test-plan-e5-s2-error-handling.md (350+ regels)
- docs/swift/test-plan-e5-s3-keyboard-shortcuts.md (350+ regels)
- docs/swift/PROJECT-STATUS-2024-12-27.md (500+ regels) - Status report

Documentatie:
- Bouwplan bijgewerkt naar v2.5
- Epic completion details toegevoegd met progress bars
- Manual test checklist bijgewerkt (17/20 scenarios)
- Risico's sectie bijgewerkt (alle major risks gemitigeerd)
- Sprint planning status: E5 75% compleet (6/8 SP)

Technische verbeteringen:
- Offline detection met visual feedback
- Network error retry met exponential backoff
- HTTP 401/404/500/503 error messages in Nederlands
- Timeout protection (30s) op alle API calls
- Keyboard shortcuts met visual hints
- Cross-platform shortcut support

Testing:
- Error handling test plan met 8 categorieën
- Keyboard shortcuts test plan met 6 categorieën
- 40+ test scenarios gedocumenteerd
- Quick smoke test checklists

Voortgang: 62 SP / 72 SP (86%) - E5.S2 en E5.S3 compleet

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 09:27:32 +01:00

70 lines
1.7 KiB
TypeScript

'use client';
/**
* Command Center
*
* Main container for the Swift interface.
* 4-zone layout: Context Bar | Canvas Area | Recent Strip | Command Input
*
* Layout specs:
* - Context Bar: 48px (h-12)
* - Canvas Area: flex-1 (fills remaining space)
* - Recent Strip: 48px (h-12)
* - Command Input: 64px (h-16)
*/
import { useEffect, useCallback, useRef } from 'react';
import { useSwiftStore } from '@/stores/swift-store';
import { ContextBar } from './context-bar';
import { CommandInput } from './command-input';
import { RecentStrip } from './recent-strip';
import { CanvasArea } from './canvas-area';
import { OfflineBanner } from './offline-banner';
export function CommandCenter() {
const { closeBlock, activeBlock } = useSwiftStore();
const inputRef = useRef<HTMLInputElement>(null);
// Global keyboard shortcuts
const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
// Escape: close active block
if (e.key === 'Escape' && activeBlock) {
e.preventDefault();
closeBlock();
}
// Cmd/Ctrl + K: focus input
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
inputRef.current?.focus();
}
},
[activeBlock, closeBlock]
);
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [handleKeyDown]);
return (
<>
{/* Offline Banner */}
<OfflineBanner />
{/* Context Bar - 48px */}
<ContextBar />
{/* Canvas Area - flex */}
<CanvasArea />
{/* Recent Strip - 48px */}
<RecentStrip />
{/* Command Input - 64px */}
<CommandInput ref={inputRef} />
</>
);
}