--- import BaseLayout from "@/layouts/BaseLayout.astro"; import { getDatabase, schema } from "@/db"; import { eq, desc, and } from "drizzle-orm"; import { Bell, Check, Settings, AtSign, UserCheck, GitPullRequest, MessageSquare, AlertCircle, CheckCircle2, Star, Inbox, Archive } from "lucide-react"; const user = Astro.locals.user; if (!user) { return Astro.redirect("/login"); } const db = getDatabase(); const filter = Astro.url.searchParams.get("filter") || "unread"; // Fetch notifications for the user let notifications: any[] = []; try { const conditions: any[] = [eq(schema.notifications.userId, user.id)]; if (filter === "unread") { conditions.push(eq(schema.notifications.isRead, false)); } else if (filter === "read") { conditions.push(eq(schema.notifications.isRead, true)); } if (filter !== "archived") { conditions.push(eq(schema.notifications.isArchived, false)); } else { conditions.push(eq(schema.notifications.isArchived, true)); } notifications = await db.query.notifications.findMany({ where: and(...conditions), orderBy: [desc(schema.notifications.createdAt)], limit: 50, with: { actor: true, repository: true, }, }); } catch (e) { console.error("Failed to fetch notifications:", e); } // Count unread let unreadCount = 0; try { const unread = await db.query.notifications.findMany({ where: and( eq(schema.notifications.userId, user.id), eq(schema.notifications.isRead, false), eq(schema.notifications.isArchived, false) ), }); unreadCount = unread.length; } catch (e) {} function timeAgo(date: string) { const seconds = Math.floor((Date.now() - new Date(date).getTime()) / 1000); if (seconds < 60) return "just now"; if (seconds < 3600) return Math.floor(seconds / 60) + "m ago"; if (seconds < 86400) return Math.floor(seconds / 3600) + "h ago"; if (seconds < 604800) return Math.floor(seconds / 86400) + "d ago"; return new Date(date).toLocaleDateString(); } --- Notifications {unreadCount > 0 && ( {unreadCount} )} Stay updated with reviews, mentions, and project activity {unreadCount > 0 && ( Mark all as read )} Unread {unreadCount > 0 && ( {unreadCount} )} All Read Archived {notifications.length === 0 ? ( All caught up! {filter === "unread" ? "You have no unread notifications." : filter === "archived" ? "No archived notifications." : "No notifications to display."} ) : ( {notifications.map((notification: any) => { return ( {notification.type === "mention" ? ( ) : notification.type === "review_request" ? ( ) : notification.type === "ci_failed" ? ( ) : notification.type === "ci_success" ? ( ) : notification.type === "star" ? ( ) : notification.type === "comment" ? ( ) : ( )} {notification.title} {timeAgo(notification.createdAt)} {notification.body && ( {notification.body} )} {notification.repository && ( {notification.repository.name} )} {notification.actor && ( <> · {notification.actor.avatarUrl ? ( ) : ( {notification.actor.username?.[0]?.toUpperCase()} )} @{notification.actor.username} > )} {!notification.isRead && ( )} ); })} )}
Stay updated with reviews, mentions, and project activity
{filter === "unread" ? "You have no unread notifications." : filter === "archived" ? "No archived notifications." : "No notifications to display."}
{notification.body}