Skip to content

🎨 Palette: Improve Login UX and Navbar accessibility#33

Open
BilalkhanIO wants to merge 1 commit intomainfrom
palette-login-ux-navbar-a11y-3796880956653555443
Open

🎨 Palette: Improve Login UX and Navbar accessibility#33
BilalkhanIO wants to merge 1 commit intomainfrom
palette-login-ux-navbar-a11y-3796880956653555443

Conversation

@BilalkhanIO
Copy link
Owner

@BilalkhanIO BilalkhanIO commented Feb 2, 2026

This PR introduces a few micro-UX and accessibility improvements:

  1. Login Interaction: The Login form now features a loading state. When submitted, the button displays "Logging in...", becomes disabled, and shows a 'not-allowed' cursor. This provides clear feedback to the user and prevents accidental double-submissions.
  2. Structural Clarity: The Login button has been isolated from the "Forgot password" link into its own list item, following structural best practices for form actions.
  3. Navbar Accessibility: The shopping cart link in the Navbar now has a descriptive aria-label="View shopping cart, 3 items". Its internal icon and badge are hidden from screen readers to prevent redundant announcements.
  4. Consistency: The :disabled state for primary buttons has been added to both Login and Signup CSS files for visual consistency across the app.

Visual verification was performed with Playwright, and a screenshot was captured showing the loading state.


PR created automatically by Jules for task 3796880956653555443 started by @BilalkhanIO

Summary by CodeRabbit

  • New Features

    • Added loading state to login form with disabled button and "Logging in..." indicator during sign-in.
  • Documentation

    • Documented UX best practices for ARIA label handling and submit button structure.
  • Style

    • Enhanced disabled state styling for login and signup buttons with visual feedback.
    • Improved cart navigation accessibility with ARIA labels and attributes.

- Added isLoading state to Login form with 2s simulation delay.
- Improved Login form structure by isolating the login button.
- Added :disabled styles for primary buttons in Login and Signup CSS.
- Enhanced Navbar cart accessibility with aria-label and aria-hidden attributes.
- Added UX learnings to .Jules/palette.md.

Co-authored-by: BilalkhanIO <48455259+BilalkhanIO@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

This pull request enhances the Login component with asynchronous loading state management, adds disabled button styling to Login and Signup components, implements accessibility improvements to the Navbar shopping cart link, and documents UX learning notes on ARIA label handling and submit button isolation.

Changes

Cohort / File(s) Summary
Documentation
.Jules/palette.md
New file documenting UX learning notes: ARIA label override behavior (recommending aria-hidden="true" for internal content) and submit button isolation best practice for improved focus management.
Login Component
fy-project/src/components/Login/Login.jsx, fy-project/src/components/Login/Login.css
Added isLoading state with 2-second async timeout simulation; button now displays "Logging in..." when disabled and "Login" otherwise. CSS introduces disabled button styling (opacity: 0.7, cursor: not-allowed).
Signup Component
fy-project/src/components/Signup/signup.css
Added disabled button styling matching Login component (opacity: 0.7, cursor: not-allowed).
Navbar Component
fy-project/src/components/Navbar/Navbar.jsx
Enhanced shopping cart link accessibility: added aria-label="View shopping cart, 3 items" to anchor, aria-hidden="true" to icon and cart count span.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A loading state springs to life with care,
With aria-labels floating through the air,
Disabled buttons rest with graceful fade,
Accessibility's where good UX is made! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: Login UX improvements (loading state, button isolation) and Navbar accessibility enhancements (ARIA attributes). It is specific, concise, and reflects the primary objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch palette-login-ux-navbar-a11y-3796880956653555443

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

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

Copy link

@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: 1

🤖 Fix all issues with AI agents
In `@fy-project/src/components/Login/Login.jsx`:
- Around line 20-28: Remove the console.log that prints email and password
inside handleSubmit to avoid credential exposure, and ensure the simulated
network setTimeout is cleaned up on component unmount: store the timeout id
(from setTimeout called in handleSubmit) in a ref (e.g., loginTimeoutRef), clear
that timeout in a useEffect cleanup (or clear it when handleSubmit finishes) and
guard setIsLoading calls so they only run while mounted (clearing timeout
prevents the post-delay setIsLoading(false)). Update references to handleSubmit,
setIsLoading, and the setTimeout call accordingly and do not log email or
password anywhere.
🧹 Nitpick comments (1)
fy-project/src/components/Navbar/Navbar.jsx (1)

24-26: Derive the aria-label from the same cart count source to avoid drift.

