Skip to content

feat/PRO-3749/pulse-beta-tag#413

Merged
RanaBug merged 1 commit intostagingfrom
feat/PRO-3749/pulse-beta-tag
Sep 30, 2025
Merged

feat/PRO-3749/pulse-beta-tag#413
RanaBug merged 1 commit intostagingfrom
feat/PRO-3749/pulse-beta-tag

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Sep 30, 2025

Description

  • FE implementation of the Pulse beta toast message

How Has This Been Tested?

  • Existing Unit Tests and Manual testing

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • New Features
    • Added a toast notification on the Pulse Home screen.
    • Appears automatically on entry and displays in the bottom-right with smooth animation.
    • Automatically dismisses after 8 seconds.
    • Includes a close button to dismiss immediately.

@RanaBug RanaBug requested a review from IAmKio September 30, 2025 14:39
@RanaBug RanaBug self-assigned this Sep 30, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

Walkthrough

Adds a new PulseToast component and integrates it into HomeScreen to auto-show a bottom-right toast on mount, with an 8-second auto-dismiss and manual close. HomeScreen manages a local flag to render the toast and hides it via onClose.

Changes

Cohort / File(s) Summary
HomeScreen integration
src/apps/pulse/components/App/HomeScreen.tsx
Imports and conditionally renders PulseToast. Adds showBetaToast state, initializes true on mount via useEffect, and hides it on onClose.
Toast component
src/apps/pulse/components/Toast/PulseToast.tsx
New animated toast component using react-spring. Fixed bottom-right, auto-appears, auto-hides after ~8s, supports manual close via button, then calls onClose. Default export PulseToast(props: { onClose: () => void }).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant HS as HomeScreen
  participant PT as PulseToast
  participant T as Timer

  User->>HS: Navigate to HomeScreen (mount)
  HS->>HS: set showBetaToast = true
  HS->>PT: Render <PulseToast onClose=... />

  activate PT
  PT->>PT: isVisible = true (animate in)
  PT->>T: start 8s timer

  T-->>PT: timeout
  PT->>PT: animate out (300ms)
  PT-->>HS: onClose()

  HS->>HS: set showBetaToast = false (unmount PT)

  opt Manual close
    User->>PT: Click close button
    PT->>PT: animate out (300ms)
    PT-->>HS: onClose()
    HS->>HS: set showBetaToast = false
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • IAmKio

Poem

A toast pops up—surprise!—so bright,
I twitch my ears, then take a bite. 🥕
Eight seconds pass, it fades from sight,
A gentle hop into the night.
Click—it closes, neat and tight;
Ship it quick, my code-delight!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The title "feat/PRO-3749/pulse-beta-tag" appears to be a branch name or ticket identifier rather than a clear, concise summary of the change, and does not describe the actual feature implemented. Rename the PR title to a succinct sentence summarizing the main change, for example “Add Pulse beta toast notification to HomeScreen component.”
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed The description follows the repository template by including the Description, How Has This Been Tested, and Types of changes sections, clearly stating that this is a new feature and summarizing the implementation and testing approach.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PRO-3749/pulse-beta-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: e3e3ad7
Status: ✅  Deploy successful!
Preview URL: https://ca42f99f.x-e62.pages.dev
Branch Preview URL: https://feat-pro-3749-pulse-beta-tag.x-e62.pages.dev

View logs

Copy link
Collaborator

@IAmKio IAmKio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/apps/pulse/components/Toast/PulseToast.tsx (3)

19-30: Consider using useCallback for handleClose to avoid the eslint-disable.

The exhaustive-deps rule is disabled because handleClose is not included in the dependency array. While this works for a mount-only effect, it creates a stale closure risk if onClose were to change (though unlikely in this case).

A cleaner pattern would be:

+import { useCallback, useEffect, useRef, useState } from 'react';

 const PulseToast = ({ onClose }: PulseToastProps) => {
   const [isVisible, setIsVisible] = useState(false);

-  const handleClose = () => {
+  const handleClose = useCallback(() => {
     setIsVisible(false);
     setTimeout(() => {
       onClose();
     }, 300);
-  };
+  }, [onClose]);

   useEffect(() => {
     setIsVisible(true);

     const timer = setTimeout(() => {
       handleClose();
     }, 8000);

     return () => {
       clearTimeout(timer);
     };
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, []);
+  }, [handleClose]);

This eliminates the need for the disable comment and ensures handleClose properly tracks its dependencies.


32-36: Consider respecting prefers-reduced-motion for accessibility.

The toast animates regardless of the user's motion preferences. Users who have enabled prefers-reduced-motion in their system settings may experience discomfort.

React-spring provides useReducedMotion() hook (per learnings). You can use it to disable animations:

