feat: notifications modal, admin dedup, and in-app notification preferences
- Replace bell dropdown with full-screen NotificationsModal (mirrors SearchModal pattern) - Notifications visible to all logged-in users (not just admin) - Admin users excluded from new-chapter fan-out (dedup vs Scrape Complete notification) - Users with notify_new_chapters=false opted out of new-chapter in-app notifications - Toggle in profile page to enable/disable in-app new-chapter notifications - PATCH /api/profile endpoint to save notification preferences - User-facing /notifications page (admin redirects to /admin/notifications)
This commit is contained in:
@@ -1,8 +1,43 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { deleteUserAccount } from '$lib/server/pocketbase';
|
||||
import { deleteUserAccount, updateUserNotificationPrefs } from '$lib/server/pocketbase';
|
||||
import { log } from '$lib/server/logger';
|
||||
|
||||
/**
|
||||
* PATCH /api/profile
|
||||
*
|
||||
* Update mutable profile preferences (currently: notification preferences).
|
||||
* Body: { notify_new_chapters?: boolean }
|
||||
*/
|
||||
export const PATCH: RequestHandler = async ({ locals, request }) => {
|
||||
if (!locals.user) error(401, 'Not authenticated');
|
||||
|
||||
let body: Record<string, unknown>;
|
||||
try {
|
||||
body = await request.json();
|
||||
} catch {
|
||||
error(400, 'Invalid JSON');
|
||||
}
|
||||
|
||||
const prefs: { notify_new_chapters?: boolean } = {};
|
||||
if (typeof body.notify_new_chapters === 'boolean') {
|
||||
prefs.notify_new_chapters = body.notify_new_chapters;
|
||||
}
|
||||
|
||||
if (Object.keys(prefs).length === 0) {
|
||||
error(400, 'No valid preferences provided');
|
||||
}
|
||||
|
||||
try {
|
||||
await updateUserNotificationPrefs(locals.user.id, prefs);
|
||||
} catch (e) {
|
||||
log.error('profile', 'PATCH /api/profile failed', { userId: locals.user.id, err: String(e) });
|
||||
error(500, { message: 'Failed to update preferences. Please try again.' });
|
||||
}
|
||||
|
||||
return json({ ok: true });
|
||||
};
|
||||
|
||||
/**
|
||||
* DELETE /api/profile
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user