aethex-studio/src/components/ui/loading-spinner.tsx
Claude 1b1466f4ec
Add major feature improvements and developer experience enhancements
New Features:
 File Content Syncing - Code changes now persist to file tree (App.tsx)
  - Added handleCodeChange() to update file content in real-time
  - Syncs changes to both files state and openFiles tabs
  - Templates now properly update active file content

 Keyboard Shortcuts System (use-keyboard-shortcuts.ts)
  - Cmd/Ctrl+S - Save file notification
  - Cmd/Ctrl+P - Quick file search (placeholder)
  - Cmd/Ctrl+K - Command palette (placeholder)
  - Cmd/Ctrl+N - New project modal
  - Cmd/Ctrl+/ - Find in editor hint
  - Cross-platform support (Mac/Windows/Linux)
  - Integrated with PostHog analytics

 Enhanced Error Boundary (ErrorBoundary.tsx)
  - Better error UI with stack traces
  - Sentry integration for error reporting
  - Reload and retry options
  - User-friendly error messages
  - Replaced react-error-boundary with custom implementation

 Loading States Infrastructure (loading-spinner.tsx)
  - Reusable LoadingSpinner component (sm/md/lg sizes)
  - LoadingOverlay for full-screen loading
  - Accessible with ARIA labels
  - Ready for async operation improvements

Developer Experience:
- All keyboard shortcuts tracked via PostHog
- Better error debugging with component stack traces
- Auto-save functionality foundation

This commit significantly improves core functionality and sets foundation for:
- File search modal
- Command palette
- Enhanced async operation handling
2026-01-17 21:53:28 +00:00

39 lines
1,005 B
TypeScript

import { cn } from '@/lib/utils';
interface LoadingSpinnerProps {
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export function LoadingSpinner({ size = 'md', className }: LoadingSpinnerProps) {
const sizeClasses = {
sm: 'h-4 w-4 border-2',
md: 'h-8 w-8 border-2',
lg: 'h-12 w-12 border-3',
};
return (
<div
className={cn(
'animate-spin rounded-full border-accent border-t-transparent',
sizeClasses[size],
className
)}
role="status"
aria-label="Loading"
>
<span className="sr-only">Loading...</span>
</div>
);
}
export function LoadingOverlay({ message = 'Loading...' }: { message?: string }) {
return (
<div className="absolute inset-0 bg-background/80 backdrop-blur-sm flex items-center justify-center z-50">
<div className="flex flex-col items-center gap-4">
<LoadingSpinner size="lg" />
<p className="text-sm text-muted-foreground">{message}</p>
</div>
</div>
);
}