Reverted to commit db532afcef

This commit is contained in:
gpt-engineer-app[bot]
2025-10-11 14:37:17 +00:00
parent be265632ad
commit 1e30dedca2
4 changed files with 69 additions and 7 deletions

View File

@@ -44,12 +44,20 @@ import BlogIndex from "./pages/BlogIndex";
import BlogPost from "./pages/BlogPost"; import BlogPost from "./pages/BlogPost";
import AdminBlog from "./pages/AdminBlog"; import AdminBlog from "./pages/AdminBlog";
const queryClient = new QueryClient(); const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false, // Don't refetch when switching back to tab
refetchOnMount: true, // Still refetch on component mount
refetchOnReconnect: true, // Refetch when internet reconnects
staleTime: 60000, // Consider data fresh for 60 seconds
},
},
});
function AppContent() { function AppContent() {
return ( return (
<TooltipProvider> <TooltipProvider>
<LocationAutoDetectProvider />
<BrowserRouter <BrowserRouter
future={{ future={{
v7_startTransition: true, v7_startTransition: true,
@@ -110,7 +118,9 @@ function AppContent() {
const App = () => ( const App = () => (
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<AuthProvider> <AuthProvider>
<AppContent /> <LocationAutoDetectProvider>
<AppContent />
</LocationAutoDetectProvider>
</AuthProvider> </AuthProvider>
</QueryClientProvider> </QueryClientProvider>
); );

View File

@@ -130,6 +130,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const isMountingRef = useRef(true); const isMountingRef = useRef(true);
const initialFetchCompleteRef = useRef(false); const initialFetchCompleteRef = useRef(false);
const FETCH_COOLDOWN_MS = 1000; const FETCH_COOLDOWN_MS = 1000;
const isPageVisible = useRef(true);
// Pagination state // Pagination state
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
@@ -212,8 +213,34 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
} }
}, [loadingState, items.length, hasRenderedOnce]); }, [loadingState, items.length, hasRenderedOnce]);
// Track page visibility to prevent tab-switch refreshes
useEffect(() => {
const handleVisibilityChange = () => {
const wasHidden = !isPageVisible.current;
isPageVisible.current = !document.hidden;
if (wasHidden && isPageVisible.current) {
console.log('📄 Page became visible - NOT auto-refreshing queue');
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, []);
const fetchItems = useCallback(async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending', silent = false, tab: QueueTab = 'mainQueue') => { const fetchItems = useCallback(async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending', silent = false, tab: QueueTab = 'mainQueue') => {
console.log('🔍 fetchItems called:', {
hasUser: !!userRef.current,
entityFilter,
statusFilter,
silent,
tab,
loadingState,
timestamp: new Date().toISOString()
});
if (!userRef.current) { if (!userRef.current) {
console.warn('⚠️ fetchItems: No user available yet, cannot fetch');
return; return;
} }
@@ -223,6 +250,12 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
return; return;
} }
// Skip fetch if triggered during tab visibility change (unless manual refresh)
if (!silent && !isPageVisible.current) {
console.log('👁️ Skipping fetch while page is hidden');
return;
}
// Cooldown check - prevent rapid-fire calls // Cooldown check - prevent rapid-fire calls
const now = Date.now(); const now = Date.now();
const timeSinceLastFetch = now - lastFetchTimeRef.current; const timeSinceLastFetch = now - lastFetchTimeRef.current;
@@ -740,15 +773,28 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
// Initial fetch on mount and filter changes // Initial fetch on mount and filter changes
useEffect(() => { useEffect(() => {
if (!user) return; console.log('🎯 Initial fetch effect:', {
hasUser: !!user,
loadingState,
hasInitialFetchRef: hasInitialFetchRef.current,
initialFetchComplete: initialFetchCompleteRef.current,
isMounting: isMountingRef.current
});
if (!user) {
console.log('⏳ Waiting for user to be available...');
return;
}
// Phase 1: Initial fetch (run once) // Phase 1: Initial fetch (run once)
if (!hasInitialFetchRef.current) { if (!hasInitialFetchRef.current) {
console.log('✅ Triggering initial fetch');
hasInitialFetchRef.current = true; hasInitialFetchRef.current = true;
isMountingRef.current = true; isMountingRef.current = true;
fetchItems(debouncedEntityFilter, debouncedStatusFilter, false) fetchItems(debouncedEntityFilter, debouncedStatusFilter, false)
.then(() => { .then(() => {
console.log('✅ Initial fetch complete');
initialFetchCompleteRef.current = true; initialFetchCompleteRef.current = true;
// Wait for DOM to paint before allowing subsequent fetches // Wait for DOM to paint before allowing subsequent fetches
requestAnimationFrame(() => { requestAnimationFrame(() => {
@@ -760,6 +806,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
// Phase 2: Filter changes (only after initial fetch completes) // Phase 2: Filter changes (only after initial fetch completes)
if (!isMountingRef.current && initialFetchCompleteRef.current) { if (!isMountingRef.current && initialFetchCompleteRef.current) {
console.log('🔄 Filter changed, fetching with debounce');
debouncedFetchItems(debouncedEntityFilter, debouncedStatusFilter, true, activeTab); debouncedFetchItems(debouncedEntityFilter, debouncedStatusFilter, true, activeTab);
} }
}, [debouncedEntityFilter, debouncedStatusFilter, user, activeTab, fetchItems, debouncedFetchItems]); }, [debouncedEntityFilter, debouncedStatusFilter, user, activeTab, fetchItems, debouncedFetchItems]);

View File

@@ -1,7 +1,11 @@
import { useEffect } from 'react'; import { ReactNode } from 'react';
import { useLocationAutoDetect } from '@/hooks/useLocationAutoDetect'; import { useLocationAutoDetect } from '@/hooks/useLocationAutoDetect';
export function LocationAutoDetectProvider() { interface LocationAutoDetectProviderProps {
useLocationAutoDetect(); children?: ReactNode;
return null; // This component doesn't render anything, just runs the hook }
export function LocationAutoDetectProvider({ children }: LocationAutoDetectProviderProps) {
useLocationAutoDetect();
return <>{children}</>;
} }

View File

@@ -109,6 +109,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
} else { } else {
setSession(session); setSession(session);
setUser(session?.user ?? null); setUser(session?.user ?? null);
setLoading(false);
} }
// Track pending email changes // Track pending email changes