feat: notifications inbox page

The bell only ever showed the last 30; add a full paginated /notifications
page, per-notification mark-read, and a shared notificationHref helper so
the bell and the page route identically instead of duplicating the logic.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Arnaud
2026-07-10 07:57:17 +02:00
parent 45b886e398
commit 913410dbf3
9 changed files with 265 additions and 12 deletions
@@ -13,10 +13,11 @@ import {
} from "@/components/ui/dropdown-menu";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { notificationHref, type NotificationType } from "@/lib/notification-links";
type Notification = {
id: string;
type: "follow" | "comment" | "reply" | "reaction" | "rating" | "mention";
type: NotificationType;
recipeId: string | null;
commentId: string | null;
read: boolean;
@@ -26,12 +27,6 @@ type Notification = {
actorUsername: string | null;
};
function notificationHref(n: Notification): string {
if (n.type === "follow") return n.actorUsername ? `/u/${n.actorUsername}` : "#";
if (n.recipeId) return `/recipes/${n.recipeId}`;
return "#";
}
export function NotificationBell() {
const t = useTranslations("notifications");
const [notifications, setNotifications] = useState<Notification[]>([]);
@@ -104,6 +99,12 @@ export function NotificationBell() {
</DropdownMenuItem>
))}
</div>
<DropdownMenuItem
render={<Link href="/notifications" />}
className="justify-center text-sm text-muted-foreground hover:text-foreground"
>
{t("viewAll")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);