diff --git a/app/components/ActivityFeed.tsx b/app/components/ActivityFeed.tsx index b49694c..a8653b3 100644 --- a/app/components/ActivityFeed.tsx +++ b/app/components/ActivityFeed.tsx @@ -77,42 +77,85 @@ export default function ActivityFeed() { // Fetch data every 30 seconds (optimized to match server cache) useEffect(() => { - // Don't fetch if tracking is disabled - if (!isTrackingEnabled) { + // Don't fetch if tracking is disabled or during SSR + if (!isTrackingEnabled || typeof window === 'undefined') { return; } const fetchData = async () => { try { + // Check if fetch is available (should be, but safety check) + if (typeof fetch === 'undefined') { + return; + } + // Add timestamp to prevent aggressive caching but respect server cache const res = await fetch("/api/n8n/status", { cache: "default", + }).catch((fetchError) => { + // Handle network errors gracefully + if (process.env.NODE_ENV === 'development') { + console.warn('ActivityFeed: Fetch failed:', fetchError); + } + return null; }); - if (!res.ok) return; - let json = await res.json(); + + if (!res || !res.ok) { + if (process.env.NODE_ENV === 'development' && res) { + console.warn('ActivityFeed: API returned non-OK status:', res.status); + } + return; + } + + let json: unknown; + try { + json = await res.json(); + } catch (parseError) { + if (process.env.NODE_ENV === 'development') { + console.warn('ActivityFeed: Failed to parse JSON response:', parseError); + } + return; + } - console.log("ActivityFeed data (raw):", json); + if (process.env.NODE_ENV === 'development') { + console.log("ActivityFeed data (raw):", json); + } // Handle array response if API returns it wrapped if (Array.isArray(json)) { json = json[0] || null; } - console.log("ActivityFeed data (processed):", json); + if (process.env.NODE_ENV === 'development') { + console.log("ActivityFeed data (processed):", json); + } - setData(json); + if (!json || typeof json !== 'object') { + return; + } + + // Type assertion - API should return StatusData format + const activityData = json as StatusData; + setData(activityData); // Check if there's any active activity - const hasActiveActivity = - json.coding?.isActive || - json.gaming?.isPlaying || - json.music?.isPlaying; + const coding = activityData.coding; + const gaming = activityData.gaming; + const music = activityData.music; + + const hasActiveActivity = Boolean( + coding?.isActive || + gaming?.isPlaying || + music?.isPlaying + ); - console.log("Has activity:", hasActiveActivity, { - coding: json.coding?.isActive, - gaming: json.gaming?.isPlaying, - music: json.music?.isPlaying, - }); + if (process.env.NODE_ENV === 'development') { + console.log("Has activity:", hasActiveActivity, { + coding: coding?.isActive, + gaming: gaming?.isPlaying, + music: music?.isPlaying, + }); + } setHasActivity(hasActiveActivity); @@ -120,8 +163,12 @@ export default function ActivityFeed() { if (hasActiveActivity && !isMinimized) { setIsExpanded(true); } - } catch (e) { - console.error("Failed to fetch activity", e); + } catch (error) { + // Silently fail - activity feed is not critical + if (process.env.NODE_ENV === 'development') { + console.error("Failed to fetch activity:", error); + } + // Don't set error state - just fail silently } };