Add reusable segmented inbox filters

This commit is contained in:
JB
2026-07-25 15:42:34 -04:00
parent 29f4de807a
commit 8b7b747866
7 changed files with 134 additions and 8 deletions
@@ -9,12 +9,24 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
const user = await getSessionUser(cookies);
if (!user) redirect(303, '/sign-in');
const database = await getDatabase();
const category = NOTIFICATION_CATEGORIES.includes(url.searchParams.get('category') as any) ? String(url.searchParams.get('category')) : '';
const unreadOnly = url.searchParams.get('state') === 'unread';
const filtering = url.searchParams.get('filtering') === '1';
const categories = filtering
? url.searchParams.getAll('channel').filter((value) => NOTIFICATION_CATEGORIES.includes(value as any))
: [...NOTIFICATION_CATEGORIES];
const states = filtering
? url.searchParams.getAll('state').filter((value) => value === 'unread' || value === 'read')
: ['unread', 'read'];
const conditions = ['n.user_id=?', '(n.mandatory=1 OR COALESCE(p.in_app_enabled,1)=1)'];
const args: unknown[] = [user.id];
if (category) { conditions.push('n.category=?'); args.push(category); }
if (unreadOnly) conditions.push('n.read_at IS NULL');
if (categories.length === 0 || states.length === 0) {
conditions.push('1=0');
} else {
if (categories.length < NOTIFICATION_CATEGORIES.length) {
conditions.push(`n.category IN (${categories.map(() => '?').join(',')})`);
args.push(...categories);
}
if (states.length === 1) conditions.push(states[0] === 'unread' ? 'n.read_at IS NULL' : 'n.read_at IS NOT NULL');
}
const where = `WHERE ${conditions.join(' AND ')}`;
const total = Number((await (await database.prepare(`SELECT COUNT(*) AS total FROM notifications n LEFT JOIN notification_preferences p ON p.user_id=n.user_id AND p.category=n.category ${where}`)).get(...args))?.total ?? 0);
const pagination = getPagination(url, total);
@@ -34,7 +46,7 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
const unread = Number((await (await database.prepare(`SELECT COUNT(*) AS count FROM notifications n
LEFT JOIN notification_preferences p ON p.user_id=n.user_id AND p.category=n.category
WHERE n.user_id=? AND n.read_at IS NULL AND (n.mandatory=1 OR COALESCE(p.in_app_enabled,1)=1)`)).get(user.id))?.count ?? 0);
return { notifications, preferences, pagination, filters: { category, unreadOnly }, unread, hasVerifiedEmail: Boolean(await (await database.prepare('SELECT 1 FROM user_emails WHERE user_id=?')).get(user.id)) };
return { notifications, preferences, pagination, filters: { categories, states }, unread, hasVerifiedEmail: Boolean(await (await database.prepare('SELECT 1 FROM user_emails WHERE user_id=?')).get(user.id)) };
};
export const actions: Actions = {