'use client'; /** * Version Panel Component * * Displays current version, checks for updates, and allows * updating and restarting the server. */ import { useState } from 'react'; import { useVersion, useForceCheckForUpdates, usePerformUpdate, useRestartServer, VersionInfo, } from '@/hooks/useMemories'; import { Button } from '@/components/ui/button'; type UpdateState = 'idle' | 'checking' | 'updating' | 'restarting' | 'success' | 'error'; export function VersionPanel() { const [updateState, setUpdateState] = useState('idle'); const [errorMessage, setErrorMessage] = useState(null); const [showRestartPrompt, setShowRestartPrompt] = useState(false); const [updateInfo, setUpdateInfo] = useState(null); const { data: versionData, isLoading: versionLoading } = useVersion(); const checkMutation = useForceCheckForUpdates(); const updateMutation = usePerformUpdate(); const restartMutation = useRestartServer(); const handleCheckUpdates = async () => { setUpdateState('checking'); setErrorMessage(null); try { const result = await checkMutation.mutateAsync(); setUpdateInfo(result); setUpdateState('idle'); } catch { setErrorMessage('Failed to check for updates'); setUpdateState('error'); } }; const handleUpdate = async () => { setUpdateState('updating'); setErrorMessage(null); try { const result = await updateMutation.mutateAsync(); if (result.success) { setUpdateState('success'); if (result.requiresRestart) { setShowRestartPrompt(true); } // Clear update info since we just updated setUpdateInfo(null); } else { setErrorMessage(result.error || 'Update failed'); setUpdateState('error'); } } catch (err) { setErrorMessage('Update failed: ' + (err as Error).message); setUpdateState('error'); } }; const handleRestart = async () => { if ( !confirm( 'This will restart the server. The page will need to be refreshed after restart. Continue?' ) ) { return; } setUpdateState('restarting'); try { await restartMutation.mutateAsync(); // Show message to refresh page - server will disconnect setErrorMessage(null); } catch { setErrorMessage('Failed to restart server'); setUpdateState('error'); } }; if (versionLoading) { return (
); } const hasUpdate = updateInfo?.updateAvailable; const currentVersion = versionData?.version || 'unknown'; const latestVersion = updateInfo?.latestVersion; return (
{/* Version Display */}
Version
v{currentVersion} {hasUpdate && ( Update available )}
{/* Update Info */} {updateInfo && latestVersion && currentVersion !== latestVersion && (
Latest: v{latestVersion} {updateInfo.cacheHit && (cached)}
)} {/* Error Message */} {errorMessage && (
{errorMessage}
)} {/* Success Message with Restart Prompt */} {updateState === 'success' && showRestartPrompt && (
Update complete! Restart the server to apply changes.
)} {/* Restarting Message */} {updateState === 'restarting' && (
Restarting server... Refresh the page in a few seconds.
)} {/* Action Buttons */}
{hasUpdate && ( )} {showRestartPrompt && ( )}
); }