'use client'; import { getVersion, restartSystem } from '@/services/admin/tool'; import { formatDate } from '@/utils/common'; import { useQuery } from '@tanstack/react-query'; import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '@workspace/ui/components/alert-dialog'; import { Badge } from '@workspace/ui/components/badge'; import { Button } from '@workspace/ui/components/button'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Icon } from '@workspace/ui/custom-components/icon'; import { useTranslations } from 'next-intl'; import Link from 'next/link'; import { useState } from 'react'; import packageJson from '../../../../package.json'; import SystemLogsDialog from './system-logs-dialog'; export default function SystemVersionCard() { const t = useTranslations('tool'); const [openRestart, setOpenRestart] = useState(false); const [isRestarting, setIsRestarting] = useState(false); const { data: latestReleases } = useQuery({ queryKey: ['getLatestReleases'], queryFn: async () => { try { const [webResponse, serverResponse] = await Promise.all([ fetch('https://api.github.com/repos/perfect-panel/ppanel-web/releases/latest'), fetch('https://api.github.com/repos/perfect-panel/server/releases/latest'), ]); const webData = webResponse.ok ? await webResponse.json() : null; const serverData = serverResponse.ok ? await serverResponse.json() : null; return { web: webData ? { version: webData.tag_name, url: webData.html_url, publishedAt: webData.published_at, } : null, server: serverData ? { version: serverData.tag_name, url: serverData.html_url, publishedAt: serverData.published_at, } : null, }; } catch (error) { console.error('Failed to fetch latest releases:', error); return { web: null, server: null }; } }, staleTime: 60 * 60 * 1000, retry: 1, retryDelay: 10000, }); const hasNewVersion = latestReleases?.web && packageJson.version !== latestReleases.web.version.replace(/^v/, ''); const { data: systemInfo } = useQuery({ queryKey: ['getVersion'], queryFn: async () => { const { data } = await getVersion(); const versionString = (data.data?.version || '').replace(' Develop', '').trim(); const releaseVersionRegex = /^[Vv]?\d+\.\d+\.\d+(-[a-zA-Z]+(\.\d+)?)?$/; const timeMatch = versionString.match(/\(([^)]+)\)/); const timeInBrackets = timeMatch ? timeMatch[1] : ''; const versionWithoutTime = versionString.replace(/\([^)]*\)/, '').trim(); const isDevelopment = versionWithoutTime.includes('-dev') || versionWithoutTime.includes('-debug') || versionWithoutTime.includes('-nightly') || versionWithoutTime.includes('dev') || !releaseVersionRegex.test(versionWithoutTime); let baseVersion = versionWithoutTime; let lastUpdated = ''; if (isDevelopment && versionWithoutTime.includes('-')) { const parts = versionWithoutTime.split('-'); baseVersion = parts[0] || versionWithoutTime; } lastUpdated = formatDate(new Date(timeInBrackets || Date.now())) || ''; const displayVersion = baseVersion.startsWith('V') || baseVersion.startsWith('v') ? baseVersion : `V${baseVersion}`; return { isRelease: !isDevelopment, version: displayVersion, lastUpdated, }; }, }); const hasServerNewVersion = latestReleases?.server && systemInfo && systemInfo.version.replace(/^V/, '') !== latestReleases.server.version.replace(/^v/, ''); return ( {t('systemServices')}
{t('confirmSystemReboot')} {t('rebootDescription')} {t('cancel')}
{t('webVersion')}
V{packageJson.version} {hasNewVersion && ( {t('newVersionAvailable')} )}
{t('serverVersion')}
{systemInfo?.version || 'V1.0.0'} {hasServerNewVersion && ( {t('newVersionAvailable')} )}
); }