210 lines
6.2 KiB
JavaScript
210 lines
6.2 KiB
JavaScript
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;
|