[FEATURE]: Add dark mode support for web app#663
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 53 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughA dark mode feature has been added to the web app. The new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 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.
Pull request overview
Adds a global, persistent theme toggle to support light mode across the EduAid web app while keeping the current dark UI as the default.
Changes:
- Introduced a new
ThemeTogglecomponent that persists the selected theme inlocalStorageand toggles a root class ondocument.documentElement. - Added global CSS for the toggle styling plus light-mode overrides for existing dark-styled utility classes.
- Rendered the toggle globally across all routes via
App.js.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
eduaid_web/src/index.css |
Adds theme-related CSS (color-scheme, toggle styles, and light-mode overrides). |
eduaid_web/src/components/ThemeToggle.jsx |
Implements persistent theme state + DOM class switching and the UI button. |
eduaid_web/src/App.js |
Mounts the global theme toggle for all routes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| useEffect(() => { | ||
| const savedTheme = localStorage.getItem(STORAGE_KEY); | ||
| const initialTheme = | ||
| savedTheme === LIGHT_THEME || savedTheme === DARK_THEME | ||
| ? savedTheme | ||
| : DARK_THEME; | ||
|
|
||
| setTheme(initialTheme); | ||
| applyTheme(initialTheme); | ||
| }, []); |
| type="button" | ||
| onClick={toggleTheme} | ||
| className="theme-toggle fixed right-4 top-4 z-[1000] rounded-full px-4 py-2 text-sm font-semibold" | ||
| aria-label="Toggle dark mode" |
| radial-gradient(circle at 90% -15%, rgba(255, 19, 132, 0.16) 0%, transparent 40%) !important; | ||
| } | ||
|
|
||
| .light-theme .text-white { |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
eduaid_web/src/components/ThemeToggle.jsx (1)
42-43: Use toggle semantics for assistive tech.Line 42 should expose the current state/action to screen readers. Prefer a dynamic
aria-labeland addaria-pressed.Suggested fix
- aria-label="Toggle dark mode" + aria-label={ + theme === DARK_THEME ? "Switch to light mode" : "Switch to dark mode" + } + aria-pressed={theme === LIGHT_THEME}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@eduaid_web/src/components/ThemeToggle.jsx` around lines 42 - 43, The toggle button in ThemeToggle.jsx currently uses a static aria-label; update it to expose current state by making aria-label dynamic (e.g., theme === DARK_THEME ? "Dark mode, toggle to light mode" : "Light mode, toggle to dark mode") and add aria-pressed={theme === DARK_THEME} on the same element (the ThemeToggle button/component) so assistive tech can read the current state; ensure the label text matches the title logic and references the DARK_THEME constant and the ThemeToggle component's theme prop/state.eduaid_web/src/index.css (1)
52-95: Consider moving from class-by-class overrides to theme tokens.Line 52-95 relies on many explicit selectors +
!important, which becomes fragile as new utility classes are introduced. Defining shared CSS variables per theme will scale better and reduce override churn.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@eduaid_web/src/index.css` around lines 52 - 95, The current stylesheet uses many explicit selectors and !important overrides (e.g., .light-theme .bg-\[\#02000F\], .light-theme .bg-cust, .light-theme .bg-custom-gradient, .light-theme .text-white, .light-theme .bg-black, .light-theme .bg-\[\#3e5063\], .light-theme .border-\[\#cbd0dc80\]) which is fragile; instead define a set of theme CSS variables on .light-theme (for example --bg-primary, --bg-surface, --text-primary, --surface-fade, --border-color, --gradient-overlay) and update your utility classes to use var(--*) rather than hardcoded colors, then remove the per-class overrides and !important flags; also replace the custom gradient value in .bg-custom-gradient with a variable so the theme can switch the gradient centrally and ensure utilities (background, text, border) reference these tokens (update places that reference .bg-cust, .text-white, .bg-black, .bg-custom-gradient, and the bracketed color classes to consume the variables).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@eduaid_web/src/components/ThemeToggle.jsx`:
- Around line 13-29: The component currently defaults theme to DARK_THEME then
reads localStorage in a mount effect, causing an unnecessary write and flash;
change the useState initialization for theme to a lazy initializer that reads
STORAGE_KEY (return LIGHT_THEME or DARK_THEME appropriately) and calls
applyTheme synchronously for the initial value, remove the separate mount
useEffect that sets theme/applyTheme, and keep the existing useEffect([theme])
to persist changes to localStorage via localStorage.setItem(STORAGE_KEY, theme);
reference the state hook (useState/theme/setTheme), STORAGE_KEY, DARK_THEME,
LIGHT_THEME, and applyTheme when making this change.
---
Nitpick comments:
In `@eduaid_web/src/components/ThemeToggle.jsx`:
- Around line 42-43: The toggle button in ThemeToggle.jsx currently uses a
static aria-label; update it to expose current state by making aria-label
dynamic (e.g., theme === DARK_THEME ? "Dark mode, toggle to light mode" : "Light
mode, toggle to dark mode") and add aria-pressed={theme === DARK_THEME} on the
same element (the ThemeToggle button/component) so assistive tech can read the
current state; ensure the label text matches the title logic and references the
DARK_THEME constant and the ThemeToggle component's theme prop/state.
In `@eduaid_web/src/index.css`:
- Around line 52-95: The current stylesheet uses many explicit selectors and
!important overrides (e.g., .light-theme .bg-\[\#02000F\], .light-theme
.bg-cust, .light-theme .bg-custom-gradient, .light-theme .text-white,
.light-theme .bg-black, .light-theme .bg-\[\#3e5063\], .light-theme
.border-\[\#cbd0dc80\]) which is fragile; instead define a set of theme CSS
variables on .light-theme (for example --bg-primary, --bg-surface,
--text-primary, --surface-fade, --border-color, --gradient-overlay) and update
your utility classes to use var(--*) rather than hardcoded colors, then remove
the per-class overrides and !important flags; also replace the custom gradient
value in .bg-custom-gradient with a variable so the theme can switch the
gradient centrally and ensure utilities (background, text, border) reference
these tokens (update places that reference .bg-cust, .text-white, .bg-black,
.bg-custom-gradient, and the bracketed color classes to consume the variables).
🪄 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: ff557e04-2dfd-43e2-8d46-51013879ab32
📒 Files selected for processing (3)
eduaid_web/src/App.jseduaid_web/src/components/ThemeToggle.jsxeduaid_web/src/index.css
|
Addressed the review feedback with a follow-up commit. What changed:
Validation:
|
Addressed Issues:
Implements issue #661 by adding dark mode support with a persistent theme toggle across the web app.
Fixes #661
Screenshots/Recordings:
Not attached from CLI environment.
Additional Notes:
This PR introduces a lightweight global theme controller without changing existing route structure.
Key Improvements:
localStorage) so user choice survives reloadsdocument.documentElementAI Usage Disclosure:
Checklist
Validation:
Summary by CodeRabbit
Release Notes