feat: add a popup about new features on the dashboard#2182
Conversation
WalkthroughAdds a dismissible "New Features" popup component, a localStorage-backed hook to persist its dismissal, and renders the popup inside the SideNav on large screens; also adds relative positioning to the aside and minor non-functional formatting tweaks. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
studio/src/hooks/use-new-features-popup-disabled.ts (2)
4-15: Expose a boolean setter (avoid leaking stringly-typed storage API).Return a boolean setter and encapsulate the string conversion internally. This prevents accidental misuse and simplifies consumers.
Apply:
-import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react"; @@ -export function useNewFeaturesPopupDisabled(): [boolean, Dispatch<SetStateAction<string>>] { - const [isPopupDisabled, setIsPopupDisabled] = useState(true); - const [isPopupDisabledOnClient, setDisablePopup] = useLocalStorage( - "dismissNewFeaturesPopup", - "false", - ); +const STORAGE_KEY = "dismissNewFeaturesPopup:v1"; + +export function useNewFeaturesPopupDisabled(): [boolean, Dispatch<SetStateAction<boolean>>] { + const [isPopupDisabled, setIsPopupDisabled] = useState(true); + const [stored, setStored] = useLocalStorage(STORAGE_KEY, "false"); @@ - useEffect(() => { - setIsPopupDisabled(isPopupDisabledOnClient === "true"); - }, [isPopupDisabledOnClient]); + useEffect(() => { + setIsPopupDisabled(stored === "true"); + }, [stored]); - return [isPopupDisabled, setDisablePopup]; + const setPopupDisabled: Dispatch<SetStateAction<boolean>> = useCallback((next) => { + setStored((prev) => { + const prevBool = prev === "true"; + const nextBool = typeof next === "function" ? (next as (p: boolean) => boolean)(prevBool) : next; + return nextBool ? "true" : "false"; + }); + }, [setStored]); + + return [isPopupDisabled, setPopupDisabled]; }
6-9: Version the storage key to allow future re-showing.A versioned key (e.g., “:v1”) lets you re-announce future features without migrating existing users’ state.
studio/src/components/layout/sidenav.tsx (1)
29-29: Load the popup lazily on the client to avoid hydration pitfalls and trim SSR bundle.The popup depends on localStorage; dynamic import with ssr: false prevents SSR mismatches and reduces server payload.
-import NewFeaturesPopup from "../dashboard/NewFeaturesPopup"; +import dynamic from "next/dynamic"; +const NewFeaturesPopup = dynamic(() => import("../dashboard/NewFeaturesPopup"), { ssr: false });studio/src/components/dashboard/NewFeaturesPopup.tsx (3)
31-37: Make the close button accessible and discoverable without hover.Add an accessible name and reveal on keyboard focus.
- <Button + <Button variant="ghost" size="icon" - className="h-4 w-4 cursor-pointer text-white/50 opacity-0 transition-all duration-300 group-hover:opacity-100" + className="h-4 w-4 cursor-pointer text-white/50 opacity-0 transition-all duration-300 group-hover:opacity-100 focus-visible:opacity-100" + aria-label="Close new features popup" onClick={handleClosePopup} >
46-53: Harden external link target and improve a11y hint.Include noopener and an aria-label to indicate a new tab.
- <Link + <Link href="https://wundergraph.com/connect" target="_blank" - rel="noreferrer" + rel="noreferrer noopener" className="flex items-center gap-x-1 text-sm font-medium text-white hover:underline" + aria-label="Learn more about Cosmo Connect (opens in a new tab)" >
22-22: Theme consistency.Avoid hard-coded hex background; prefer a token (e.g., bg-card) to respect themes.
- <div className="relative z-10 flex h-full w-full flex-col items-start justify-center gap-4 rounded-lg bg-[#15121C] p-3"> + <div className="relative z-10 flex h-full w-full flex-col items-start justify-center gap-4 rounded-lg bg-card p-3">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
studio/src/components/dashboard/NewFeaturesPopup.tsx(1 hunks)studio/src/components/layout/sidenav.tsx(4 hunks)studio/src/hooks/use-new-features-popup-disabled.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
studio/src/components/layout/sidenav.tsx (2)
studio/src/lib/utils.ts (1)
cn(6-8)studio/src/components/dashboard/NewFeaturesPopup.tsx (1)
NewFeaturesPopup(8-204)
studio/src/components/dashboard/NewFeaturesPopup.tsx (2)
studio/src/hooks/use-new-features-popup-disabled.ts (1)
useNewFeaturesPopupDisabled(4-16)studio/src/components/ui/link.tsx (1)
Link(5-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build_test
- GitHub Check: build_push_image
- GitHub Check: Analyze (go)
Summary by CodeRabbit
Checklist