Proposed refactor (single source of truth)
 function Navbar() {
+    const cartCount = 3;
     return (
@@
-                    <a href='#addToCart' className='navbar__cart' aria-label="View shopping cart, 3 items">
+                    <a
+                      href='#addToCart'
+                      className='navbar__cart'
+                      aria-label={`View shopping cart, ${cartCount} item${cartCount === 1 ? '' : 's'}`}
+                    >
                         <FiShoppingBag className="navbar__cart-icon" aria-hidden="true" />
-                        <span className='navbar__cart_span' aria-hidden="true">3</span>
+                        <span className='navbar__cart_span' aria-hidden="true">{cartCount}</span>
                     </a>

Comment on lines 20 to +28
const handleSubmit = (event) => {
event.preventDefault();
// Perform login validation
console.log("Logging in with email:", email, " and password:", password);
setIsLoading(true);

// Simulate a network request
setTimeout(() => {
setIsLoading(false);
console.log("Logging in with email:", email, " and password:", password);
}, 2000);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n fy-project/src/components/Login/Login.jsx | head -50

Repository: BilalkhanIO/FYP

Length of output: 1762


🌐 Web query:

React 18 useEffect cleanup pattern setTimeout memory leak unmount

💡 Result:

In React 18, the safe pattern for setTimeout inside useEffect is:

useEffect(() => {
  const id = setTimeout(() => {
    // do work (optionally setState)
  }, 500);

  return () => clearTimeout(id); // runs on unmount + before re-run
}, []);

Why this fixes “memory leak / unmount” issues:

  • React calls your Effect’s cleanup on unmount and before re-running the Effect when dependencies change, so clearTimeout prevents a pending timer from firing after the component is gone. [1]
  • In React 18 Strict Mode (development only), React intentionally does an extra setup → cleanup → setup cycle to catch missing cleanup—so without clearTimeout, you can accidentally schedule duplicate timers and/or run work after the “test unmount.” [1][2]
  • The old warning (“Can’t perform a React state update on an unmounted component…”) was removed because it produced many false positives; you still should clean up real external resources like timers, subscriptions, listeners, etc. [3]

If your timeout callback does async work (or you want extra safety), combine cleanup with a cancel flag:

useEffect(() => {
  let cancelled = false;

  const id = setTimeout(async () => {
    const data = await somethingAsync();
    if (!cancelled) setState(data);
  }, 500);

  return () => {
    cancelled = true;
    clearTimeout(id);
  };
}, []);

Sources:
[1] React useEffect reference (setup/cleanup timing; Strict Mode extra cycle) https://react.dev/reference/react/useEffect
[2] React <StrictMode> reference (re-running Effects in dev to find missing cleanup) https://react.dev/reference/react/StrictMode
[3] React 18 working group: removal of “setState on unmounted component” warning reactwg/react-18#82


Remove credential logging and add timeout cleanup on unmount.

Logging passwords and emails exposes sensitive data (privacy/compliance risk), and the uncleared setTimeout will attempt state updates after unmount, causing warnings and potential errors in React 18 Strict Mode.

Proposed fix
-import React, { useState } from "react";
+import React, { useEffect, useRef, useState } from "react";
@@
   const [email, setEmail] = useState("");
   const [password, setPassword] = useState("");
   const [isLoading, setIsLoading] = useState(false);
+  const loginTimeoutRef = useRef(null);
@@
-    setTimeout(() => {
-      setIsLoading(false);
-      console.log("Logging in with email:", email, " and password:", password);
-    }, 2000);
+    loginTimeoutRef.current = window.setTimeout(() => {
+      setIsLoading(false);
+      console.log("Login submitted");
+    }, 2000);
   };
+
+  useEffect(() => {
+    return () => {
+      if (loginTimeoutRef.current !== null) {
+        clearTimeout(loginTimeoutRef.current);
+      }
+    };
+  }, []);
🤖 Prompt for AI Agents
In `@fy-project/src/components/Login/Login.jsx` around lines 20 - 28, Remove the
console.log that prints email and password inside handleSubmit to avoid
credential exposure, and ensure the simulated network setTimeout is cleaned up
on component unmount: store the timeout id (from setTimeout called in
handleSubmit) in a ref (e.g., loginTimeoutRef), clear that timeout in a
useEffect cleanup (or clear it when handleSubmit finishes) and guard
setIsLoading calls so they only run while mounted (clearing timeout prevents the
post-delay setIsLoading(false)). Update references to handleSubmit,
setIsLoading, and the setTimeout call accordingly and do not log email or
password anywhere.

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.

1 participant