'use client' import { useState } from 'react' import { useTranslations } from 'next-intl' import { useMissionControl } from '@/store' import { Button } from '@/components/ui/button' type UpdateState = 'idle' | 'updating' | 'success' | 'error' export function OpenClawUpdateBanner() { const { openclawUpdate, openclawUpdateDismissedVersion, dismissOpenclawUpdate, setOpenclawUpdate } = useMissionControl() const t = useTranslations('openclawUpdateBanner') const tc = useTranslations('common') const [copied, setCopied] = useState(false) const [state, setState] = useState('idle') const [errorMsg, setErrorMsg] = useState(null) const [newVersion, setNewVersion] = useState(null) const [showChangelog, setShowChangelog] = useState(false) if (!openclawUpdate) return null if (openclawUpdateDismissedVersion === openclawUpdate.latest) return null function handleCopy() { navigator.clipboard.writeText(openclawUpdate!.updateCommand).then(() => { setCopied(true) setTimeout(() => setCopied(false), 2000) }).catch(() => {}) } async function handleUpdate() { setState('updating') setErrorMsg(null) try { const res = await fetch('/api/openclaw/update', { method: 'POST' }) const data = await res.json() if (!res.ok) { setState('error') setErrorMsg(data.detail || data.error || t('updateFailed')) return } setState('success') setNewVersion(data.newVersion) // Clear the banner after a few seconds setTimeout(() => setOpenclawUpdate(null), 5000) } catch { setState('error') setErrorMsg(t('networkError')) } } const busy = state === 'updating' return (

{state === 'updating' && ( {t('updatingOpenClaw')} )} {state === 'success' && ( {t('openclawUpdated', { version: newVersion || openclawUpdate.latest })} )} {state === 'error' && ( {errorMsg} )} {state === 'idle' && ( <> {t('openclawUpdateAvailable', { version: openclawUpdate.latest })} {' ('}{t('installed', { version: openclawUpdate.installed })}{')'} )}

{!busy && state !== 'success' && ( <> {openclawUpdate.releaseNotes && ( )} {tc('viewRelease')} )} {busy && ( )}
{showChangelog && openclawUpdate.releaseNotes && (
{openclawUpdate.releaseNotes}
)}
) }