From c3907277632d0b5608942413bf2de255b29c9c44 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Fri, 16 Jan 2026 17:44:36 +0000 Subject: [PATCH] Generated by Spark: Fix all reported errors. --- src/App.tsx | 33 +++++---- src/components/PWAInstallPrompt.tsx | 100 ++++++++++++++-------------- src/components/PWAStatusBar.tsx | 4 +- src/components/PWAUpdatePrompt.tsx | 82 +++++++++++------------ src/components/atoms/StatusIcon.tsx | 6 +- src/hooks/use-auto-repair.ts | 13 ++-- src/hooks/use-keyboard-shortcuts.ts | 28 +++++--- src/hooks/use-pwa.ts | 26 +++++--- 8 files changed, 160 insertions(+), 132 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 6971890..5670176 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -191,7 +191,7 @@ function App() { const [nextjsConfig, setNextjsConfig] = useKV('project-nextjs-config', DEFAULT_NEXTJS_CONFIG) const [npmSettings, setNpmSettings] = useKV('project-npm-settings', DEFAULT_NPM_SETTINGS) const [featureToggles, setFeatureToggles] = useKV('project-feature-toggles', DEFAULT_FEATURE_TOGGLES) - const [activeFileId, setActiveFileId] = useState((files || [])[0]?.id || null) + const [activeFileId, setActiveFileId] = useState(null) const [activeTab, setActiveTab] = useState('dashboard') const [exportDialogOpen, setExportDialogOpen] = useState(false) const [shortcutsDialogOpen, setShortcutsDialogOpen] = useState(false) @@ -199,21 +199,27 @@ function App() { const [generatedCode, setGeneratedCode] = useState>({}) const [lastSaved, setLastSaved] = useState(Date.now()) - const safeFiles = files || [] - const safeModels = models || [] - const safeComponents = components || [] - const safeComponentTrees = componentTrees || [] - const safeWorkflows = workflows || [] - const safeLambdas = lambdas || [] - const safeTheme = (theme && theme.variants && theme.variants.length > 0) ? theme : DEFAULT_THEME - const safePlaywrightTests = playwrightTests || [] - const safeStorybookStories = storybookStories || [] - const safeUnitTests = unitTests || [] + const safeFiles = Array.isArray(files) ? files : [] + const safeModels = Array.isArray(models) ? models : [] + const safeComponents = Array.isArray(components) ? components : [] + const safeComponentTrees = Array.isArray(componentTrees) ? componentTrees : [] + const safeWorkflows = Array.isArray(workflows) ? workflows : [] + const safeLambdas = Array.isArray(lambdas) ? lambdas : [] + const safeTheme = (theme && theme.variants && Array.isArray(theme.variants) && theme.variants.length > 0) ? theme : DEFAULT_THEME + const safePlaywrightTests = Array.isArray(playwrightTests) ? playwrightTests : [] + const safeStorybookStories = Array.isArray(storybookStories) ? storybookStories : [] + const safeUnitTests = Array.isArray(unitTests) ? unitTests : [] const safeFlaskConfig = flaskConfig || DEFAULT_FLASK_CONFIG const safeNextjsConfig = nextjsConfig || DEFAULT_NEXTJS_CONFIG const safeNpmSettings = npmSettings || DEFAULT_NPM_SETTINGS const safeFeatureToggles = featureToggles || DEFAULT_FEATURE_TOGGLES + useEffect(() => { + if (safeFiles.length > 0 && !activeFileId) { + setActiveFileId(safeFiles[0].id) + } + }, [safeFiles, activeFileId]) + useEffect(() => { const params = new URLSearchParams(window.location.search) const shortcut = params.get('shortcut') @@ -253,7 +259,8 @@ function App() { featureToggles, ]) - const { errors: autoDetectedErrors } = useAutoRepair(safeFiles, false) + const { errors: autoDetectedErrors = [] } = useAutoRepair(safeFiles, false) + const errorCount = Array.isArray(autoDetectedErrors) ? autoDetectedErrors.length : 0 useKeyboardShortcuts([ { @@ -552,7 +559,7 @@ Navigate to the backend directory and follow the setup instructions. activeTab={activeTab} onTabChange={setActiveTab} featureToggles={safeFeatureToggles} - errorCount={autoDetectedErrors.length} + errorCount={errorCount} lastSaved={lastSaved} currentProject={getCurrentProject()} onProjectLoad={handleLoadProject} diff --git a/src/components/PWAInstallPrompt.tsx b/src/components/PWAInstallPrompt.tsx index fe2ec77..9080312 100644 --- a/src/components/PWAInstallPrompt.tsx +++ b/src/components/PWAInstallPrompt.tsx @@ -38,63 +38,61 @@ export function PWAInstallPrompt() { localStorage.setItem('pwa-install-dismissed', 'true') } - if (!isInstallable || dismissed || !showPrompt) { - return null - } - return ( - - -
-
-
- -
-
-
-
-

Install CodeForge

- -
-

- Install our app for a faster, offline-capable experience with quick access from your device. -

-
-
- - Works offline -
-
- - Quick access + {isInstallable && !dismissed && showPrompt && ( + + +
+
+
+
-
- - +
+
+

Install CodeForge

+ +
+

+ Install our app for a faster, offline-capable experience with quick access from your device. +

+
+
+ + Works offline +
+
+ + Quick access +
+
+
+ + +
-
-
-
+ + + )} ) } diff --git a/src/components/PWAStatusBar.tsx b/src/components/PWAStatusBar.tsx index 26d60d2..4544630 100644 --- a/src/components/PWAStatusBar.tsx +++ b/src/components/PWAStatusBar.tsx @@ -10,13 +10,13 @@ export function PWAStatusBar() { useEffect(() => { if (!isOnline) { setShowOffline(true) - } else { + } else if (showOffline) { const timer = setTimeout(() => { setShowOffline(false) }, 3000) return () => clearTimeout(timer) } - }, [isOnline]) + }, [isOnline, showOffline]) return ( diff --git a/src/components/PWAUpdatePrompt.tsx b/src/components/PWAUpdatePrompt.tsx index 71f85cb..82ac196 100644 --- a/src/components/PWAUpdatePrompt.tsx +++ b/src/components/PWAUpdatePrompt.tsx @@ -17,52 +17,50 @@ export function PWAUpdatePrompt() { setDismissed(true) } - if (!isUpdateAvailable || dismissed) { - return null - } - return ( - - -
-
-
- + {isUpdateAvailable && !dismissed && ( + + +
+
+
+ +
+
+
+
+

Update Available

+ +
+

+ A new version is ready. Update now for the latest features and fixes. +

+
+ + +
-
-
-

Update Available

- -
-

- A new version is ready. Update now for the latest features and fixes. -

-
- - -
-
-
- - + + + )} ) } diff --git a/src/components/atoms/StatusIcon.tsx b/src/components/atoms/StatusIcon.tsx index 402b91f..7b828e7 100644 --- a/src/components/atoms/StatusIcon.tsx +++ b/src/components/atoms/StatusIcon.tsx @@ -7,12 +7,16 @@ interface StatusIconProps { } export function StatusIcon({ type, size = 14, animate = false }: StatusIconProps) { + const baseClassName = type === 'saved' ? 'text-accent' : '' + const animateClassName = animate ? 'animate-in zoom-in duration-200' : '' + const className = [baseClassName, animateClassName].filter(Boolean).join(' ') + if (type === 'saved') { return ( ) } diff --git a/src/hooks/use-auto-repair.ts b/src/hooks/use-auto-repair.ts index 6d3e7db..a215e96 100644 --- a/src/hooks/use-auto-repair.ts +++ b/src/hooks/use-auto-repair.ts @@ -11,20 +11,25 @@ export function useAutoRepair( const [isScanning, setIsScanning] = useState(false) const scanFiles = useCallback(async () => { - if (!enabled || files.length === 0) return + if (!enabled || !files || files.length === 0) return setIsScanning(true) try { const allErrors: CodeError[] = [] for (const file of files) { - const fileErrors = await ErrorRepairService.detectErrors(file) - allErrors.push(...fileErrors) + if (file && file.content) { + const fileErrors = await ErrorRepairService.detectErrors(file) + if (Array.isArray(fileErrors)) { + allErrors.push(...fileErrors) + } + } } setErrors(allErrors) } catch (error) { console.error('Auto-scan failed:', error) + setErrors([]) } finally { setIsScanning(false) } @@ -41,7 +46,7 @@ export function useAutoRepair( }, [files, enabled, scanFiles]) return { - errors, + errors: Array.isArray(errors) ? errors : [], isScanning, scanFiles, } diff --git a/src/hooks/use-keyboard-shortcuts.ts b/src/hooks/use-keyboard-shortcuts.ts index e1f5c59..efe9e6c 100644 --- a/src/hooks/use-keyboard-shortcuts.ts +++ b/src/hooks/use-keyboard-shortcuts.ts @@ -11,18 +11,24 @@ interface KeyboardShortcut { export function useKeyboardShortcuts(shortcuts: KeyboardShortcut[]) { useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - for (const shortcut of shortcuts) { - const ctrlMatch = shortcut.ctrl ? (event.ctrlKey || event.metaKey) : !event.ctrlKey && !event.metaKey - const shiftMatch = shortcut.shift ? event.shiftKey : !event.shiftKey - const altMatch = shortcut.alt ? event.altKey : !event.altKey - const keyMatch = event.key.toLowerCase() === shortcut.key.toLowerCase() + if (typeof window === 'undefined') return - if (ctrlMatch && shiftMatch && altMatch && keyMatch) { - event.preventDefault() - shortcut.action() - break + const handleKeyDown = (event: KeyboardEvent) => { + try { + for (const shortcut of shortcuts) { + const ctrlMatch = shortcut.ctrl ? (event.ctrlKey || event.metaKey) : !event.ctrlKey && !event.metaKey + const shiftMatch = shortcut.shift ? event.shiftKey : !event.shiftKey + const altMatch = shortcut.alt ? event.altKey : !event.altKey + const keyMatch = event.key.toLowerCase() === shortcut.key.toLowerCase() + + if (ctrlMatch && shiftMatch && altMatch && keyMatch) { + event.preventDefault() + shortcut.action() + break + } } + } catch (error) { + console.error('[Keyboard Shortcuts] Error handling keydown:', error) } } @@ -35,7 +41,7 @@ export function getShortcutDisplay(shortcut: Omit): const parts: string[] = [] if (shortcut.ctrl) { - parts.push(navigator.platform.includes('Mac') ? '⌘' : 'Ctrl') + parts.push(typeof navigator !== 'undefined' && navigator.platform.includes('Mac') ? '⌘' : 'Ctrl') } if (shortcut.shift) { parts.push('Shift') diff --git a/src/hooks/use-pwa.ts b/src/hooks/use-pwa.ts index a6dd7cc..ae12489 100644 --- a/src/hooks/use-pwa.ts +++ b/src/hooks/use-pwa.ts @@ -17,26 +17,36 @@ export function usePWA() { const [state, setState] = useState({ isInstallable: false, isInstalled: false, - isOnline: navigator.onLine, + isOnline: typeof navigator !== 'undefined' ? navigator.onLine : true, isUpdateAvailable: false, registration: null, }) const [deferredPrompt, setDeferredPrompt] = useState(null) useEffect(() => { + if (typeof window === 'undefined') return + const checkInstalled = () => { - const isStandalone = window.matchMedia('(display-mode: standalone)').matches - const isIOSStandalone = (window.navigator as any).standalone === true - setState(prev => ({ ...prev, isInstalled: isStandalone || isIOSStandalone })) + try { + const isStandalone = window.matchMedia && window.matchMedia('(display-mode: standalone)').matches + const isIOSStandalone = (window.navigator as any).standalone === true + setState(prev => ({ ...prev, isInstalled: isStandalone || isIOSStandalone })) + } catch (error) { + console.error('[PWA] Error checking install status:', error) + } } checkInstalled() const handleBeforeInstallPrompt = (e: Event) => { - e.preventDefault() - const installEvent = e as BeforeInstallPromptEvent - setDeferredPrompt(installEvent) - setState(prev => ({ ...prev, isInstallable: true })) + try { + e.preventDefault() + const installEvent = e as BeforeInstallPromptEvent + setDeferredPrompt(installEvent) + setState(prev => ({ ...prev, isInstallable: true })) + } catch (error) { + console.error('[PWA] Error handling beforeinstallprompt:', error) + } } const handleAppInstalled = () => {