Fix: Resolve dropdown conflicts between search and profile menus#4130
Fix: Resolve dropdown conflicts between search and profile menus#4130samay871 wants to merge 6 commits into
Conversation
- Replace single showDropdown state with searchDropdownOpen and profileDropdownOpen - Add mutual exclusion to prevent both dropdowns opening simultaneously - Integrate useClickOutside hook for independent closing - Add Escape key support to close both dropdowns - Fix race condition in search onBlur setTimeout
… hook for detecting outside clicks - Creates reusable hook for handling click outside elements - Supports both mouse and touch events - Used by Navbar for dropdown close functionality
|
@samay871 is attempting to deploy a commit to the Anurag Mishra's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Skipping CodeAnt AI review — this PR is a back-merge between long-lived branches ( If you want to analyze this anyway (e.g. you resolved conflicts with new logic), comment |
|
Warning Review limit reached
More reviews will be available in 14 minutes and 11 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughA new ChangesNavbar Decoupled Dropdown State
Email Verification Flow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/components/Navbar.jsx`:
- Around line 181-185: The onBlur handler schedules a delayed close of the
search dropdown, but if onFocus is triggered before that timeout completes, the
stale timeout will still fire and close the dropdown again, causing flicker.
Store the timeout ID returned by the setTimeout call (in the onBlur handler) in
a ref or state variable, then in the onFocus handler (before calling
openSearchDropdown), clear that stored timeout using clearTimeout. This prevents
the stale blur timer from closing a newly focused dropdown.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 66cb4b99-5a47-409b-b685-59709c1c5201
📒 Files selected for processing (2)
frontend/src/components/Navbar.jsxfrontend/src/hooks/useClickOutside.js
Add Firebase email verification trigger after successful email/password registration. Changes: - Import sendEmailVerification from Firebase Auth - Send verification email after createUserWithEmailAndPassword - Ensure newly registered accounts must verify email ownership This prevents unverified email accounts from entering the application flow.
Create a verification screen for users who have not verified their email. Features: - Display verification instructions - Show registered email address - Add resend verification email action - Add verification refresh action using user.reload() Allows users to continue after successful Firebase email verification.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/context/AuthProvider.jsx`:
- Around line 60-63: The sendEmailVerification call at line 62 is in the
hard-fail path and will cause the entire signup to fail if it throws an error,
even though the user account has already been successfully created at line 60 by
createUserWithEmailAndPassword. Wrap the sendEmailVerification call in a
try-catch block so that email verification failures are caught and logged
separately without causing the signup operation to fail. This allows the signup
process to complete successfully for the user even if the verification email
delivery fails due to network issues, rate limiting, or provider errors,
preventing confusing UX where users retry with the same email and encounter
"email already in use" errors.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2a8f59c6-e8f7-4832-b7b6-0c479782bd28
📒 Files selected for processing (1)
frontend/src/context/AuthProvider.jsx
| const result = await createUserWithEmailAndPassword(auth, email, password) | ||
|
|
||
| await sendEmailVerification(result.user) | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For Firebase JS SDK v11 (firebase/auth), does sendEmailVerification(user)reject on transient/provider errors aftercreateUserWithEmailAndPassword succeeds, and what handling pattern is recommended to avoid treating account creation as failed?
💡 Result:
In the Firebase JS SDK, the sendEmailVerification(user) function is an independent asynchronous operation that is decoupled from the createUserWithEmailAndPassword call [1][2]. Consequently, sendEmailVerification can reject with errors (such as auth/too-many-requests or auth/network-request-failed) even after a successful account creation [3][4][5]. Because createUserWithEmailAndPassword automatically signs the user in [6][7][8], the account is already persisted in Firebase Authentication by the time you attempt to send the verification email [5][9]. If the verification email fails to send, the user's account remains active and the user is still considered logged in [6][8]. Recommended Handling Pattern: To avoid treating the entire sign-up flow as a failure when only the email delivery fails, implement a decoupled error-handling strategy: 1. Separate Concerns: Do not block the application flow or treat account creation as a failure if sendEmailVerification throws an error [9]. 2. User Feedback: Inform the user that their account was created successfully, but that the verification email could not be sent immediately. Provide a UI mechanism (e.g., a "Resend Verification Email" button) to allow the user to retry the operation later [3][4]. 3. Graceful Error Handling: Catch the error from sendEmailVerification specifically, log it, and update the UI to notify the user without affecting their authenticated state [3][5]. Example Pattern: const { user } = await createUserWithEmailAndPassword(auth, email, password); try { await sendEmailVerification(user); // Notify user: "Account created! Please check your email." } catch (error) { console.error("Verification email failed:", error); // Notify user: "Account created, but we couldn't send the verification email. You can request a new one later." // Do not log the user out or delete the account. } This approach ensures that the account is preserved and the user can continue using the application, while still allowing them to eventually verify their email address [4][8].
Citations:
- 1: https://firebase.google.com/docs/auth/web/manage-users
- 2: https://stackoverflow.com/questions/71577312/send-verification-email-with-firebase-v9
- 3: Firebase sendEmailVerification error (too many requests)Title for the bug firebase/firebase-js-sdk#7733
- 4: 🐛 [Firebase_auth] Too-Many-Requests Error on sendEmailVerification after SignUp firebase/flutterfire#6481
- 5: https://stackoverflow.com/questions/45703554/firebase-email-verification-not-sending
- 6: https://stackoverflow.com/questions/76703779/blocking-functions-are-broken-and-unable-to-prevent-sign-in-before-verifying-ema
- 7: https://stackoverflow.com/questions/69376494/firebase-email-password-authentication-how-to-require-email-verification
- 8: https://stackoverflow.com/questions/72265441/is-there-a-way-to-generate-a-firebase-email-verification-link-before-a-user-is-a
- 9: https://stackoverflow.com/questions/77732623/email-verification-failing-before-link-is-sent-to-email
🏁 Script executed:
# First, find the AuthProvider.jsx file
fd -type f -name "AuthProvider.jsx"Repository: anurag3407/career-pilot
Length of output: 238
🏁 Script executed:
# Find the AuthProvider.jsx file
fd "AuthProvider.jsx"Repository: anurag3407/career-pilot
Length of output: 105
🏁 Script executed:
# Read the AuthProvider.jsx file to see lines 60-63
cat -n frontend/src/context/AuthProvider.jsx | sed -n '50,75p'Repository: anurag3407/career-pilot
Length of output: 1284
🏁 Script executed:
# Find and check Register.jsx to see how signup errors are handled
fd "Register.jsx" | head -5Repository: anurag3407/career-pilot
Length of output: 99
🏁 Script executed:
# Read Register.jsx to see how signup is called and errors are handled
cat -n frontend/src/pages/Register.jsx | head -150Repository: anurag3407/career-pilot
Length of output: 6024
Don't fail the whole signup on verification-email delivery failure.
At Line 62, sendEmailVerification is in the hard-fail path after account creation at Line 60. If that call throws (due to network issues, rate limiting, or provider errors), the caller sees signup failure even though the user already exists in Firebase, which creates a confusing UX where users retry with the same email and encounter "email already in use" errors.
Suggested fix
const result = await createUserWithEmailAndPassword(auth, email, password)
-
- await sendEmailVerification(result.user)
+ try {
+ await sendEmailVerification(result.user)
+ } catch (verificationError) {
+ // Account is already created; keep signup successful and handle notification separately.
+ console.warn('Failed to send verification email:', verificationError)
+ }📝 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.
| const result = await createUserWithEmailAndPassword(auth, email, password) | |
| await sendEmailVerification(result.user) | |
| const result = await createUserWithEmailAndPassword(auth, email, password) | |
| try { | |
| await sendEmailVerification(result.user) | |
| } catch (verificationError) { | |
| // Account is already created; keep signup successful and handle notification separately. | |
| console.warn('Failed to send verification email:', verificationError) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/context/AuthProvider.jsx` around lines 60 - 63, The
sendEmailVerification call at line 62 is in the hard-fail path and will cause
the entire signup to fail if it throws an error, even though the user account
has already been successfully created at line 60 by
createUserWithEmailAndPassword. Wrap the sendEmailVerification call in a
try-catch block so that email verification failures are caught and logged
separately without causing the signup operation to fail. This allows the signup
process to complete successfully for the user even if the verification email
delivery fails due to network issues, rate limiting, or provider errors,
preventing confusing UX where users retry with the same email and encounter
"email already in use" errors.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/components/EmailVerificationPrompt.jsx`:
- Around line 28-41: The checkVerification function lacks in-flight state
tracking, allowing users to trigger overlapping reload() calls that can
interleave message updates and race conditions. Add a loading or in-flight state
variable (similar to what the resendEmail function implements) to guard the
checkVerification async function so it cannot execute while already in progress.
Set this state to true before calling user.reload(), and set it to false in both
the success path (after navigating or setting message) and the catch block.
Ensure the resendEmail function at lines 62-74 follows the same pattern to
prevent overlapping operations between both asynchronous flows.
- Around line 13-33: Add guard checks in the checkVerification function before
invoking user.reload() and accessing user.emailVerified to verify that the user
object is a Firebase User instance (checking for the presence of required
methods/properties) to prevent runtime errors when running with the AuthProvider
dev-mode fallback mock user. Additionally, add disabled={loading} to the check
button element to prevent concurrent invocations when a verification check is
already in progress.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 742688fe-d797-446b-949b-4e5afb2869c1
📒 Files selected for processing (1)
frontend/src/components/EmailVerificationPrompt.jsx
| const resendEmail = async () => { | ||
| try { | ||
| setLoading(true); | ||
|
|
||
| await sendEmailVerification(user); | ||
|
|
||
| setMessage("Verification email sent successfully."); | ||
| } catch (error) { | ||
| setMessage(error.message); | ||
| } finally { | ||
| setLoading(false); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
| const checkVerification = async () => { | ||
| try { | ||
| await user.reload(); | ||
|
|
||
| if (user.emailVerified) { | ||
| navigate("/dashboard"); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify where EmailVerificationPrompt is rendered and inspect user-shape contracts.
rg -n -C3 "EmailVerificationPrompt|verify.*email|/dashboard" frontend/src
rg -n -C3 "setUser\\(|dev-user-001|emailVerified|reload|getIdToken" frontend/src/context/AuthProvider.jsxRepository: anurag3407/career-pilot
Length of output: 24364
🏁 Script executed:
cat -n frontend/src/components/EmailVerificationPrompt.jsxRepository: anurag3407/career-pilot
Length of output: 2544
🏁 Script executed:
rg -n "sendEmailVerification" frontend/src --type jsx --type js -A2 | head -30Repository: anurag3407/career-pilot
Length of output: 95
🏁 Script executed:
rg -n "sendEmailVerification" frontend/src --type js -B2 -A2Repository: anurag3407/career-pilot
Length of output: 1560
🏁 Script executed:
# Check if there are any tests or other usages of EmailVerificationPrompt that might reveal expected behavior
rg -n "EmailVerificationPrompt" frontend/src --type jsx --type jsRepository: anurag3407/career-pilot
Length of output: 95
🏁 Script executed:
# Check AuthProvider's full context around setUser and mock user creation
sed -n '25,50p' frontend/src/context/AuthProvider.jsxRepository: anurag3407/career-pilot
Length of output: 672
🏁 Script executed:
# Look for other components that use Firebase user methods safely
rg -n "user\.(reload|emailVerified)" frontend/src --type jsRepository: anurag3407/career-pilot
Length of output: 236
🏁 Script executed:
# Check if there are guards or utility functions for Firebase user checks elsewhere
rg -n "typeof.*function|reload.*function|emailVerified" frontend/src --type js -B2 -A1Repository: anurag3407/career-pilot
Length of output: 1180
Guard Firebase-user API calls before invoking verification methods.
Lines 30 and 32 assume user is a Firebase User object with reload() method and emailVerified property. The AuthProvider dev-mode fallback creates a mock user without these members, causing runtime errors in local development. Additionally, line 71's check button lacks a loading disabled state, allowing concurrent invocations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/components/EmailVerificationPrompt.jsx` around lines 13 - 33,
Add guard checks in the checkVerification function before invoking user.reload()
and accessing user.emailVerified to verify that the user object is a Firebase
User instance (checking for the presence of required methods/properties) to
prevent runtime errors when running with the AuthProvider dev-mode fallback mock
user. Additionally, add disabled={loading} to the check button element to
prevent concurrent invocations when a verification check is already in progress.
| const checkVerification = async () => { | ||
| try { | ||
| await user.reload(); | ||
|
|
||
| if (user.emailVerified) { | ||
| navigate("/dashboard"); | ||
| } else { | ||
| setMessage("Email is still not verified."); | ||
| } | ||
|
|
||
| } catch (error) { | ||
| setMessage(error.message); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Prevent overlapping async actions for resend/check flows.
checkVerification has no in-flight state while resendEmail does. On Line [71], users can trigger repeated reload() calls and interleave message updates with resend operations.
Suggested fix
const [message, setMessage] = useState("");
const [loading, setLoading] = useState(false);
+ const [checking, setChecking] = useState(false);
@@
const checkVerification = async () => {
try {
+ setChecking(true);
await user.reload();
@@
} catch (error) {
setMessage(error.message);
+ } finally {
+ setChecking(false);
}
};
@@
<button
onClick={resendEmail}
- disabled={loading || !canUseVerificationApis}
+ disabled={loading || checking || !canUseVerificationApis}
>
{loading ? "Sending..." : "Resend verification email"}
</button>
@@
<button
onClick={checkVerification}
- disabled={loading || !canUseVerificationApis}
+ disabled={loading || checking || !canUseVerificationApis}
>
- I've verified, continue
+ {checking ? "Checking..." : "I've verified, continue"}
</button>Also applies to: 62-74
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/components/EmailVerificationPrompt.jsx` around lines 28 - 41,
The checkVerification function lacks in-flight state tracking, allowing users to
trigger overlapping reload() calls that can interleave message updates and race
conditions. Add a loading or in-flight state variable (similar to what the
resendEmail function implements) to guard the checkVerification async function
so it cannot execute while already in progress. Set this state to true before
calling user.reload(), and set it to false in both the success path (after
navigating or setting message) and the catch block. Ensure the resendEmail
function at lines 62-74 follows the same pattern to prevent overlapping
operations between both asynchronous flows.
Add email verification protection to authenticated routes. Changes: - Add EmailVerificationPrompt integration - Check user.emailVerified inside ProtectedRoute - Prevent unverified users from accessing protected pages Verified users continue to access the application normally.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Changes Made
showDropdownstate withsearchDropdownOpenandprofileDropdownOpenuseClickOutsidecustom hook for click-outside detectionTesting
Summary by CodeRabbit
Release Notes
New Features
Improvements