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
107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { Card } from './ui/card';
|
|
import { AlertTriangle } from '@phosphor-icons/react';
|
|
import { captureError } from '../lib/sentry';
|
|
|
|
interface Props {
|
|
children: ReactNode;
|
|
fallback?: ReactNode;
|
|
}
|
|
|
|
interface State {
|
|
hasError: boolean;
|
|
error: Error | null;
|
|
errorInfo: ErrorInfo | null;
|
|
}
|
|
|
|
export class ErrorBoundary extends Component<Props, State> {
|
|
public state: State = {
|
|
hasError: false,
|
|
error: null,
|
|
errorInfo: null,
|
|
};
|
|
|
|
public static getDerivedStateFromError(error: Error): State {
|
|
return { hasError: true, error, errorInfo: null };
|
|
}
|
|
|
|
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
console.error('Uncaught error:', error, errorInfo);
|
|
|
|
this.setState({
|
|
error,
|
|
errorInfo,
|
|
});
|
|
|
|
// Report to Sentry
|
|
if (typeof captureError === 'function') {
|
|
captureError(error, { extra: { errorInfo } });
|
|
}
|
|
}
|
|
|
|
private handleReset = () => {
|
|
this.setState({ hasError: false, error: null, errorInfo: null });
|
|
window.location.reload();
|
|
};
|
|
|
|
private handleResetWithoutReload = () => {
|
|
this.setState({ hasError: false, error: null, errorInfo: null });
|
|
};
|
|
|
|
public render() {
|
|
if (this.state.hasError) {
|
|
if (this.props.fallback) {
|
|
return this.props.fallback;
|
|
}
|
|
|
|
return (
|
|
<div className="h-screen w-screen flex items-center justify-center bg-background p-4">
|
|
<Card className="max-w-2xl w-full p-8">
|
|
<div className="flex items-center gap-4 mb-6">
|
|
<AlertTriangle className="text-destructive" size={48} weight="fill" />
|
|
<div>
|
|
<h1 className="text-2xl font-bold">Something went wrong</h1>
|
|
<p className="text-muted-foreground mt-1">
|
|
An unexpected error occurred in the application
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{this.state.error && (
|
|
<div className="bg-muted p-4 rounded-lg mb-6 overflow-auto max-h-64">
|
|
<p className="font-mono text-sm text-destructive font-semibold mb-2">
|
|
{this.state.error.toString()}
|
|
</p>
|
|
{this.state.errorInfo && (
|
|
<pre className="font-mono text-xs text-muted-foreground whitespace-pre-wrap">
|
|
{this.state.errorInfo.componentStack}
|
|
</pre>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
<div className="flex gap-4">
|
|
<Button onClick={this.handleReset} className="flex-1">
|
|
Reload Application
|
|
</Button>
|
|
<Button
|
|
onClick={this.handleResetWithoutReload}
|
|
variant="outline"
|
|
className="flex-1"
|
|
>
|
|
Try Again
|
|
</Button>
|
|
</div>
|
|
|
|
<p className="text-xs text-muted-foreground mt-4 text-center">
|
|
If this problem persists, please report it to the development team
|
|
</p>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|