Skip to content

🎨 Palette: Add Loading State to Login Button#29

Open
BilalkhanIO wants to merge 1 commit intomainfrom
palette-login-loading-state-17085105205676504075
Open

🎨 Palette: Add Loading State to Login Button#29
BilalkhanIO wants to merge 1 commit intomainfrom
palette-login-loading-state-17085105205676504075

Conversation

@BilalkhanIO
Copy link
Owner

@BilalkhanIO BilalkhanIO commented Jan 29, 2026

This change introduces a loading state to the login button to provide better user feedback during form submission. When the user clicks "Login", the button is now disabled and its text changes to "Logging in..." for the duration of the simulated network request. This prevents duplicate submissions and makes the interface feel more responsive.

The implementation includes:

  • An isLoading state variable in the Login.jsx component.
  • Updated handleSubmit logic to manage the loading state.
  • Conditional rendering of the button's text and disabled attribute.
  • A minor structural improvement, separating the "Forgot password" link into its own list item for better semantic HTML.

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

Summary by CodeRabbit

  • New Features
    • Enhanced login experience with real-time loading feedback. The login button now displays "Logging in..." and becomes disabled during authentication to prevent duplicate submissions and provide clear visual feedback to users about the in-progress login state.

✏️ Tip: You can customize this high-level summary in your review settings.

💡 What:
- Added an `isLoading` state to the login form.
- The "Login" button is now disabled and its text changes to "Logging in..." during the simulated form submission.

🎯 Why:
- Provides immediate visual feedback to the user that their action has been registered.
- Prevents users from clicking the login button multiple times, which could lead to duplicate requests.
- Improves the overall perceived responsiveness of the application.

📸 Before/After:
- **Before:** Clicking "Login" gave no visual feedback. The button remained active.
- **After:** The button enters a disabled, loading state, as shown in the verification screenshot.

♿ Accessibility:
- Disabling the button during submission prevents accidental re-submission from keyboard or screen reader users.
- The change in button text provides a clear status update for users of assistive technologies.

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 Jan 29, 2026

📝 Walkthrough

Walkthrough

A Login component was enhanced with loading state management. During login submission, an internal isLoading state toggles true for 2 seconds to simulate network delay, disabling the submit button and changing its label to "Logging in..." during the simulated request.

Changes

Cohort / File(s) Summary
Login Component Enhancement
fy-project/src/components/Login/Login.jsx
Added internal loading state using useState(false). On login submission, isLoading is set to true, triggering a 2-second simulated network delay via setTimeout. Button is disabled when loading and displays "Logging in..." text; reverts to "Login" when loading completes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A button once eager, now learns to be patient,
"Logging in..." it declares with such graceful persuasion,
Two seconds of waiting, then back to its post,
User feedback achieved—no longer a ghost! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
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.
Title check ❓ Inconclusive The title includes an emoji and uses vague branding language ('Palette') that doesn't clearly communicate the main change to someone unfamiliar with the codebase. Consider simplifying to a clear, emoji-free title like 'Add loading state to login button' that directly describes the primary change without decorative elements.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings

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-29: The handleSubmit currently starts a setTimeout and calls
setIsLoading(false) without cleanup; store the timeout id (e.g., const timeoutId
= setTimeout(...)) and clear it on unmount (useEffect cleanup or a useRef to
hold the id and call clearTimeout(timeoutId) in a cleanup function) so
setIsLoading isn't called after unmount, and when replacing the simulated delay
with a real API call wrap the request in try/finally (or use an AbortController)
to ensure setIsLoading(false) runs regardless of success/error and to cancel
in-flight requests on unmount; update references to handleSubmit, setTimeout,
setIsLoading, and add useEffect/useRef/AbortController as needed.

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

// Simulate a network request
setTimeout(() => {
setIsLoading(false);
}, 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 | 🟡 Minor

Memory leak: setTimeout should be cleaned up on unmount.

If the component unmounts before the 2-second timeout completes (e.g., user navigates away), the setIsLoading(false) call will attempt to update state on an unmounted component, causing a React warning and potential memory leak.

When you replace this simulated delay with a real API call, also wrap the state reset in a try/finally block to ensure isLoading is always cleared, even on errors.

🛠️ Proposed fix using useEffect cleanup
+import React, { useState, useEffect, useRef } from "react";
-import React, { useState } from "react";
 function Login() {
   const [email, setEmail] = useState("");
   const [password, setPassword] = useState("");
   const [isLoading, setIsLoading] = useState(false);
+  const timeoutRef = useRef(null);
+
+  useEffect(() => {
+    return () => {
+      if (timeoutRef.current) {
+        clearTimeout(timeoutRef.current);
+      }
+    };
+  }, []);
   const handleSubmit = (event) => {
     event.preventDefault();
     setIsLoading(true);
     // Perform login validation
     console.log("Logging in with email:", email, " and password:", password);
     // Simulate a network request
-    setTimeout(() => {
+    timeoutRef.current = setTimeout(() => {
       setIsLoading(false);
     }, 2000);
   };
📝 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
const handleSubmit = (event) => {
event.preventDefault();
setIsLoading(true);
// Perform login validation
console.log("Logging in with email:", email, " and password:", password);
// Simulate a network request
setTimeout(() => {
setIsLoading(false);
}, 2000);
};
import React, { useState, useEffect, useRef } from "react";
function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [isLoading, setIsLoading] = useState(false);
const timeoutRef = useRef(null);
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
const handleSubmit = (event) => {
event.preventDefault();
setIsLoading(true);
// Perform login validation
console.log("Logging in with email:", email, " and password:", password);
// Simulate a network request
timeoutRef.current = setTimeout(() => {
setIsLoading(false);
}, 2000);
};
🤖 Prompt for AI Agents
In `@fy-project/src/components/Login/Login.jsx` around lines 20 - 29, The
handleSubmit currently starts a setTimeout and calls setIsLoading(false) without
cleanup; store the timeout id (e.g., const timeoutId = setTimeout(...)) and
clear it on unmount (useEffect cleanup or a useRef to hold the id and call
clearTimeout(timeoutId) in a cleanup function) so setIsLoading isn't called
after unmount, and when replacing the simulated delay with a real API call wrap
the request in try/finally (or use an AbortController) to ensure
setIsLoading(false) runs regardless of success/error and to cancel in-flight
requests on unmount; update references to handleSubmit, setTimeout,
setIsLoading, and add useEffect/useRef/AbortController as needed.

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