UNPKG

gebeya-dala-error-fixer

Version:

Automatic runtime error detection and fix suggestions for Next.js applications with config-based setup

98 lines (97 loc) 4.51 kB
'use client'; import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useCallback, useEffect } from 'react'; import { ErrorDetector } from './ErrorDetector'; import { ErrorModal } from './ErrorModal'; import { ErrorBoundary } from './ErrorBoundary'; export const ErrorFixerProvider = ({ children, enabled = true, autoShow = true, position = 'top-right' }) => { const [currentError, setCurrentError] = useState(null); const [currentSuggestion, setCurrentSuggestion] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [errorDetector, setErrorDetector] = useState(null); const [errorCount, setErrorCount] = useState(0); const handleError = useCallback((error, suggestion) => { console.log('Error detected:', error); setCurrentError(error); setCurrentSuggestion(suggestion); setErrorCount(prev => prev + 1); if (autoShow) { setIsModalOpen(true); } }, [autoShow]); const closeModal = useCallback(() => { setIsModalOpen(false); }, []); const openModal = useCallback(() => { setIsModalOpen(true); }, []); useEffect(() => { if (enabled && typeof window !== 'undefined') { const detector = new ErrorDetector(handleError); setErrorDetector(detector); return () => { detector.destroy(); }; } }, [enabled, handleError]); // Don't render anything if disabled or on server if (!enabled || typeof window === 'undefined') { return _jsx(_Fragment, { children: children }); } const getFloatingButtonPosition = () => { const base = { position: 'fixed', zIndex: 9998, width: '50px', height: '50px', borderRadius: '50%', backgroundColor: errorCount > 0 ? '#ef4444' : '#333', border: '2px solid #555', color: '#fff', fontSize: '18px', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)', transition: 'all 0.2s ease', fontFamily: 'system-ui, -apple-system, sans-serif' }; switch (position) { case 'top-right': return { ...base, top: '20px', right: '20px' }; case 'top-left': return { ...base, top: '20px', left: '20px' }; case 'bottom-right': return { ...base, bottom: '20px', right: '20px' }; case 'bottom-left': return { ...base, bottom: '20px', left: '20px' }; default: return { ...base, top: '20px', right: '20px' }; } }; return (_jsxs(ErrorBoundary, { onError: handleError, children: [children, _jsxs("button", { onClick: openModal, style: getFloatingButtonPosition(), title: errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''} detected` : 'No errors', children: [errorCount > 0 ? '!' : '✓', errorCount > 0 && (_jsx("div", { style: { position: 'absolute', top: '-8px', right: '-8px', backgroundColor: '#dc2626', color: '#fff', borderRadius: '50%', width: '20px', height: '20px', fontSize: '12px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 'bold' }, children: errorCount > 99 ? '99+' : errorCount }))] }), _jsx(ErrorModal, { isOpen: isModalOpen, error: currentError, suggestion: currentSuggestion, onClose: closeModal, fixItEnabled: true, onFixIt: (error, suggestion) => { // Default fix it action - copy code to clipboard if (suggestion.code) { navigator.clipboard.writeText(suggestion.code); alert('Code copied to clipboard! Apply the fix to your code.'); } else { alert('Please follow the suggested actions to fix this error.'); } } })] })); };