Skip to content

Commit e3af248

Browse files
committed
Merge main into bugfixing_bumps - keep bugfixing_bumps versions (Prisma 7, tsx support)
2 parents 43bafb6 + 7833d5d commit e3af248

11 files changed

Lines changed: 334 additions & 99 deletions

File tree

next.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ const config = {
5353
}
5454
return config;
5555
},
56-
// Ignore TypeScript errors during build (they can be fixed separately)
56+
// TypeScript errors will fail the build
5757
typescript: {
58-
ignoreBuildErrors: true,
58+
ignoreBuildErrors: false,
5959
},
6060
};
6161

src/app/_components/LXCSettingsModal.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useEffect } from 'react';
3+
import { useState, useEffect, startTransition } from 'react';
44
import { api } from '~/trpc/react';
55
import { Button } from './ui/button';
66
import { Input } from './ui/input';
@@ -159,9 +159,13 @@ export function LXCSettingsModal({ isOpen, script, onClose, onSave: _onSave }: L
159159
useEffect(() => {
160160
if (configData?.success) {
161161
populateFormData(configData);
162-
setHasChanges(false);
162+
startTransition(() => {
163+
setHasChanges(false);
164+
});
163165
} else if (configData && !configData.success) {
164-
setError(String(configData.error ?? 'Failed to load configuration'));
166+
startTransition(() => {
167+
setError(String(configData.error ?? 'Failed to load configuration'));
168+
});
165169
}
166170
}, [configData]);
167171

src/app/_components/ReleaseNotesModal.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useEffect } from 'react';
3+
import { useState, useEffect, startTransition } from 'react';
44
import { api } from '~/trpc/react';
55
import { Button } from './ui/button';
66
import { Badge } from './ui/badge';
@@ -47,7 +47,9 @@ export function ReleaseNotesModal({ isOpen, onClose, highlightVersion }: Release
4747
// Get current version when modal opens
4848
useEffect(() => {
4949
if (isOpen && versionData?.success && versionData.version) {
50-
setCurrentVersion(versionData.version);
50+
startTransition(() => {
51+
setCurrentVersion(versionData.version);
52+
});
5153
}
5254
}, [isOpen, versionData]);
5355

src/app/_components/ResyncButton.tsx

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useRef } from 'react';
3+
import { useState, useRef, useEffect } from 'react';
44
import { api } from '~/trpc/react';
55
import { Button } from './ui/button';
66
import { ContextualHelpIcon } from './ContextualHelpIcon';
@@ -11,6 +11,8 @@ export function ResyncButton() {
1111
const [syncMessage, setSyncMessage] = useState<string | null>(null);
1212
const hasReloadedRef = useRef<boolean>(false);
1313
const isUserInitiatedRef = useRef<boolean>(false);
14+
const reloadTimeoutRef = useRef<NodeJS.Timeout | null>(null);
15+
const messageTimeoutRef = useRef<NodeJS.Timeout | null>(null);
1416

1517
const resyncMutation = api.scripts.resyncScripts.useMutation({
1618
onSuccess: (data) => {
@@ -21,7 +23,16 @@ export function ResyncButton() {
2123
// Only reload if this was triggered by user action
2224
if (isUserInitiatedRef.current && !hasReloadedRef.current) {
2325
hasReloadedRef.current = true;
24-
setTimeout(() => {
26+
27+
// Clear any existing reload timeout
28+
if (reloadTimeoutRef.current) {
29+
clearTimeout(reloadTimeoutRef.current);
30+
reloadTimeoutRef.current = null;
31+
}
32+
33+
// Set new reload timeout
34+
reloadTimeoutRef.current = setTimeout(() => {
35+
reloadTimeoutRef.current = null;
2536
window.location.reload();
2637
}, 2000); // Wait 2 seconds to show the success message
2738
} else {
@@ -31,14 +42,26 @@ export function ResyncButton() {
3142
} else {
3243
setSyncMessage(data.error ?? 'Failed to sync scripts');
3344
// Clear message after 3 seconds for errors
34-
setTimeout(() => setSyncMessage(null), 3000);
45+
if (messageTimeoutRef.current) {
46+
clearTimeout(messageTimeoutRef.current);
47+
}
48+
messageTimeoutRef.current = setTimeout(() => {
49+
setSyncMessage(null);
50+
messageTimeoutRef.current = null;
51+
}, 3000);
3552
isUserInitiatedRef.current = false;
3653
}
3754
},
3855
onError: (error) => {
3956
setIsResyncing(false);
4057
setSyncMessage(`Error: ${error.message}`);
41-
setTimeout(() => setSyncMessage(null), 3000);
58+
if (messageTimeoutRef.current) {
59+
clearTimeout(messageTimeoutRef.current);
60+
}
61+
messageTimeoutRef.current = setTimeout(() => {
62+
setSyncMessage(null);
63+
messageTimeoutRef.current = null;
64+
}, 3000);
4265
isUserInitiatedRef.current = false;
4366
},
4467
});
@@ -47,6 +70,12 @@ export function ResyncButton() {
4770
// Prevent multiple simultaneous sync operations
4871
if (isResyncing) return;
4972

73+
// Clear any pending reload timeout
74+
if (reloadTimeoutRef.current) {
75+
clearTimeout(reloadTimeoutRef.current);
76+
reloadTimeoutRef.current = null;
77+
}
78+
5079
// Mark as user-initiated before starting
5180
isUserInitiatedRef.current = true;
5281
hasReloadedRef.current = false;
@@ -55,6 +84,23 @@ export function ResyncButton() {
5584
resyncMutation.mutate();
5685
};
5786

87+
// Cleanup on unmount - clear any pending timeouts
88+
useEffect(() => {
89+
return () => {
90+
if (reloadTimeoutRef.current) {
91+
clearTimeout(reloadTimeoutRef.current);
92+
reloadTimeoutRef.current = null;
93+
}
94+
if (messageTimeoutRef.current) {
95+
clearTimeout(messageTimeoutRef.current);
96+
messageTimeoutRef.current = null;
97+
}
98+
// Reset refs on unmount
99+
hasReloadedRef.current = false;
100+
isUserInitiatedRef.current = false;
101+
};
102+
}, []);
103+
58104
return (
59105
<div className="flex flex-col sm:flex-row sm:items-center gap-3">
60106
<div className="text-sm text-muted-foreground font-medium">

src/app/_components/ThemeProvider.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { createContext, useContext, useEffect, useState } from 'react';
3+
import { createContext, useContext, useEffect, useState, startTransition } from 'react';
44

55
type Theme = 'light' | 'dark';
66

@@ -31,9 +31,13 @@ export function ThemeProvider({ children }: ThemeProviderProps) {
3131
useEffect(() => {
3232
const savedTheme = localStorage.getItem('theme') as Theme;
3333
if (savedTheme && (savedTheme === 'light' || savedTheme === 'dark')) {
34-
setThemeState(savedTheme);
34+
startTransition(() => {
35+
setThemeState(savedTheme);
36+
});
3537
}
36-
setMounted(true);
38+
startTransition(() => {
39+
setMounted(true);
40+
});
3741
}, []);
3842

3943
// Apply theme to document element

0 commit comments

Comments
 (0)