feat: add Apprise sidecar user/admin notifications
This commit is contained in:
@@ -72,6 +72,10 @@ export default function ProfilePage() {
|
||||
const [currentPassword, setCurrentPassword] = useState('')
|
||||
const [newPassword, setNewPassword] = useState('')
|
||||
const [status, setStatus] = useState<string | null>(null)
|
||||
const [notifyEnabled, setNotifyEnabled] = useState(false)
|
||||
const [notifyUrls, setNotifyUrls] = useState('')
|
||||
const [notifyStatus, setNotifyStatus] = useState<string | null>(null)
|
||||
const [notifySaving, setNotifySaving] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -97,6 +101,14 @@ export default function ProfilePage() {
|
||||
})
|
||||
setStats(data?.stats ?? null)
|
||||
setActivity(data?.activity ?? null)
|
||||
|
||||
const notifyResponse = await authFetch(`${baseUrl}/auth/notifications`)
|
||||
if (notifyResponse.ok) {
|
||||
const notifyData = await notifyResponse.json()
|
||||
setNotifyEnabled(Boolean(notifyData?.enabled))
|
||||
const urls = Array.isArray(notifyData?.urls) ? notifyData.urls : []
|
||||
setNotifyUrls(urls.join('\n'))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
setStatus('Could not load your profile.')
|
||||
@@ -137,6 +149,59 @@ export default function ProfilePage() {
|
||||
}
|
||||
}
|
||||
|
||||
const saveNotifications = async (event: React.FormEvent) => {
|
||||
event.preventDefault()
|
||||
setNotifyStatus(null)
|
||||
setNotifySaving(true)
|
||||
try {
|
||||
const baseUrl = getApiBase()
|
||||
const response = await authFetch(`${baseUrl}/auth/notifications`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
enabled: notifyEnabled,
|
||||
urls: notifyUrls,
|
||||
}),
|
||||
})
|
||||
if (!response.ok) {
|
||||
const text = await response.text()
|
||||
throw new Error(text || 'Update failed')
|
||||
}
|
||||
setNotifyStatus('Notification settings saved.')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const message =
|
||||
err instanceof Error && err.message
|
||||
? err.message.replace(/^\\{\"detail\":\"|\"\\}$/g, '')
|
||||
: 'Could not save notification settings.'
|
||||
setNotifyStatus(message)
|
||||
} finally {
|
||||
setNotifySaving(false)
|
||||
}
|
||||
}
|
||||
|
||||
const sendTest = async () => {
|
||||
setNotifyStatus(null)
|
||||
try {
|
||||
const baseUrl = getApiBase()
|
||||
const response = await authFetch(`${baseUrl}/auth/notifications/test`, {
|
||||
method: 'POST',
|
||||
})
|
||||
if (!response.ok) {
|
||||
const text = await response.text()
|
||||
throw new Error(text || 'Test failed')
|
||||
}
|
||||
setNotifyStatus('Test notification sent.')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
const message =
|
||||
err instanceof Error && err.message
|
||||
? err.message.replace(/^\\{\"detail\":\"|\"\\}$/g, '')
|
||||
: 'Could not send test notification.'
|
||||
setNotifyStatus(message)
|
||||
}
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return <main className="card">Loading profile...</main>
|
||||
}
|
||||
@@ -222,6 +287,42 @@ export default function ProfilePage() {
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<section className="profile-section">
|
||||
<h2>Notifications</h2>
|
||||
<div className="status-banner">
|
||||
Add Apprise URLs to receive notifications (one URL per line).
|
||||
</div>
|
||||
<form onSubmit={saveNotifications} className="auth-form">
|
||||
<label>
|
||||
Enable notifications
|
||||
<select
|
||||
value={notifyEnabled ? 'true' : 'false'}
|
||||
onChange={(event) => setNotifyEnabled(event.target.value === 'true')}
|
||||
>
|
||||
<option value="true">Enabled</option>
|
||||
<option value="false">Disabled</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Apprise URLs
|
||||
<textarea
|
||||
rows={4}
|
||||
placeholder="discord://token@webhook_id\nmailto://user:pass@server"
|
||||
value={notifyUrls}
|
||||
onChange={(event) => setNotifyUrls(event.target.value)}
|
||||
/>
|
||||
</label>
|
||||
{notifyStatus && <div className="status-banner">{notifyStatus}</div>}
|
||||
<div className="auth-actions">
|
||||
<button type="submit" disabled={notifySaving}>
|
||||
{notifySaving ? 'Saving...' : 'Save notifications'}
|
||||
</button>
|
||||
<button type="button" className="ghost-button" onClick={sendTest}>
|
||||
Send test
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{profile?.auth_provider !== 'local' ? (
|
||||
<div className="status-banner">
|
||||
Password changes are only available for local Magent accounts.
|
||||
|
||||
Reference in New Issue
Block a user