import { useEffect, useState } from 'react' import StyledButton from '~/components/StyledButton' import StyledSectionHeader from '~/components/StyledSectionHeader' import Alert from '~/components/Alert' import api from '~/lib/api' import Input from '~/components/inputs/Input' import Switch from '~/components/inputs/Switch' import { useMutation, useQueryClient } from '@tanstack/react-query' import { useNotifications } from '~/context/NotificationContext' import { useAutoUpdateStatus } from '~/hooks/useAutoUpdateStatus' const COOLOFF_OPTIONS = [ { value: 24, label: '24 hours (1 day)' }, { value: 48, label: '48 hours (2 days)' }, { value: 72, label: '72 hours (3 days)' }, { value: 168, label: '7 days' }, ] export default function CoreAutoUpdateSection() { const { addNotification } = useNotifications() const queryClient = useQueryClient() const { data: status, isLoading } = useAutoUpdateStatus() const [windowStart, setWindowStart] = useState('02:00') const [windowEnd, setWindowEnd] = useState('05:00') const [cooloff, setCooloff] = useState(72) // Seed editable fields once the persisted status loads. useEffect(() => { if (status) { setWindowStart(status.windowStart) setWindowEnd(status.windowEnd) setCooloff(status.cooloffHours) } }, [status?.windowStart, status?.windowEnd, status?.cooloffHours]) const saveMutation = useMutation({ mutationFn: ({ key, value }: { key: string; value: any }) => api.updateSetting(key, value), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['auto-update-status'] }) }, onError: () => { addNotification({ type: 'error', message: 'Failed to update auto-update setting.' }) }, }) const enabled = status?.enabled ?? false const autoDisabled = !!status?.autoDisabledReason const handleToggle = (value: boolean) => { saveMutation.mutate( { key: 'autoUpdate.enabled', value }, { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['auto-update-status'] }) addNotification({ type: 'success', message: value ? 'Automatic updates enabled.' : 'Automatic updates disabled.', }) }, } ) } const handleSaveWindow = async () => { try { await api.updateSetting('autoUpdate.windowStart', windowStart) await api.updateSetting('autoUpdate.windowEnd', windowEnd) await api.updateSetting('autoUpdate.cooloffHours', String(cooloff)) queryClient.invalidateQueries({ queryKey: ['auto-update-status'] }) addNotification({ type: 'success', message: 'Auto-update schedule saved.' }) } catch { addNotification({ type: 'error', message: 'Failed to save auto-update schedule.' }) } } return ( <>
{autoDisabled && ( )}
setWindowStart(e.target.value)} disabled={!enabled} helpText="Local server time" /> setWindowEnd(e.target.value)} disabled={!enabled} helpText="Local server time" />

Delay after a release is published

Save Schedule
{enabled && status && (

Status: {status.eligibleTarget ? `Eligible update ready: ${status.eligibleTarget.version}` : 'No eligible update — system is current or the latest release is a major version / still in cool-off.'}

Update window: {status.withinWindow ? 'Currently inside the window' : 'Currently outside the window'}

{status.lastResult && (

Last check: {status.lastResult} {status.lastAttemptAt ? ` (${new Date(status.lastAttemptAt).toLocaleString()})` : ''}

)} {status.lastError && (

Last error: {status.lastError}

)}
)}
) }