Skip to content

Commit 7816a42

Browse files
committed
🔧 Fix build errors and SSR issues
- Fix updateManager.ts to prevent localStorage/document access during SSR - Add client-side checks for all browser-only APIs - Fix missing GripVertical import in admin dashboard - Ensure emergency read optimizer works in server environment - Build now passes successfully with no critical errors All database read optimizations and app update modal fixes are working correctly.
1 parent 0d6ba3f commit 7816a42

3 files changed

Lines changed: 54 additions & 25 deletions

File tree

app/admin/dashboard/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import './dashboard.css';
55
import { useRouter } from 'next/navigation';
66
import { useAuth } from '../../providers/AuthProvider';
77
import { Button } from '../../components/ui/button';
8-
import { ChevronLeft, Filter } from 'lucide-react';
8+
import { ChevronLeft, Filter, GripVertical } from 'lucide-react';
99
import { isAdmin } from "../../utils/isAdmin";
1010
import { DndProvider, useDrag, useDrop } from 'react-dnd';
1111
import { HTML5Backend } from 'react-dnd-html5-backend';

app/utils/emergencyReadOptimizer.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,13 @@ class EmergencyReadOptimizer {
215215
// Example: Increase polling intervals or disable certain polls
216216
if (typeof window !== 'undefined') {
217217
// Client-side polling adjustments
218-
window.dispatchEvent(new CustomEvent('emergency-optimization', {
219-
detail: { action: 'disable-polling' }
220-
}));
218+
try {
219+
window.dispatchEvent(new CustomEvent('emergency-optimization', {
220+
detail: { action: 'disable-polling' }
221+
}));
222+
} catch (error) {
223+
console.warn('Failed to dispatch emergency optimization event:', error);
224+
}
221225
}
222226
}
223227

app/utils/updateManager.ts

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ class UpdateManager {
1919
private listeners = new Set<(hasUpdate: boolean) => void>();
2020

2121
private constructor() {
22-
this.loadFromStorage();
23-
this.detectCurrentBuild();
22+
// Only initialize on client-side
23+
if (typeof window !== 'undefined') {
24+
this.loadFromStorage();
25+
this.detectCurrentBuild();
26+
}
2427
}
2528

2629
static getInstance(): UpdateManager {
@@ -34,6 +37,9 @@ class UpdateManager {
3437
* Detect current build ID from various sources
3538
*/
3639
private detectCurrentBuild(): void {
40+
// Only run on client-side
41+
if (typeof window === 'undefined') return;
42+
3743
// Try to get build ID from meta tag
3844
const metaBuildId = document.querySelector('meta[name="build-id"]')?.getAttribute('content');
3945
if (metaBuildId) {
@@ -57,6 +63,9 @@ class UpdateManager {
5763
* Load update states from localStorage
5864
*/
5965
private loadFromStorage(): void {
66+
// Only run on client-side
67+
if (typeof window === 'undefined') return;
68+
6069
try {
6170
const stored = localStorage.getItem('updateStates');
6271
if (stored) {
@@ -72,6 +81,9 @@ class UpdateManager {
7281
* Save update states to localStorage
7382
*/
7483
private saveToStorage(): void {
84+
// Only run on client-side
85+
if (typeof window === 'undefined') return;
86+
7587
try {
7688
const states = Object.fromEntries(this.updateStates.entries());
7789
localStorage.setItem('updateStates', JSON.stringify(states));
@@ -137,9 +149,11 @@ class UpdateManager {
137149
this.updateStates.set(buildId, state);
138150
this.saveToStorage();
139151

140-
// Also set legacy dismissal keys for backward compatibility
141-
localStorage.setItem(`updateDismissed_${buildId}`, Date.now().toString());
142-
localStorage.setItem('updateDismissedAt', Date.now().toString());
152+
// Also set legacy dismissal keys for backward compatibility (client-side only)
153+
if (typeof window !== 'undefined') {
154+
localStorage.setItem(`updateDismissed_${buildId}`, Date.now().toString());
155+
localStorage.setItem('updateDismissedAt', Date.now().toString());
156+
}
143157

144158
console.log('🔕 Update dismissed for build:', buildId);
145159

@@ -154,7 +168,12 @@ class UpdateManager {
154168
// Clear the update state since it's been applied
155169
this.updateStates.delete(buildId);
156170
this.currentBuildId = buildId;
157-
localStorage.setItem('currentBuildId', buildId);
171+
172+
// Only update localStorage on client-side
173+
if (typeof window !== 'undefined') {
174+
localStorage.setItem('currentBuildId', buildId);
175+
}
176+
158177
this.saveToStorage();
159178

160179
console.log('✅ Update applied for build:', buildId);
@@ -174,13 +193,15 @@ class UpdateManager {
174193
// Don't show if already dismissed or shown
175194
if (state?.dismissed || state?.shown) return false;
176195

177-
// Check if recently dismissed (within 1 hour)
178-
const dismissedAt = localStorage.getItem('updateDismissedAt');
179-
if (dismissedAt) {
180-
const dismissedTime = parseInt(dismissedAt);
181-
const oneHour = 60 * 60 * 1000;
182-
if (Date.now() - dismissedTime < oneHour) {
183-
return false;
196+
// Check if recently dismissed (within 1 hour) - client-side only
197+
if (typeof window !== 'undefined') {
198+
const dismissedAt = localStorage.getItem('updateDismissedAt');
199+
if (dismissedAt) {
200+
const dismissedTime = parseInt(dismissedAt);
201+
const oneHour = 60 * 60 * 1000;
202+
if (Date.now() - dismissedTime < oneHour) {
203+
return false;
204+
}
184205
}
185206
}
186207

@@ -248,14 +269,18 @@ class UpdateManager {
248269
*/
249270
reset(): void {
250271
this.updateStates.clear();
251-
localStorage.removeItem('updateStates');
252-
localStorage.removeItem('updateDismissedAt');
253-
254-
// Clear all build-specific dismissals
255-
for (let i = 0; i < localStorage.length; i++) {
256-
const key = localStorage.key(i);
257-
if (key?.startsWith('updateDismissed_')) {
258-
localStorage.removeItem(key);
272+
273+
// Only clear localStorage on client-side
274+
if (typeof window !== 'undefined') {
275+
localStorage.removeItem('updateStates');
276+
localStorage.removeItem('updateDismissedAt');
277+
278+
// Clear all build-specific dismissals
279+
for (let i = 0; i < localStorage.length; i++) {
280+
const key = localStorage.key(i);
281+
if (key?.startsWith('updateDismissed_')) {
282+
localStorage.removeItem(key);
283+
}
259284
}
260285
}
261286

0 commit comments

Comments
 (0)