From a0b4a26ad398137e13c35f3fe0dad99154537d91 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Tue, 30 Dec 2025 12:52:50 +0200 Subject: feat: 2025 wrapped (#2322) * feat: 2025 wrapped * don't add wrapped for new users --- apps/web/app/dashboard/layout.tsx | 20 ++++++++++++++++++-- apps/web/app/dashboard/wrapped/page.tsx | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 apps/web/app/dashboard/wrapped/page.tsx (limited to 'apps/web/app/dashboard') diff --git a/apps/web/app/dashboard/layout.tsx b/apps/web/app/dashboard/layout.tsx index be65e66a..81b44a3c 100644 --- a/apps/web/app/dashboard/layout.tsx +++ b/apps/web/app/dashboard/layout.tsx @@ -16,6 +16,7 @@ import { Highlighter, Home, Search, + Sparkles, Tag, } from "lucide-react"; @@ -34,9 +35,10 @@ export default async function Dashboard({ redirect("/"); } - const [lists, userSettings] = await Promise.all([ + const [lists, userSettings, showWrapped] = await Promise.all([ tryCatch(api.lists.list()), tryCatch(api.users.settings()), + tryCatch(api.users.hasWrapped()), ]); if (userSettings.error) { @@ -55,6 +57,10 @@ export default async function Dashboard({ throw lists.error; } + if (showWrapped.error) { + throw showWrapped.error; + } + const items = (t: TFunction) => [ { @@ -86,10 +92,20 @@ export default async function Dashboard({ icon: , path: "/dashboard/archive", }, + // Only show wrapped if user has at least 20 bookmarks + showWrapped.data + ? [ + { + name: t("wrapped.button"), + icon: , + path: "/dashboard/wrapped", + }, + ] + : [], ].flat(); const mobileSidebar = (t: TFunction) => [ - ...items(t), + ...items(t).filter((item) => item.path !== "/dashboard/wrapped"), { name: t("lists.all_lists"), icon: , diff --git a/apps/web/app/dashboard/wrapped/page.tsx b/apps/web/app/dashboard/wrapped/page.tsx new file mode 100644 index 00000000..f479aca7 --- /dev/null +++ b/apps/web/app/dashboard/wrapped/page.tsx @@ -0,0 +1,24 @@ +"use client"; + +import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { WrappedModal } from "@/components/wrapped"; + +export default function WrappedPage() { + const router = useRouter(); + + const handleClose = () => { + router.push("/dashboard/bookmarks"); + }; + + // Always show the modal when this page is loaded + useEffect(() => { + // Prevent page from being scrollable when modal is open + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = ""; + }; + }, []); + + return ; +} -- cgit v1.2.3-70-g09d2