import { useState, useEffect } from 'react';
import { TogglePill } from '@/components/ui/toggle-pill';
import { Skeleton } from '@/components/ui/skeleton';
import { useAuth } from '@/context/AuthContext';
import { RefreshCw } from 'lucide-react';
import { apiFetch } from '@/lib/api';
import { toast } from '@/components/ui/toast-store';
import { useNodes } from '@/context/NodeContext';
import { DEFAULT_SETTINGS } from './types';
import type { PatchableSettings } from './types';
import { SettingsSection } from './SettingsSection';
import { SettingsField } from './SettingsField';
import { SettingsActions, SettingsPrimaryButton } from './SettingsActions';
import { useMastheadStats } from './MastheadStatsContext';
import { useSettingsDirty } from './useSettingsDirty';
interface ContainerAlertsSectionProps {
onDirtyChange?: (dirty: boolean) => void;
}
function SectionSkeleton() {
return (
);
}
type ContainerAlertFields = Pick;
const DEFAULT_CONTAINER_ALERTS: ContainerAlertFields = {
global_crash: DEFAULT_SETTINGS.global_crash,
};
export function ContainerAlertsSection({ onDirtyChange }: ContainerAlertsSectionProps) {
const { isAdmin } = useAuth();
const { activeNode } = useNodes();
const readOnly = !isAdmin;
const { settings, setSettings, dirtyCount, hasChanges, reset, markSaved } = useSettingsDirty({ ...DEFAULT_CONTAINER_ALERTS });
const [isLoading, setIsLoading] = useState(false);
const [isSaving, setIsSaving] = useState(false);
useEffect(() => {
onDirtyChange?.(hasChanges);
}, [hasChanges, onDirtyChange]);
useMastheadStats(
isLoading
? null
: [
{
label: 'EDITED',
value: hasChanges ? `${dirtyCount} pending` : 'saved',
tone: hasChanges ? 'warn' : 'value',
},
],
);
useEffect(() => {
const fetchSettings = async () => {
setIsLoading(true);
try {
const nodeRes = await apiFetch('/settings');
const nodeData: Record = nodeRes.ok ? await nodeRes.json() : {};
const safe: ContainerAlertFields = {
global_crash: (nodeData.global_crash as '0' | '1') ?? DEFAULT_SETTINGS.global_crash,
};
reset(safe);
} catch (e) {
console.error('Failed to fetch container alert settings', e);
} finally {
setIsLoading(false);
}
};
fetchSettings();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeNode?.id]);
const onSettingChange = (key: K, value: ContainerAlertFields[K]) => {
setSettings(prev => ({ ...prev, [key]: value }));
};
const saveSettings = async () => {
const submitted = { ...settings };
setIsSaving(true);
try {
const res = await apiFetch('/settings', {
method: 'PATCH',
body: JSON.stringify({ global_crash: submitted.global_crash }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
toast.error(err?.error || err?.message || 'Failed to save settings.');
return;
}
markSaved(submitted);
toast.success('Container alert settings saved.');
} catch (e: unknown) {
toast.error((e as Error)?.message || 'Something went wrong.');
} finally {
setIsSaving(false);
}
};
if (isLoading) return ;
return (
);
}