Skip to content

Fix/notification bar theme sync#340

Open
compiler041 wants to merge 2 commits intoAOSSIE-Org:mainfrom
compiler041:fix/notification-bar-theme-sync
Open

Fix/notification bar theme sync#340
compiler041 wants to merge 2 commits intoAOSSIE-Org:mainfrom
compiler041:fix/notification-bar-theme-sync

Conversation

@compiler041
Copy link
Contributor

@compiler041 compiler041 commented Feb 28, 2026

Addressed Issues:

Fixes #338

Additional Notes:

Header.tsx was using hardcoded Tailwind color classes like text-gray-900, bg-gray-50, bg-white and border-gray-100 throughout the notification panel, profile popover and mobile drawer. These classes are light-mode-only and do not respond to theme changes, causing the UI to break in dark and system modes — text becomes unreadable and backgrounds don't adapt.

All hardcoded colors have been replaced with semantic Tailwind theme tokens that automatically adapt to the active theme:

Before After
text-gray-900 text-foreground / text-popover-foreground
bg-white / bg-gray-50 bg-background / bg-popover
text-gray-500 text-muted-foreground
border-gray-100 border-border
hover:bg-gray-50 hover:bg-accent
bg-gray-100 bg-muted
bg-blue-50/50 bg-blue-500/10

No logic or functionality was changed — this is a styling-only fix affecting only Header.tsx.

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.

AI Usage Disclosure

  • This PR contains AI-generated code. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: Claude (Anthropic) — used to identify hardcoded color classes and suggest semantic Tailwind token replacements. All changes were reviewed and tested locally across light, dark and system modes.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added email autocomplete suggestions in authentication forms
    • Integrated Google login functionality
    • Enhanced password validation with minimum length requirements
  • Bug Fixes & Improvements

    • Improved error message display and formatting in authentication flows
    • Added client-side email validation with user-facing error messages
    • Added delete button and unread indicators to notifications panel
  • UI/UX Updates

    • Refreshed header and notifications design with updated styling
    • Enhanced mobile navigation drawer and menu layout

@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Walkthrough

This pull request enhances form authentication with email autocomplete via a new EmailInputWithSuggestions component, adds client-side email and password validation, and updates the Header component's UI styling with new design tokens and a reorganized mobile navigation drawer.

Changes

Cohort / File(s) Summary
Authentication Forms
frontend/src/Pages/Authentication/forms.tsx
Introduces EmailInputWithSuggestions component for email autocomplete with keyboard/mouse interactions. Adds validateEmail function and password validation rules. Replaces direct email inputs across LoginForm, SignUpForm, and ForgotPasswordForm. Improves error message rendering and integrates updated Google login flow. Public API signatures unchanged.
Header Component
frontend/src/components/Header.tsx
Replaces Tailwind utility classes with new design tokens throughout (border-border, bg-background, text-muted-foreground, etc.). Overhauls notifications panel with unread indicators, delete buttons, and updated styling. Redesigns avatar/profile popover and sign-out button. Introduces mobile drawer with backdrop overlay and reorganized navigation items. No fundamental logic changes to notification or navigation behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Possibly related PRs

Suggested reviewers

  • bhavik-mangla

Poem

🐰 New forms with suggestions so bright,
Emails autocomplete—what a delight!
Headers now styled with tokens so true,
Mobile drawers open with design anew.
Validation stands guard, passwords secure,
Each keystroke refined, the UX made pure!

🚥 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
Title check ✅ Passed The PR title 'Fix/notification bar theme sync' directly references the main change (Header.tsx theme-aware styling fixes), but is somewhat narrow—it emphasizes 'notification bar' specifically, whereas the PR also updates profile popover and mobile drawer styling comprehensively.
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 unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

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/Authentication/forms.tsx (1)

505-516: ⚠️ Potential issue | 🟡 Minor

ResetPasswordForm lacks password length validation.

LoginForm and SignUpForm validate minimum password length, but ResetPasswordForm only checks if passwords match (line 508). Users could set a weak password during reset.