-import { animated, useSpring } from '@react-spring/web';
+import { animated, useReducedMotion, useSpring } from '@react-spring/web';

 const PulseToast = ({ onClose }: PulseToastProps) => {
   const [isVisible, setIsVisible] = useState(false);
+  const prefersReducedMotion = useReducedMotion();

   // ... handleClose and useEffect ...

   const toastAnimation = useSpring({
     opacity: isVisible ? 1 : 0,
-    transform: isVisible ? 'translateY(0px)' : 'translateY(20px)',
+    transform: isVisible && !prefersReducedMotion ? 'translateY(0px)' : 'translateY(20px)',
-    config: { tension: 200, friction: 20 },
+    config: prefersReducedMotion ? { duration: 0 } : { tension: 200, friction: 20 },
   });

This respects user accessibility preferences while maintaining the visual polish for others.


38-63: Consider adding Escape key handler for better UX.

Users typically expect to dismiss toasts using the Escape key, especially when they auto-appear.

Add a keyboard event listener:

 useEffect(() => {
   setIsVisible(true);

+  const handleEscape = (e: KeyboardEvent) => {
+    if (e.key === 'Escape') {
+      handleClose();
+    }
+  };
+
+  document.addEventListener('keydown', handleEscape);
+
   const timer = setTimeout(() => {
     handleClose();
   }, 8000);

   return () => {
+    document.removeEventListener('keydown', handleEscape);
     clearTimeout(timer);
   };
   // eslint-disable-next-line react-hooks/exhaustive-deps
 }, []);

This provides an additional accessible way to dismiss the toast.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5acb28e and e3e3ad7.

📒 Files selected for processing (2)
  • src/apps/pulse/components/App/HomeScreen.tsx (4 hunks)
  • src/apps/pulse/components/Toast/PulseToast.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/apps/pulse/components/Toast/PulseToast.tsx (1)
src/components/LandingPage/Header/index.jsx (1)
  • isVisible (9-9)
⏰ 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: unit-tests
  • GitHub Check: lint
  • GitHub Check: build
🔇 Additional comments (8)
src/apps/pulse/components/Toast/PulseToast.tsx (4)

1-3: LGTM!

Imports are appropriate and follow best practices. Using @react-spring/web package-specific entrypoint enables better tree-shaking.


5-7: LGTM!

Type definition is clear and appropriate for the component's API.


9-10: LGTM!

Component declaration and initial state setup are correct. Starting with isVisible = false enables the entrance animation.


32-36: LGTM!

Animation configuration is appropriate. The fade-in with slide-up effect provides good visual feedback, and the spring config values are reasonable.

src/apps/pulse/components/App/HomeScreen.tsx (4)

29-29: LGTM!

Import path and default import are correct.


59-59: LGTM!

State initialization is correct. Starting with false and setting to true in the effect ensures the toast animates in properly.


85-88: LGTM!

The mount effect correctly shows the toast on entry. The comment "on every entry to Pulse" is accurate assuming the component remounts on navigation (typical for React SPAs).


416-416: LGTM!

Conditional rendering and integration with PulseToast are correct. The onClose callback properly manages the toast visibility state.

Comment on lines +38 to +63
return (
<animated.div
style={toastAnimation}
className="flex fixed bottom-4 right-4 max-w-80 bg-[#8A77FF] text-medium_grey p-4 rounded-lg shadow-lg z-[500] border border-white/[.5]"
>
<div className="flex flex-col">
<div className="flex justify-between">
<p className="text-sm font-medium text-white mb-2">
Welcome to Pulse (beta)
</p>
<button
type="button"
className="absolute top-2 right-2"
onClick={handleClose}
aria-label="Close"
>
<MdClose color="white" />
</button>
</div>
<p className="text-xs font-normal text-white">
You’re trying out the beta version of Pulse: expect improvements
ahead. Thank you for being part of the journey!
</p>
</div>
</animated.div>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add ARIA role for screen reader announcement.

The toast appears automatically without user action, but lacks an ARIA role to announce its presence to screen readers. This impacts accessibility for users relying on assistive technology.

Add role="status" or role="alert" to the toast container:

 <animated.div
   style={toastAnimation}
   className="flex fixed bottom-4 right-4 max-w-80 bg-[#8A77FF] text-medium_grey p-4 rounded-lg shadow-lg z-[500] border border-white/[.5]"
+  role="status"
+  aria-live="polite"
 >

Use role="status" with aria-live="polite" for informational messages (preferred for beta announcements), or role="alert" with aria-live="assertive" for urgent messages.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<animated.div
style={toastAnimation}
className="flex fixed bottom-4 right-4 max-w-80 bg-[#8A77FF] text-medium_grey p-4 rounded-lg shadow-lg z-[500] border border-white/[.5]"
>
<div className="flex flex-col">
<div className="flex justify-between">
<p className="text-sm font-medium text-white mb-2">
Welcome to Pulse (beta)
</p>
<button
type="button"
className="absolute top-2 right-2"
onClick={handleClose}
aria-label="Close"
>
<MdClose color="white" />
</button>
</div>
<p className="text-xs font-normal text-white">
You’re trying out the beta version of Pulse: expect improvements
ahead. Thank you for being part of the journey!
</p>
</div>
</animated.div>
);
return (
<animated.div
style={toastAnimation}
className="flex fixed bottom-4 right-4 max-w-80 bg-[#8A77FF] text-medium_grey p-4 rounded-lg shadow-lg z-[500] border border-white/[.5]"
role="status"
aria-live="polite"
>
<div className="flex flex-col">
<div className="flex justify-between">
<p className="text-sm font-medium text-white mb-2">
Welcome to Pulse (beta)
</p>
<button
type="button"
className="absolute top-2 right-2"
onClick={handleClose}
aria-label="Close"
>
<MdClose color="white" />
</button>
</div>
<p className="text-xs font-normal text-white">
You’re trying out the beta version of Pulse: expect improvements
ahead. Thank you for being part of the journey!
</p>
</div>
</animated.div>
);
🤖 Prompt for AI Agents
In src/apps/pulse/components/Toast/PulseToast.tsx around lines 38 to 63, the
toast lacks ARIA attributes so screen readers won’t announce it; add
accessibility attributes to the top-level animated.div by setting role="status"
and aria-live="polite" (optionally aria-atomic="true") to ensure the
informational beta message is announced politely to assistive technologies.

@RanaBug RanaBug merged commit a526175 into staging Sep 30, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 14, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants