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>
This commit is contained in:
71
components/swift/command-center/offline-banner.tsx
Normal file
71
components/swift/command-center/offline-banner.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
'use client';
|
||||
|
||||
/**
|
||||
* Offline Banner
|
||||
*
|
||||
* Toont een banner wanneer de gebruiker offline is.
|
||||
* E5.S2: Offline detection en melding.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { WifiOff } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export function OfflineBanner() {
|
||||
const [isOffline, setIsOffline] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Initial check
|
||||
setIsOffline(!navigator.onLine);
|
||||
|
||||
// Listen for online/offline events
|
||||
const handleOnline = () => setIsOffline(false);
|
||||
const handleOffline = () => setIsOffline(true);
|
||||
|
||||
window.addEventListener('online', handleOnline);
|
||||
window.addEventListener('offline', handleOffline);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('online', handleOnline);
|
||||
window.removeEventListener('offline', handleOffline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!isOffline) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'fixed top-0 left-0 right-0 z-[100] bg-amber-500 text-white px-4 py-2',
|
||||
'flex items-center justify-center gap-2 text-sm font-medium',
|
||||
'shadow-md'
|
||||
)}
|
||||
style={{ height: '40px' }}
|
||||
>
|
||||
<WifiOff className="h-4 w-4" />
|
||||
<span>Geen internetverbinding</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook om te checken of de gebruiker offline is
|
||||
*/
|
||||
export function useOffline() {
|
||||
const [isOffline, setIsOffline] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsOffline(!navigator.onLine);
|
||||
const handleOnline = () => setIsOffline(false);
|
||||
const handleOffline = () => setIsOffline(true);
|
||||
window.addEventListener('online', handleOnline);
|
||||
window.addEventListener('offline', handleOffline);
|
||||
return () => {
|
||||
window.removeEventListener('online', handleOnline);
|
||||
window.removeEventListener('offline', handleOffline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isOffline;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user