import { useCallback, useEffect, useState } from 'react'; const createDefaultSettings = () => ({ ntfy: { enabled: false, topic: '', serverUrl: '' }, telegram: { enabled: false, chatId: '' } }); const createDefaultCapabilities = () => ({ ntfy: { enabled: false, serverUrl: '', topicPrefix: '' }, telegram: { enabled: false } }); const useNotificationSettings = ({ authorizedFetch, sessionToken }) => { const [settings, setSettings] = useState(createDefaultSettings); const [capabilities, setCapabilities] = useState(createDefaultCapabilities); const [dirty, setDirty] = useState(false); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [message, setMessage] = useState(''); const [error, setError] = useState(''); const [copyFeedback, setCopyFeedback] = useState(''); const resetState = useCallback(() => { setSettings(createDefaultSettings()); setCapabilities(createDefaultCapabilities()); setDirty(false); setLoading(false); setSaving(false); setMessage(''); setError(''); setCopyFeedback(''); }, []); const loadNotificationSettings = useCallback(async () => { if (!sessionToken) { return; } setLoading(true); setError(''); try { const response = await authorizedFetch('/api/notifications/settings'); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json(); setSettings({ ntfy: { enabled: Boolean(data?.settings?.ntfy?.enabled), topic: data?.settings?.ntfy?.topic || '', serverUrl: data?.settings?.ntfy?.serverUrl || '' }, telegram: { enabled: Boolean(data?.settings?.telegram?.enabled), chatId: data?.settings?.telegram?.chatId || '' } }); setCapabilities({ ntfy: { enabled: Boolean(data?.capabilities?.ntfy?.enabled), serverUrl: data?.capabilities?.ntfy?.serverUrl || '', topicPrefix: data?.capabilities?.ntfy?.topicPrefix || '' }, telegram: { enabled: Boolean(data?.capabilities?.telegram?.enabled) } }); setDirty(false); } catch (err) { setError(`Benachrichtigungseinstellungen konnten nicht geladen werden: ${err.message}`); } finally { setLoading(false); } }, [authorizedFetch, sessionToken]); const handleFieldChange = useCallback((channel, field, value) => { if (channel === 'ntfy' && field === 'serverUrl') { return; } setSettings((prev) => { const nextChannel = { ...prev[channel], [field]: value }; return { ...prev, [channel]: nextChannel }; }); setDirty(true); }, []); const saveNotificationSettings = useCallback(async () => { if (!sessionToken) { return; } setSaving(true); setError(''); setMessage(''); try { const response = await authorizedFetch('/api/notifications/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ notifications: settings }) }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json(); setSettings({ ntfy: { enabled: Boolean(data?.ntfy?.enabled), topic: data?.ntfy?.topic || settings.ntfy.topic, serverUrl: data?.ntfy?.serverUrl || settings.ntfy.serverUrl }, telegram: { enabled: Boolean(data?.telegram?.enabled), chatId: data?.telegram?.chatId || settings.telegram.chatId } }); setDirty(false); setMessage('Benachrichtigungseinstellungen gespeichert.'); setTimeout(() => setMessage(''), 4000); } catch (err) { setError(`Speichern der Benachrichtigungen fehlgeschlagen: ${err.message}`); } finally { setSaving(false); } }, [authorizedFetch, sessionToken, settings]); const sendNotificationTest = useCallback( async (channel) => { if (!sessionToken) { return; } setError(''); setMessage(''); try { const response = await authorizedFetch('/api/notifications/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ channel }) }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } await response.json(); setMessage('Testbenachrichtigung gesendet.'); setTimeout(() => setMessage(''), 4000); } catch (err) { setError(`Testbenachrichtigung fehlgeschlagen: ${err.message}`); } }, [authorizedFetch, sessionToken] ); const copyToClipboard = useCallback(async (text) => { if (!text) { return; } setCopyFeedback(''); try { if (navigator?.clipboard?.writeText) { await navigator.clipboard.writeText(text); } else { const tempInput = document.createElement('textarea'); tempInput.value = text; tempInput.style.position = 'fixed'; tempInput.style.top = '-9999px'; document.body.appendChild(tempInput); tempInput.focus(); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); } setCopyFeedback('Link kopiert!'); setTimeout(() => setCopyFeedback(''), 2000); } catch (err) { setCopyFeedback(`Kopieren fehlgeschlagen: ${err.message}`); setTimeout(() => setCopyFeedback(''), 3000); } }, []); useEffect(() => { if (!sessionToken) { resetState(); return; } loadNotificationSettings(); }, [sessionToken, loadNotificationSettings, resetState]); return { notificationSettings: settings, notificationCapabilities: capabilities, notificationDirty: dirty, notificationLoading: loading, notificationSaving: saving, notificationMessage: message, notificationError: error, copyFeedback, loadNotificationSettings, handleNotificationFieldChange: handleFieldChange, saveNotificationSettings, sendNotificationTest, copyToClipboard, resetNotificationState: resetState }; }; export default useNotificationSettings;