Add all-in-one desktop wallet with extensive feature set: Infrastructure: - Storage: IPFS-based decentralized file storage with upload/download - Hosting: Domain registration and static site hosting - Compute: GPU/CPU job marketplace for distributed computing - Database: Multi-model database services (KV, Document, Vector, etc.) Financial Features: - Privacy: Confidential transactions with Pedersen commitments - Bridge: Cross-chain transfers (Ethereum, Bitcoin, IBC/Cosmos) - Governance: DAO proposals, voting, and delegation - ZK-Rollup: L2 scaling with deposits, withdrawals, and transfers UI/UX Improvements: - Add ErrorBoundary component for graceful error handling - Add LoadingStates components (spinners, skeletons, overlays) - Add Animation components (FadeIn, SlideIn, CountUp, etc.) - Update navigation with new feature sections Testing: - Add Playwright E2E smoke tests - Test route accessibility and page rendering - Verify build process and asset loading Build: - Fix TypeScript compilation errors - Update Tauri plugin dependencies - Successfully build macOS app bundle and DMG
79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import { Component, ErrorInfo, ReactNode } from 'react';
|
|
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
|
|
|
interface Props {
|
|
children: ReactNode;
|
|
fallback?: ReactNode;
|
|
}
|
|
|
|
interface State {
|
|
hasError: boolean;
|
|
error?: Error;
|
|
}
|
|
|
|
/**
|
|
* Error Boundary component for graceful error handling
|
|
*
|
|
* Catches JavaScript errors anywhere in the child component tree
|
|
* and displays a fallback UI instead of crashing the whole app.
|
|
*/
|
|
export class ErrorBoundary extends Component<Props, State> {
|
|
public state: State = {
|
|
hasError: false,
|
|
};
|
|
|
|
public static getDerivedStateFromError(error: Error): State {
|
|
return { hasError: true, error };
|
|
}
|
|
|
|
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
console.error('Uncaught error:', error, errorInfo);
|
|
}
|
|
|
|
private handleReset = () => {
|
|
this.setState({ hasError: false, error: undefined });
|
|
};
|
|
|
|
public render() {
|
|
if (this.state.hasError) {
|
|
if (this.props.fallback) {
|
|
return this.props.fallback;
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col items-center justify-center min-h-[200px] p-8 bg-red-900/10 rounded-xl border border-red-800/50">
|
|
<AlertTriangle className="text-red-400 mb-4" size={48} />
|
|
<h2 className="text-xl font-semibold text-white mb-2">Something went wrong</h2>
|
|
<p className="text-gray-400 text-center mb-4 max-w-md">
|
|
{this.state.error?.message || 'An unexpected error occurred'}
|
|
</p>
|
|
<button
|
|
onClick={this.handleReset}
|
|
className="flex items-center gap-2 px-4 py-2 bg-red-600 hover:bg-red-700 rounded-lg text-white font-medium transition-colors"
|
|
>
|
|
<RefreshCw size={16} />
|
|
Try Again
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* HOC to wrap any component with error boundary
|
|
*/
|
|
export function withErrorBoundary<P extends object>(
|
|
WrappedComponent: React.ComponentType<P>,
|
|
fallback?: ReactNode
|
|
) {
|
|
return function WithErrorBoundary(props: P) {
|
|
return (
|
|
<ErrorBoundary fallback={fallback}>
|
|
<WrappedComponent {...props} />
|
|
</ErrorBoundary>
|
|
);
|
|
};
|
|
}
|