Proposed fix
   const handleSubmit = async (e: React.FormEvent) => {
     e.preventDefault();

+    if (newPassword.length < 8) {
+      authContext.handleError('Password must be at least 8 characters');
+      return;
+    }
+
     if (newPassword !== confirmNewPassword) {
       authContext.handleError('Passwords do not match');
       return;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/Pages/Authentication/forms.tsx` around lines 505 - 516,
ResetPasswordForm's handleSubmit currently only checks for matching passwords
and allows weak passwords; update the handleSubmit function to enforce the same
minimum password length used by LoginForm/SignUpForm (use the existing constant
if available, e.g., PASSWORD_MIN_LENGTH, or the same numeric value), validate
newPassword length before calling confirmForgotPassword, and call
authContext.handleError with a clear message (e.g., "Password must be at least X
characters") and return early if it fails; ensure this validation occurs prior
to matching check or combine both checks so weak or mismatched passwords stop
the reset flow.
frontend/src/components/Header.tsx (1)

66-74: ⚠️ Potential issue | 🟡 Minor

Potential stale closure when checking isRead status.

handleDeleteNotification captures notifications from the render closure. If called in quick succession, notifications.find() on line 70 may reference stale state, potentially miscounting unread notifications.

Proposed fix using functional state update
   const handleDeleteNotification = async (e: React.MouseEvent, id: string) => {
     e.stopPropagation();
     await deleteNotification(id);
-    setNotifications(prev => prev.filter(n => n.id !== id));
-    const notification = notifications.find(n => n.id === id);
-    if (notification && !notification.isRead) {
-      setUnreadCount(prev => Math.max(0, prev - 1));
-    }
+    setNotifications(prev => {
+      const notification = prev.find(n => n.id === id);
+      if (notification && !notification.isRead) {
+        setUnreadCount(count => Math.max(0, count - 1));
+      }
+      return prev.filter(n => n.id !== id);
+    });
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/Header.tsx` around lines 66 - 74,
handleDeleteNotification currently reads notifications from the render closure
which can be stale; change the logic to use a functional state update on
setNotifications so you inspect the latest prev state to find the deleted
notification and compute unread delta before returning the filtered array.
Specifically, inside handleDeleteNotification (which calls deleteNotification),
replace the notifications.find(...)/setUnreadCount(...) sequence with a single
setNotifications(prev => { const target = prev.find(p => p.id === id); if
(target && !target.isRead) setUnreadCount(u => Math.max(0, u - 1)); return
prev.filter(p => p.id !== id); }) so you reference the up-to-date state and
avoid stale-closure bugs.
🧹 Nitpick comments (3)
frontend/src/Pages/Authentication/forms.tsx (3)

445-465: ForgotPasswordForm lacks email validation before API call.

Unlike LoginForm and SignUpForm, this form sends the email directly to the server without client-side validation. Consider adding the same validation for consistency and to avoid unnecessary API calls.

Proposed fix
+  const validateEmail = (email: string) => {
+    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+    return emailRegex.test(email);
+  };
+
   const handleSubmit = async (e: React.FormEvent) => {
     e.preventDefault();
     setError('');

+    if (!email.trim()) {
+      setError('Please enter your email address');
+      return;
+    }
+
+    if (!validateEmail(email)) {
+      setError('Please enter a valid email address');
+      return;
+    }
+
     try {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/Pages/Authentication/forms.tsx` around lines 445 - 465, Add
client-side email validation in ForgotPasswordForm's handleSubmit to mirror
LoginForm/SignUpForm behavior: before calling fetch or startResetPassword,
validate the email string (the same regex/validateEmail helper used elsewhere or
replicate its logic) and if invalid call setError with the same message used in
other forms and return early; ensure you reference the email state, setError,
handleSubmit and only proceed to fetch(`${baseURL}/forgotPassword`, ...) and
startResetPassword(email) when validation passes.

86-94: Consider using type="email" to preserve native benefits.

Changing from type="email" to type="text" loses native browser benefits: mobile keyboards won't optimize for email entry (showing @ prominently), and built-in email format validation hints are lost. The autocomplete feature can still work with type="email".

Proposed fix
       <Input
-        type="text"
+        type="email"
         value={value}
         onChange={(e) => handleInputChange(e.target.value)}
         onKeyDown={handleKeyDown}
         onFocus={() => value && !value.includes('@') && setShowSuggestions(true)}
         placeholder={placeholder}
         className={className}
+        autoComplete="email"
       />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/Pages/Authentication/forms.tsx` around lines 86 - 94, The Input
currently uses type="text" which loses native email keyboard and validation —
change the type prop to "email" on the Input used in the email field and keep
the existing handlers (onChange -> handleInputChange, onKeyDown ->
handleKeyDown, onFocus -> setShowSuggestions) intact; also ensure autocomplete
is set (e.g., "email") if not already, and verify the onFocus logic that checks
value and value.includes('@') still behaves correctly with type="email".

130-135: Extract duplicated validation logic to shared utilities.

validateEmail (lines 132-135 and 268-271), MIN_PASSWORD_LENGTH (lines 130 and 266), and handleGoogleLogin (lines 166-172 and 314-320) are duplicated across LoginForm and SignUpForm. Consider extracting to a shared module.

Example shared validation module
// utils/validation.ts
export const MIN_PASSWORD_LENGTH = 8;

export const validateEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
};

Then import and use in both forms:

import { MIN_PASSWORD_LENGTH, validateEmail } from '@/utils/validation';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/Pages/Authentication/forms.tsx` around lines 130 - 135, Extract
the duplicated constants and functions into a shared utility module and import
them into both forms: create a new module that exports MIN_PASSWORD_LENGTH,
validateEmail, and handleGoogleLogin (preserving the same signatures), move the
existing implementations from LoginForm and SignUpForm into that module, then
replace the inline definitions in both components (referencing validateEmail,
MIN_PASSWORD_LENGTH, and handleGoogleLogin) with imports from the new utility so
both LoginForm and SignUpForm reuse the same implementations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/Pages/Authentication/forms.tsx`:
- Around line 96-110: The suggestion dropdown uses hardcoded color classes and
lacks ARIA semantics; update the container and item classNames to use the PR's
semantic tokens (e.g., replace bg-white/dark:bg-slate-800 with bg-popover,
border-gray-300 with border-border, bg-gray-100 with bg-accent or
hover/bg-accent-foreground as appropriate) in the dropdown wrapper and each
suggestion item, and add accessibility attributes: give the wrapper
role="listbox" (and an id), each suggestion role="option" with a stable id
(e.g., `suggestion-${index}`), set aria-selected on items based on
activeSuggestionIndex, and set aria-activedescendant on the listbox to the
active item id so screen readers announce the active option; preserve existing
click behavior via handleSuggestionClick(suggestion).

---

Outside diff comments:
In `@frontend/src/components/Header.tsx`:
- Around line 66-74: handleDeleteNotification currently reads notifications from
the render closure which can be stale; change the logic to use a functional
state update on setNotifications so you inspect the latest prev state to find
the deleted notification and compute unread delta before returning the filtered
array. Specifically, inside handleDeleteNotification (which calls
deleteNotification), replace the notifications.find(...)/setUnreadCount(...)
sequence with a single setNotifications(prev => { const target = prev.find(p =>
p.id === id); if (target && !target.isRead) setUnreadCount(u => Math.max(0, u -
1)); return prev.filter(p => p.id !== id); }) so you reference the up-to-date
state and avoid stale-closure bugs.

In `@frontend/src/Pages/Authentication/forms.tsx`:
- Around line 505-516: ResetPasswordForm's handleSubmit currently only checks
for matching passwords and allows weak passwords; update the handleSubmit
function to enforce the same minimum password length used by
LoginForm/SignUpForm (use the existing constant if available, e.g.,
PASSWORD_MIN_LENGTH, or the same numeric value), validate newPassword length
before calling confirmForgotPassword, and call authContext.handleError with a
clear message (e.g., "Password must be at least X characters") and return early
if it fails; ensure this validation occurs prior to matching check or combine
both checks so weak or mismatched passwords stop the reset flow.

---

Nitpick comments:
In `@frontend/src/Pages/Authentication/forms.tsx`:
- Around line 445-465: Add client-side email validation in ForgotPasswordForm's
handleSubmit to mirror LoginForm/SignUpForm behavior: before calling fetch or
startResetPassword, validate the email string (the same regex/validateEmail
helper used elsewhere or replicate its logic) and if invalid call setError with
the same message used in other forms and return early; ensure you reference the
email state, setError, handleSubmit and only proceed to
fetch(`${baseURL}/forgotPassword`, ...) and startResetPassword(email) when
validation passes.
- Around line 86-94: The Input currently uses type="text" which loses native
email keyboard and validation — change the type prop to "email" on the Input
used in the email field and keep the existing handlers (onChange ->
handleInputChange, onKeyDown -> handleKeyDown, onFocus -> setShowSuggestions)
intact; also ensure autocomplete is set (e.g., "email") if not already, and
verify the onFocus logic that checks value and value.includes('@') still behaves
correctly with type="email".
- Around line 130-135: Extract the duplicated constants and functions into a
shared utility module and import them into both forms: create a new module that
exports MIN_PASSWORD_LENGTH, validateEmail, and handleGoogleLogin (preserving
the same signatures), move the existing implementations from LoginForm and
SignUpForm into that module, then replace the inline definitions in both
components (referencing validateEmail, MIN_PASSWORD_LENGTH, and
handleGoogleLogin) with imports from the new utility so both LoginForm and
SignUpForm reuse the same implementations.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb07eaf and 5eb76d3.

📒 Files selected for processing (2)
  • frontend/src/Pages/Authentication/forms.tsx
  • frontend/src/components/Header.tsx

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.

Bug: Notification bar and popovers don't follow theme in dark/system modes

1 participant