--- import { z } from 'astro/zod' import { Icon } from 'astro-icon/components' import { actions } from 'astro:actions' import Button from '../components/Button.astro' import CopyButton from '../components/CopyButton.astro' import PushNotificationBanner from '../components/PushNotificationBanner.astro' import TimeFormatted from '../components/TimeFormatted.astro' import Tooltip from '../components/Tooltip.astro' import { getNotificationTypeInfo } from '../constants/notificationTypes' import BaseLayout from '../layouts/BaseLayout.astro' import { cn } from '../lib/cn' import { getOrCreateNotificationPreferences } from '../lib/notificationPreferences' import { makeNotificationActions, makeNotificationContent, makeNotificationTitle } from '../lib/notifications' import { zodParseQueryParamsStoringErrors } from '../lib/parseUrlFilters' import { prisma } from '../lib/prisma' import { makeLoginUrl } from '../lib/redirectUrls' const user = Astro.locals.user if (!user) return Astro.redirect(makeLoginUrl(Astro.url)) const PAGE_SIZE = 20 const { data: params } = zodParseQueryParamsStoringErrors( { page: z.coerce.number().int().min(1).default(1), }, Astro ) const skip = (params.page - 1) * PAGE_SIZE const [dbNotifications, notificationPreferences, totalNotifications, pushSubscriptions] = await Astro.locals.banners.tryMany([ [ 'Error while fetching notifications', () => prisma.notification.findMany({ where: { userId: user.id, }, orderBy: { createdAt: 'desc', }, skip, take: PAGE_SIZE, select: { id: true, type: true, createdAt: true, read: true, aboutAccountStatusChange: true, aboutCommentStatusChange: true, aboutServiceVerificationStatusChange: true, aboutSuggestionStatusChange: true, aboutComment: { select: { id: true, author: { select: { id: true, }, }, status: true, content: true, communityNote: true, service: { select: { slug: true, name: true, }, }, parent: { select: { author: { select: { id: true, }, }, }, }, }, }, aboutServiceSuggestionId: true, aboutServiceSuggestion: { select: { status: true, type: true, service: { select: { name: true, }, }, }, }, aboutServiceSuggestionMessage: { select: { id: true, content: true, suggestion: { select: { id: true, service: { select: { name: true, }, }, }, }, }, }, aboutEvent: { select: { title: true, type: true, service: { select: { slug: true, name: true, }, }, }, }, aboutService: { select: { slug: true, name: true, verificationStatus: true, }, }, aboutKarmaTransaction: { select: { points: true, action: true, description: true, }, }, }, }), [], ], [ 'Error while fetching notification preferences', () => getOrCreateNotificationPreferences(user.id, { id: true, enableOnMyCommentStatusChange: true, enableAutowatchMyComments: true, enableNotifyPendingRepliesOnWatch: true, karmaNotificationThreshold: true, }), null, ], [ 'Error while fetching total notifications', () => prisma.notification.count({ where: { userId: user.id } }), 0, ], [ 'Error while fetching push subscriptions', () => prisma.pushSubscription.findMany({ where: { userId: user.id }, select: { endpoint: true, }, }), [], ], ]) if (!notificationPreferences) console.error('No notification preferences found') const totalPages = Math.ceil(totalNotifications / PAGE_SIZE) const notificationPreferenceFields = [ { id: 'enableOnMyCommentStatusChange', label: 'Notify me when my comment status changes.', icon: 'ri:chat-check-line', }, { id: 'enableAutowatchMyComments', label: 'Autowatch my comments to receive notifications when they get a new reply.', icon: 'ri:eye-line', }, { id: 'enableNotifyPendingRepliesOnWatch', label: 'Notify me also about unmoderated replies for watched comments.', icon: 'ri:chat-delete-line', }, ] as const satisfies { id: Omit, 'id'> label: string icon: string }[] const notifications = dbNotifications.map((notification) => ({ ...notification, typeInfo: getNotificationTypeInfo(notification.type), title: makeNotificationTitle(notification, user), content: makeNotificationContent(notification), actions: makeNotificationActions(notification, Astro.url.origin), })) ---
{ notifications.length >= 5 && ( ) }

Notifications

You received a new notification
{ notifications.length === 0 ? (

No notifications

) : (
{notifications.map((notification) => (
{notification.title}

{notification.content}

{notification.actions.map((action) => ( {action.title} ))}
))} {totalPages > 1 && (
Page {params.page} of {totalPages}
)}
) }

Notification Settings

{ notificationPreferenceFields.map((field) => ( )) }
Notify me when my karma changes by at least
points

RSS feeds available

Subscribe to receive your notifications in your favorite RSS reader.

Public RSS feeds

Don't require an account to subscribe. Includes service comments and events.