Skip to content

feat: improve mobile responsiveness and auth UX (closes #413)#851

Open
singhanurag0317-bit wants to merge 1 commit into
ritesh-1918:mainfrom
singhanurag0317-bit:feat/mobile-responsiveness-413
Open

feat: improve mobile responsiveness and auth UX (closes #413)#851
singhanurag0317-bit wants to merge 1 commit into
ritesh-1918:mainfrom
singhanurag0317-bit:feat/mobile-responsiveness-413

Conversation

@singhanurag0317-bit
Copy link
Copy Markdown

@singhanurag0317-bit singhanurag0317-bit commented May 31, 2026

Description

This pull request resolves Issue #413 ("Improve Mobile Responsiveness and Authentication UX") by modernizing the layouts, responsive styles, navigation capabilities, and widgets in the frontend client.

Key Improvements

  1. Authentication Store & Session Sync:

    • Created loginWithGoogle inside authStore.js leveraging Supabase OAuth with a dynamic origin redirect target.
    • Enhanced getProfile to automatically detect confirmed user sessions (user.email_confirmed_at) and dynamically update profiles from pending_email_verification to pending_approval locally and in the database to prevent redirection loops.
  2. Global Themes & Adaptive Headers:

    • Initialized and synced the dark/light mode state using localStorage with system default fallback (prefers-color-scheme) inside App.jsx.
    • Embedded interactive Sun/Moon theme switcher buttons in TopNav.jsx (both desktop header and mobile navigation menu) and AdminHeader.jsx.
    • Styled base container boundaries (UserLayout.jsx and AdminLayout.jsx) with theme-aware transition-colors backgrounds (dark:bg-[#102219] dark:text-slate-100).
  3. Refactored Onboarding Screens:

    • Replaced heavy inline styling with standard Tailwind dark-mode classes across Login.jsx, Signup.jsx, ForgotPassword.jsx, ResetPassword.jsx, and AdminSignup.jsx.
    • Exposed beautiful Google Sign-In and Sign-Up action triggers.
    • Fixed "Back to Home" absolute elements to utilize natural-flow layout positioning on mobile screens to prevent interface overlaps.
    • Resolved a style key compilation bug inside the Admin step wizard (AdminSignup.jsx).
  4. Responsive Diagnostics Widget:

    • Collapsed the floating BugReportWidget.jsx text-badge into a minimal circular icon button on screen sizes smaller than md (hidden md:block), freeing up precious screen space.
    • Moved positioning parameters to bottom-4 right-4 on mobile and md:bottom-6 md:right-6 on desktop.

Verification

  • Ran full production compilation (npm run build) in Frontend successfully:
    dist/index.html                     1.69 kB
    dist/assets/index-DMZR6E-d.css    130.32 kB
    dist/assets/index-BTaNHvCa.js   2,223.31 kB
    ✓ built in 27.52s

Summary by CodeRabbit

Release Notes

  • New Features

    • Added dark/light theme toggle throughout the app with automatic system preference detection and persistent settings.
    • Introduced Google login option for faster authentication.
    • Enhanced profile status handling during signup flow with improved user routing.
  • Style

    • Redesigned UI across all authentication and admin pages with dark-mode support and improved visual hierarchy.
    • Updated responsive layouts and styling for better usability on mobile and desktop devices.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements dark mode theming across the frontend with Tailwind CSS and localStorage persistence, integrates Google OAuth login, updates post-signup routing to handle pending email verification states, redesigns authentication pages with new UI styling, and refines responsive design breakpoints.

Changes

Dark Mode Theme and Authentication Infrastructure

Layer / File(s) Summary
App initialization and authStore enhancements
Frontend/src/App.jsx, Frontend/src/store/authStore.js
App.jsx initializes dark/light theme on mount from localStorage and system preference, syncing the dark class to document root. authStore updates getProfile to distinguish email confirmation states and upgrades DB profiles when auth confirms email; adds loginWithGoogle action for Google OAuth sign-in.
Component theme toggles and dark mode state
Frontend/src/admin/components/AdminHeader.jsx, Frontend/src/user/components/TopNav.jsx
AdminHeader and TopNav add isDark state initialized from the DOM root dark class, define toggleTheme handlers updating both the class and localStorage, and wire Sun/Moon theme toggle buttons with dark-mode Tailwind variants throughout header/nav UI, dropdowns, and mobile overlays.
Layout containers dark mode support
Frontend/src/admin/layout/AdminLayout.jsx, Frontend/src/user/UserLayout.jsx
AdminLayout and UserLayout add dark-mode background color classes and transition utilities to their root containers for consistent dark theming.

Authentication Pages Redesign and Google OAuth Integration

Layer / File(s) Summary
Login page with Google OAuth and UI overhaul
Frontend/src/pages/Login.jsx
Login.jsx adds loginWithGoogle from authStore, implements handleGoogleLogin handler, wires a "Continue with Google" button, and completely reworks the page layout with new Tailwind classes and dark-mode variants while preserving password/magic-link mode logic.
Signup page redesign with Google integration and pending approval routing
Frontend/src/pages/Signup.jsx
Signup.jsx adds Google OAuth support via loginWithGoogle and handleGoogleSignup, updates post-signup routing to /user-lobby when profile.status is pending_approval, and refactors the entire form UI with new Tailwind styling, dark-mode variants, required input attributes, and improved company dropdown/checklist styling.
AdminSignup page redesign with pending approval routing
Frontend/src/pages/AdminSignup.jsx
AdminSignup.jsx updates post-signup flow to route to /admin-lobby on pending_approval status and refactors the entire multi-step form with new Tailwind/dark-mode styling, responsive design, updated progress indicators, button styling, password strength display, and footer content across all three steps while preserving validation and submission behavior.
Password recovery pages redesign with dark mode support
Frontend/src/pages/ResetPassword.jsx, Frontend/src/pages/ForgotPassword.jsx
ResetPassword and ForgotPassword are redesigned with gradient backgrounds, dark-mode Tailwind classes, and updated form styling. ResetPassword adds "Back to Login" link; both pages refactor header/step containers, error/success banners, and all form inputs while preserving the same password reset flow logic.
Bug report widget responsive refinement
Frontend/src/components/shared/BugReportWidget.jsx
BugReportWidget updates the floating trigger button's responsive Tailwind classes for positioning/padding and adjusts text visibility to the md breakpoint.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • ritesh-1918/HELPDESK.AI#413: This PR directly addresses the issue by implementing dark-mode theme toggles across App/TopNav/AdminHeader, adding Google OAuth support, updating post-signup/verification routing, and redesigning auth pages with responsive UI.

Possibly related PRs

  • ritesh-1918/HELPDESK.AI#753: Dark-mode implementation in TopNav, App.jsx, and theme class/localStorage handling overlaps directly with this PR's global theming infrastructure.

Suggested labels

gssoc, gssoc:approved, level:advanced, type:feature

Poem

🐰 A hop through dark and light so bright,
Theme toggles dancing left and right,
Google's hand joins the signup dance,
Dark mode clothes in CSS romance,
From login halls to signup floors,
The rabbit cheers at feature doors! 🌙✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: improve mobile responsiveness and auth UX' accurately reflects the primary changes: responsive design improvements (BugReportWidget mobile adjustments, Tailwind refactoring) and authentication UX enhancements (Google OAuth, theme switching, profile state handling).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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
Copy Markdown

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Frontend/src/pages/Signup.jsx (1)

251-307: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

The required company picker is mouse-only.

The trigger and options are plain divs with click handlers, so keyboard users can't properly open, navigate, or select a company. Since this field is required, that blocks signup. Please switch this to an actual button/listbox-combobox pattern or a native/select-based control.

🤖 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/pages/Signup.jsx` around lines 251 - 307, The company picker
uses plain divs and is inaccessible to keyboard users; replace the clickable div
trigger and option divs with an accessible control (either a native <select> or
an ARIA Listbox/Combobox) and add keyboard handling/focus management.
Specifically, change the trigger that currently uses
setIsDropdownOpen/isDropdownOpen and selectedCompany into a button or Listbox
trigger with aria-haspopup, aria-expanded and aria-required, ensure the search
input (companySearch/setCompanySearch) stops propagation but is focusable,
render each filteredCompanies item with role="option"/tabindex and aria-selected
and wire keyboard handlers (Enter/Space to select via setSelectedCompany,
ArrowUp/ArrowDown to move focus, Escape to close via setIsDropdownOpen(false)).
Also ensure the option onClick behavior (setSelectedCompany, setIsDropdownOpen,
setCompanySearch) is mirrored for keyboard activation and that focus moves
appropriately after selection.
Frontend/src/pages/ForgotPassword.jsx (1)

98-103: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent password length requirement with ResetPassword page.

This validation requires a minimum of 6 characters, while ResetPassword.jsx (line 28) requires 8 characters. Users might encounter different password requirements depending on which recovery flow they use, which can be confusing.

Recommend standardizing the minimum password length across both password reset flows.

🔧 Suggested fix to align with ResetPassword.jsx
-        if (!newPassword || newPassword.length < 6) {
-            setError("Password must be at least 6 characters long.");
+        if (!newPassword || newPassword.length < 8) {
+            setError("Password must be at least 8 characters long.");
             return;
         }
🤖 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/pages/ForgotPassword.jsx` around lines 98 - 103, The password
minimum length in the ForgotPassword flow is inconsistent: update the validation
inside handleUpdatePassword to require the same minimum as ResetPassword (use 8
characters) so both flows match; locate handleUpdatePassword in
ForgotPassword.jsx and change the check/validation message from 6 to 8
characters to mirror ResetPassword.jsx's requirement and ensure any UI/error
text there is updated accordingly.
🧹 Nitpick comments (2)
Frontend/src/admin/components/AdminHeader.jsx (1)

23-38: ⚡ Quick win

Extract theme toggle logic to a shared custom hook.

The theme toggle implementation (state initialization, DOM class sync, localStorage persistence) is duplicated verbatim in TopNav.jsx (lines 20-36). Consider extracting this logic into a custom hook like useTheme() to eliminate duplication and ensure consistent behavior across both components.

♻️ Example custom hook

Create Frontend/src/hooks/useTheme.js:

import { useState, useEffect } from 'react';

export const useTheme = () => {
    const [isDark, setIsDark] = useState(() => 
        document.documentElement.classList.contains('dark')
    );

    useEffect(() => {
        setIsDark(document.documentElement.classList.contains('dark'));
    }, []);

    const toggleTheme = () => {
        const nextDark = !isDark;
        setIsDark(nextDark);
        if (nextDark) {
            document.documentElement.classList.add('dark');
            localStorage.setItem('theme', 'dark');
        } else {
            document.documentElement.classList.remove('dark');
            localStorage.setItem('theme', 'light');
        }
    };

    return { isDark, toggleTheme };
};

Then replace lines 23-38 in both AdminHeader.jsx and TopNav.jsx with:

-const [isDark, setIsDark] = useState(false);
-useEffect(() => {
-    setIsDark(document.documentElement.classList.contains('dark'));
-}, []);
-
-const toggleTheme = () => {
-    const nextDark = !isDark;
-    setIsDark(nextDark);
-    if (nextDark) {
-        document.documentElement.classList.add('dark');
-        localStorage.setItem('theme', 'dark');
-    } else {
-        document.documentElement.classList.remove('dark');
-        localStorage.setItem('theme', 'light');
-    }
-};
+const { isDark, toggleTheme } = useTheme();
🤖 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/admin/components/AdminHeader.jsx` around lines 23 - 38, Extract
the duplicated theme logic into a shared custom hook named useTheme: create and
export a hook (export const useTheme) that initializes isDark from
document.documentElement.classList.contains('dark'), keeps DOM sync in a
useEffect, and exposes a toggleTheme that flips isDark, updates
document.documentElement.classList and writes 'theme' to localStorage; then
remove the local useState/useEffect/toggleTheme blocks from AdminHeader.jsx and
TopNav.jsx and replace them with an import of useTheme and use the returned {
isDark, toggleTheme } values.
Frontend/src/pages/ForgotPassword.jsx (1)

241-284: 💤 Low value

Consider using Tailwind color utilities for disabled state.

Line 268 uses hardcoded hex colors for the disabled button state (disabled:bg-[#e5e7eb] dark:disabled:bg-[#223c2f]), which is inconsistent with the rest of the codebase that uses Tailwind's color scale (e.g., bg-emerald-600, text-slate-400).

Consider using standard Tailwind utilities:

♻️ Suggested refactor for consistency
-                                            className="w-full rounded-2xl py-4 font-bold transition-all flex items-center justify-center gap-2 text-white bg-gradient-to-r from-emerald-600 to-emerald-500 shadow-lg shadow-emerald-600/20 disabled:bg-[`#e5e7eb`] dark:disabled:bg-[`#223c2f`] disabled:text-[`#9ca3af`] disabled:shadow-none"
+                                            className="w-full rounded-2xl py-4 font-bold transition-all flex items-center justify-center gap-2 text-white bg-gradient-to-r from-emerald-600 to-emerald-500 shadow-lg shadow-emerald-600/20 disabled:bg-gray-200 dark:disabled:bg-gray-800 disabled:text-gray-400 disabled:shadow-none"
🤖 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/pages/ForgotPassword.jsx` around lines 241 - 284, Replace the
hardcoded hex disabled colors on the submit button in the STEP 2 OTP form with
Tailwind color utilities for consistency: in the button that uses
loading/otp/timerExpired state (the type="submit" button rendering "Verify
Identity Signature") swap disabled:bg-[`#e5e7eb`] for a Tailwind utility like
disabled:bg-slate-200 and dark:disabled:bg-slate-800, and replace
disabled:text-[`#9ca3af`] with disabled:text-slate-400 (keep
disabled:shadow-none). This change ensures consistency with existing classes
(e.g., bg-emerald-600, text-slate-400) and touches the JSX element that
references loading, otp, timerExpired and uses onMouseEnter/onMouseLeave.
🤖 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/pages/Login.jsx`:
- Around line 101-108: The Google login catch currently sets a generic message;
update handleGoogleLogin to normalize errors the same way as the
password/magic-link handlers by reusing the same normalization logic (e.g. call
the same helper used in those handlers or replicate its checks) before calling
setError, so failures like fetch/AdBlock or Supabase-specific errors are
detected and produce the same diagnostic text; locate handleGoogleLogin and
loginWithGoogle and replace the catch body to pass err through the existing
normalization function (or inline its checks for fetch failures and Supabase
error fields) and then call setError(normalizedMessage).

In `@Frontend/src/pages/Signup.jsx`:
- Around line 172-179: handleGoogleSignup currently calls loginWithGoogle()
which completes OAuth but drops the signup form context (fullName,
selectedCompany, role "user", company_id), allowing users to bypass required
signup data; update handleGoogleSignup to preserve and forward the signup fields
after the OAuth flow (or block completion until they are provided): after
loginWithGoogle resolves, call the profile-creation path that accepts the OAuth
token plus fullName, selectedCompany (or its id as company_id), and role "user"
(e.g., a helper like createProfileWithGoogle / completeSignupWithOAuth), or
redirect back to the Signup form with the OAuth result so the user must submit
those fields before finalizing account creation. Ensure you reference and
populate the unique symbols fullName, selectedCompany/company_id and role when
creating the user profile.

In `@Frontend/src/store/authStore.js`:
- Around line 49-53: The upgrade path that calls get().updateProfile({ status:
'pending_approval' }) when user.email_confirmed_at && dbProfile.status ===
'pending_email_verification' must be wrapped in a try/catch: inside the try call
updateProfile and return the updated result if truthy; in catch log the error
(including context like user.id or email) and fall back to returning dbProfile
so calling sites (e.g., getCurrentUser and the initialize auth listener) don’t
get an unhandled rejection; ensure you reference the existing dbProfile and
updateProfile symbols and preserve the existing console message when successful.

---

Outside diff comments:
In `@Frontend/src/pages/ForgotPassword.jsx`:
- Around line 98-103: The password minimum length in the ForgotPassword flow is
inconsistent: update the validation inside handleUpdatePassword to require the
same minimum as ResetPassword (use 8 characters) so both flows match; locate
handleUpdatePassword in ForgotPassword.jsx and change the check/validation
message from 6 to 8 characters to mirror ResetPassword.jsx's requirement and
ensure any UI/error text there is updated accordingly.

In `@Frontend/src/pages/Signup.jsx`:
- Around line 251-307: The company picker uses plain divs and is inaccessible to
keyboard users; replace the clickable div trigger and option divs with an
accessible control (either a native <select> or an ARIA Listbox/Combobox) and
add keyboard handling/focus management. Specifically, change the trigger that
currently uses setIsDropdownOpen/isDropdownOpen and selectedCompany into a
button or Listbox trigger with aria-haspopup, aria-expanded and aria-required,
ensure the search input (companySearch/setCompanySearch) stops propagation but
is focusable, render each filteredCompanies item with role="option"/tabindex and
aria-selected and wire keyboard handlers (Enter/Space to select via
setSelectedCompany, ArrowUp/ArrowDown to move focus, Escape to close via
setIsDropdownOpen(false)). Also ensure the option onClick behavior
(setSelectedCompany, setIsDropdownOpen, setCompanySearch) is mirrored for
keyboard activation and that focus moves appropriately after selection.

---

Nitpick comments:
In `@Frontend/src/admin/components/AdminHeader.jsx`:
- Around line 23-38: Extract the duplicated theme logic into a shared custom
hook named useTheme: create and export a hook (export const useTheme) that
initializes isDark from document.documentElement.classList.contains('dark'),
keeps DOM sync in a useEffect, and exposes a toggleTheme that flips isDark,
updates document.documentElement.classList and writes 'theme' to localStorage;
then remove the local useState/useEffect/toggleTheme blocks from AdminHeader.jsx
and TopNav.jsx and replace them with an import of useTheme and use the returned
{ isDark, toggleTheme } values.

In `@Frontend/src/pages/ForgotPassword.jsx`:
- Around line 241-284: Replace the hardcoded hex disabled colors on the submit
button in the STEP 2 OTP form with Tailwind color utilities for consistency: in
the button that uses loading/otp/timerExpired state (the type="submit" button
rendering "Verify Identity Signature") swap disabled:bg-[`#e5e7eb`] for a Tailwind
utility like disabled:bg-slate-200 and dark:disabled:bg-slate-800, and replace
disabled:text-[`#9ca3af`] with disabled:text-slate-400 (keep
disabled:shadow-none). This change ensures consistency with existing classes
(e.g., bg-emerald-600, text-slate-400) and touches the JSX element that
references loading, otp, timerExpired and uses onMouseEnter/onMouseLeave.
🪄 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: 878ae2eb-26f7-4144-9925-11f0e5966f24

📥 Commits

Reviewing files that changed from the base of the PR and between da8faf2 and 4ef270d.

📒 Files selected for processing (12)
  • Frontend/src/App.jsx
  • Frontend/src/admin/components/AdminHeader.jsx
  • Frontend/src/admin/layout/AdminLayout.jsx
  • Frontend/src/components/shared/BugReportWidget.jsx
  • Frontend/src/pages/AdminSignup.jsx
  • Frontend/src/pages/ForgotPassword.jsx
  • Frontend/src/pages/Login.jsx
  • Frontend/src/pages/ResetPassword.jsx
  • Frontend/src/pages/Signup.jsx
  • Frontend/src/store/authStore.js
  • Frontend/src/user/UserLayout.jsx
  • Frontend/src/user/components/TopNav.jsx

Comment on lines +101 to +108
const handleGoogleLogin = async () => {
try {
setError("");
await loginWithGoogle();
} catch (err) {
console.error("Google login error:", err);
setError(err.message || "Google Sign-In failed.");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize Google OAuth fetch failures the same way as the other auth paths.

This new handler falls back to a generic error, so the Google flow loses the ad-blocker/Supabase diagnostic you already added for password and magic-link sign-in.

Suggested fix
  const handleGoogleLogin = async () => {
    try {
      setError("");
      await loginWithGoogle();
    } catch (err) {
      console.error("Google login error:", err);
-      setError(err.message || "Google Sign-In failed.");
+      let errMsg = err.message || "Google Sign-In failed.";
+      if (errMsg.toLowerCase().includes("failed to fetch")) {
+        errMsg = "Network Error: Failed to fetch. This usually happens if your browser's ad-blocker is blocking Supabase requests. Please try disabling your ad-blocker for this site and refresh!";
+      }
+      setError(errMsg);
    }
  };
🤖 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/pages/Login.jsx` around lines 101 - 108, The Google login catch
currently sets a generic message; update handleGoogleLogin to normalize errors
the same way as the password/magic-link handlers by reusing the same
normalization logic (e.g. call the same helper used in those handlers or
replicate its checks) before calling setError, so failures like fetch/AdBlock or
Supabase-specific errors are detected and produce the same diagnostic text;
locate handleGoogleLogin and loginWithGoogle and replace the catch body to pass
err through the existing normalization function (or inline its checks for fetch
failures and Supabase error fields) and then call setError(normalizedMessage).

Comment on lines +172 to +179
const handleGoogleSignup = async () => {
try {
setError("");
await loginWithGoogle();
} catch (err) {
console.error("Google signup error:", err);
setError(err.message || "Google Sign-up failed.");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

This Google path bypasses the required signup data.

loginWithGoogle() starts the same OAuth flow as login, but this page's signup contract depends on fullName, selectedCompany, role "user", and company_id being carried into profile creation. Right now a user can leave this screen through Google without any of that context, so the pending-approval/company-association flow can’t be completed reliably.

🤖 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/pages/Signup.jsx` around lines 172 - 179, handleGoogleSignup
currently calls loginWithGoogle() which completes OAuth but drops the signup
form context (fullName, selectedCompany, role "user", company_id), allowing
users to bypass required signup data; update handleGoogleSignup to preserve and
forward the signup fields after the OAuth flow (or block completion until they
are provided): after loginWithGoogle resolves, call the profile-creation path
that accepts the OAuth token plus fullName, selectedCompany (or its id as
company_id), and role "user" (e.g., a helper like createProfileWithGoogle /
completeSignupWithOAuth), or redirect back to the Signup form with the OAuth
result so the user must submit those fields before finalizing account creation.
Ensure you reference and populate the unique symbols fullName,
selectedCompany/company_id and role when creating the user profile.

Comment on lines +49 to +53
if (user.email_confirmed_at && dbProfile.status === 'pending_email_verification') {
console.log("Email confirmed! Upgrading status in database to pending_approval.");
const updated = await get().updateProfile({ status: 'pending_approval' });
if (updated) return updated;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add error handling for the profile status upgrade.

When updateProfile is called here to upgrade pending_email_verification to pending_approval, errors are not caught. Since getProfile is invoked without await in getCurrentUser (line 94) and the initialize auth listener (line 308), a thrown error from updateProfile will result in an unhandled promise rejection in those code paths.

Wrap the upgrade call in a try/catch block to prevent console errors and ensure the function gracefully falls back to returning dbProfile if the update fails.

🛡️ Proposed fix
 if (user.email_confirmed_at && dbProfile.status === 'pending_email_verification') {
     console.log("Email confirmed! Upgrading status in database to pending_approval.");
-    const updated = await get().updateProfile({ status: 'pending_approval' });
-    if (updated) return updated;
+    try {
+        const updated = await get().updateProfile({ status: 'pending_approval' });
+        if (updated) return updated;
+    } catch (err) {
+        console.warn("Profile status upgrade failed, continuing with DB profile:", err);
+    }
 }
📝 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
if (user.email_confirmed_at && dbProfile.status === 'pending_email_verification') {
console.log("Email confirmed! Upgrading status in database to pending_approval.");
const updated = await get().updateProfile({ status: 'pending_approval' });
if (updated) return updated;
}
if (user.email_confirmed_at && dbProfile.status === 'pending_email_verification') {
console.log("Email confirmed! Upgrading status in database to pending_approval.");
try {
const updated = await get().updateProfile({ status: 'pending_approval' });
if (updated) return updated;
} catch (err) {
console.warn("Profile status upgrade failed, continuing with DB profile:", err);
}
}
🤖 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/store/authStore.js` around lines 49 - 53, The upgrade path that
calls get().updateProfile({ status: 'pending_approval' }) when
user.email_confirmed_at && dbProfile.status === 'pending_email_verification'
must be wrapped in a try/catch: inside the try call updateProfile and return the
updated result if truthy; in catch log the error (including context like user.id
or email) and fall back to returning dbProfile so calling sites (e.g.,
getCurrentUser and the initialize auth listener) don’t get an unhandled
rejection; ensure you reference the existing dbProfile and updateProfile symbols
and preserve the existing console message when successful.

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