import { useState } from "react"; import { useTranslation } from "react-i18next"; import { authenticatedFetch } from "../../utils/api"; import { ReleaseInfo } from "../../types/sharedTypes"; interface VersionUpgradeModalProps { isOpen: boolean; onClose: () => void; releaseInfo: ReleaseInfo | null; currentVersion: string; latestVersion: string | null; } export default function VersionUpgradeModal({ isOpen, onClose, releaseInfo, currentVersion, latestVersion }: VersionUpgradeModalProps) { const { t } = useTranslation('common'); const [isUpdating, setIsUpdating] = useState(false); const [updateOutput, setUpdateOutput] = useState(''); const [updateError, setUpdateError] = useState(''); if (!isOpen) return null; const handleUpdateNow = async () => { setIsUpdating(true); setUpdateOutput('Starting update...\n'); setUpdateError(''); try { // Call the backend API to run the update command const response = await authenticatedFetch('/api/system/update', { method: 'POST', }); const data = await response.json(); if (response.ok) { setUpdateOutput(prev => prev + data.output + '\n'); setUpdateOutput(prev => prev + '\n✅ Update completed successfully!\n'); setUpdateOutput(prev => prev + 'Please restart the server to apply changes.\n'); } else { setUpdateError(data.error || 'Update failed'); setUpdateOutput(prev => prev + '\n❌ Update failed: ' + (data.error || 'Unknown error') + '\n'); } } catch (error: any) { setUpdateError(error.message); setUpdateOutput(prev => prev + '\n❌ Update failed: ' + error.message + '\n'); } finally { setIsUpdating(false); } }; return (
{/* Backdrop */}
{/* Version Info */}
{t('versionUpdate.currentVersion')} {currentVersion}
{t('versionUpdate.latestVersion')} {latestVersion}
{/* Changelog */} {releaseInfo?.body && (

{t('versionUpdate.whatsNew')}

{releaseInfo?.htmlUrl && ( {t('versionUpdate.viewFullRelease')} )}
{cleanChangelog(releaseInfo.body)}
)} {/* Update Output */} {updateOutput && (

{t('versionUpdate.updateProgress')}

{updateOutput}
)} {/* Upgrade Instructions */} {!isUpdating && !updateOutput && (

{t('versionUpdate.manualUpgrade')}

git checkout main && git pull && npm install

{t('versionUpdate.manualUpgradeHint')}

)} {/* Actions */}
{!updateOutput && ( <> )}
); }; // Clean up changelog by removing GitHub-specific metadata const cleanChangelog = (body: string) => { if (!body) return ''; return body // Remove full commit hashes (40 character hex strings) .replace(/\b[0-9a-f]{40}\b/gi, '') // Remove short commit hashes (7-10 character hex strings at start of line or after dash/space) .replace(/(?:^|\s|-)([0-9a-f]{7,10})\b/gi, '') // Remove "Full Changelog" links .replace(/\*\*Full Changelog\*\*:.*$/gim, '') // Remove compare links (e.g., https://github.com/.../compare/v1.0.0...v1.0.1) .replace(/https?:\/\/github\.com\/[^\/]+\/[^\/]+\/compare\/[^\s)]+/gi, '') // Clean up multiple consecutive empty lines .replace(/\n\s*\n\s*\n/g, '\n\n') // Trim whitespace .trim(); };