--- import BaseLayout from "@/layouts/BaseLayout.astro"; import { getDatabase, schema } from "@/db"; import { eq, desc, and } from "drizzle-orm"; 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"; return Math.floor(seconds / 86400) + "d ago"; } function getIconAndColor(type: string) { switch (type) { case "mention": return { icon: "M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207", color: "text-blue-400", bg: "bg-blue-500/10" }; case "assign": return { icon: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z", color: "text-purple-400", bg: "bg-purple-500/10" }; case "review_request": return { icon: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4", color: "text-orange-400", bg: "bg-orange-500/10" }; case "comment": return { icon: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z", color: "text-green-400", bg: "bg-green-500/10" }; case "ci_failed": return { icon: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", color: "text-red-400", bg: "bg-red-500/10" }; case "ci_success": return { icon: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z", color: "text-green-400", bg: "bg-green-500/10" }; case "star": return { icon: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z", color: "text-yellow-400", bg: "bg-yellow-500/10" }; default: return { icon: "M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9", color: "text-cyan-400", bg: "bg-cyan-500/10" }; } } ---

Notifications

{unreadCount > 0 && ( {unreadCount} )}
{unreadCount > 0 && ( )}
{notifications.length === 0 ? (

No notifications

{filter === "unread" ? "You're all caught up! No unread notifications." : filter === "archived" ? "No archived notifications." : "No notifications to display."}

) : ( )}