'use client'; import { useState, useRef, useEffect } from 'react'; import { api } from '~/trpc/react'; import { Button } from './ui/button'; import { ContextualHelpIcon } from './ContextualHelpIcon'; export function ResyncButton() { const [isResyncing, setIsResyncing] = useState(false); const [lastSync, setLastSync] = useState(null); const [syncMessage, setSyncMessage] = useState(null); const hasReloadedRef = useRef(false); const isUserInitiatedRef = useRef(false); const reloadTimeoutRef = useRef(null); const messageTimeoutRef = useRef(null); const resyncMutation = api.scripts.resyncScripts.useMutation({ onSuccess: (data) => { setIsResyncing(false); setLastSync(new Date()); if (data.success) { setSyncMessage(data.message ?? 'Scripts synced successfully'); // Only reload if this was triggered by user action if (isUserInitiatedRef.current && !hasReloadedRef.current) { hasReloadedRef.current = true; // Clear any existing reload timeout if (reloadTimeoutRef.current) { clearTimeout(reloadTimeoutRef.current); reloadTimeoutRef.current = null; } // Set new reload timeout reloadTimeoutRef.current = setTimeout(() => { reloadTimeoutRef.current = null; window.location.reload(); }, 2000); // Wait 2 seconds to show the success message } else { // Reset flag if reload didn't happen isUserInitiatedRef.current = false; } } else { setSyncMessage(data.error ?? 'Failed to sync scripts'); // Clear message after 3 seconds for errors if (messageTimeoutRef.current) { clearTimeout(messageTimeoutRef.current); } messageTimeoutRef.current = setTimeout(() => { setSyncMessage(null); messageTimeoutRef.current = null; }, 3000); isUserInitiatedRef.current = false; } }, onError: (error) => { setIsResyncing(false); setSyncMessage(`Error: ${error.message}`); if (messageTimeoutRef.current) { clearTimeout(messageTimeoutRef.current); } messageTimeoutRef.current = setTimeout(() => { setSyncMessage(null); messageTimeoutRef.current = null; }, 3000); isUserInitiatedRef.current = false; }, }); const handleResync = async () => { // Prevent multiple simultaneous sync operations if (isResyncing) return; // Clear any pending reload timeout if (reloadTimeoutRef.current) { clearTimeout(reloadTimeoutRef.current); reloadTimeoutRef.current = null; } // Mark as user-initiated before starting isUserInitiatedRef.current = true; hasReloadedRef.current = false; setIsResyncing(true); setSyncMessage(null); resyncMutation.mutate(); }; // Cleanup on unmount - clear any pending timeouts useEffect(() => { return () => { if (reloadTimeoutRef.current) { clearTimeout(reloadTimeoutRef.current); reloadTimeoutRef.current = null; } if (messageTimeoutRef.current) { clearTimeout(messageTimeoutRef.current); messageTimeoutRef.current = null; } // Reset refs on unmount hasReloadedRef.current = false; isUserInitiatedRef.current = false; }; }, []); return (
Sync scripts with configured repositories
{lastSync && (
Last sync: {lastSync.toLocaleTimeString()}
)}
{syncMessage && (
{syncMessage}
)}
); }