refactoring

This commit is contained in:
2025-11-10 09:57:48 +01:00
parent 083c79d82e
commit 248b0bcba4
5 changed files with 317 additions and 19533 deletions

View File

@@ -0,0 +1,209 @@
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;