Skip to content

feat:Add Light/Dark Theme Toggle Using Redux - #8

Open
SaumyaDwivedi179 wants to merge 4 commits into
refactor/code-changesfrom
feat/theme-redux
Open

SaumyaDwivedi179 wants to merge 4 commits into
refactor/code-changesfrom
feat/theme-redux

Conversation

@SaumyaDwivedi179

Copy link
Copy Markdown
Collaborator

What This PR Does

  • Implements a light/dark theme toggle for the Weather App using Redux Toolkit.
  • Adds a themeSlice with toggleTheme action and themeReducer in src/store/themeSlice.js.
  • Adds a Redux store in src/store/store.js and wraps the app with <Provider> in Main.jsx.
  • Adds a toggle button (in AppContext.jsx or header component) to switch between light and dark themes using useDispatch and useSelector.
  • Updates all relevant inline styles (background, color, border) to use CSS variables, making theme switching global and seamless.
  • Keeps the app fully functional with the weather search and card components.

Manual Testing Steps (Reviewer)

  1. Run npm install & npm run dev to start the app.
  2. Verify the weather search works as expected.
  3. Click the Toggle Theme button in the header:
    • Check that the background, text, and weather card update colors appropriately.
    • Confirm the toggle switches between light and dark themes.
  4. Verify no console warnings or errors appear.

Files Changed

  • src/store/themeSlice.js → Added themeSlice with toggleTheme action.
  • src/store/store.js → Added Redux store configuration.
  • src/components/AppContext.jsx → Added toggle button UI using useDispatch & useSelector.
  • src/Main.jsx → Wrapped with <Provider> & applied theme styles based on Redux state.
  • src/index.css → Added CSS variables for light/dark themes.

✅ Definition of Done

Code Quality

  • Clean, readable, and well-structured code.
  • Logic for theme management separated into reusable Redux slice.
  • Removed unnecessary inline comments and unused code.

Testing

  • Manual testing completed for toggle functionality.
  • Verified weather API features still work with theme toggling.
  • No regressions or styling issues found.

@ashik-shaji

Copy link
Copy Markdown
Collaborator

@cw-pr-agent review

1 similar comment
@saumya-cw

Copy link
Copy Markdown
Collaborator

@cw-pr-agent review

@mergemitra

mergemitra Bot commented Feb 3, 2026

Copy link
Copy Markdown

Change Summary

Implements Redux-driven light/dark theming for the Weather App.
Wraps the root app with Provider and ThemeProvider to sync document classes with store state.
Adds a ThemeToggle button plus updated CSS variables and glassmorphism styling for theme-aware UI.

File Changes
File Summary
node_modules/.package-lock.json Adds package-lock capturing Redux Toolkit, React-Redux, and runtime dependencies for consistent installs.
weather-app/src/components/Header.jsx Adds ThemeToggle component to header and reorganizes header layout spacing.
weather-app/src/components/ThemeToggle.jsx Adds ThemeToggle button using Redux hooks to switch themes iconically.
weather-app/src/index.css Refactors global styles with theme-aware backgrounds, gradients, and glass effects.
weather-app/src/main.jsx Wraps app with Redux Provider and ThemeProvider to apply theme state globally.
weather-app/src/providers/ThemeProvider.jsx Adds ThemeProvider syncing document classes to Redux theme state.
weather-app/src/store/index.js Adds Redux store configuration exposing theme reducer.
weather-app/src/store/themeSlice.js Adds theme slice with toggle action and localStorage-backed initial state.

Based on 16e6dac...9ca410c

@mergemitra

mergemitra Bot commented Feb 3, 2026

Copy link
Copy Markdown

PR Scorecard

Score

Communication Quality Code Correctness & Design Quality Test Quality & Coverage Code Readability & Maintainability
Scoring Methodology

Communication Scoring Framework

The overall communication score is a weighted average:

Dimension Weight Evaluates
PR Description Quality 60% Title format (conventional commits) + Description clarity (what changed & why)
PR Size & Scope 25% Appropriate sizing, scope cohesion, and justification for size
Commit Messages 15% Conventional commits format, atomic & descriptive changes

Formula: (Description x 0.6) + (PR Size x 0.25) + (Commits x 0.15)

Code Scoring Framework

The scorecard evaluates code using 3 key reviewer questions:

Reviewer Question Category
Is this the right solution, implemented the right way? Code Correctness
Would this catch bugs if the code broke tomorrow? Test Quality
Can someone new understand and safely modify this in 6 months? Maintainability
PR Communication Notes

Description Quality

  • ❌ Title not in conventional format; use feat(theme): add light/dark toggle (missing space and scope).
  • ❌ Description says Redux, but commits mention Zustand; clarify migration from Zustand to Redux Toolkit.
  • ❌ File paths in description don't match (Main.jsx/store.js/AppContext.jsx vs src/main.jsx/store/index.js/Header.jsx).
  • ❌ Description claims CSS variables, but CSS uses html.light/dark selectors with !important; update wording.

PR Size & Scope

  • ❌ Very large PR (126k+ lines, 473 files) makes review risky; please reduce scope or remove generated content.
  • node_modules/.package-lock.json appears in diff; node_modules/lock artifacts should not be committed.
  • 💡 Suggestion: PR1 Redux setup only: weather-app/src/store/*, weather-app/src/main.jsx, providers/ThemeProvider.jsx
  • 💡 Suggestion: PR2 UI/CSS only: weather-app/src/components/{Header,ThemeToggle}.jsx, weather-app/src/index.css

Commit Messages

  • ❌ Commit 2 is non-compliant (feat(header, index. main)-...); use <type>(<scope>): <desc> going forward.
  • ❌ Messages reference Zustand though PR uses Redux (themeSlice, configureStore); align wording to actual approach.
  • feat: Zustand theme is vague; describe what changed (e.g., add theme slice, persist to localStorage).

Issue Notes

Code Correctness & Design Quality

  • 🔴 Stray {} after <ThemeToggle /> at weather-app/src/components/Header.jsx:13 will fail JSX parsing and break the build
  • 🟠 Icon-only button lacks accessible name at weather-app/src/components/ThemeToggle.jsx:10 so screen readers may announce an unclear emoji instead of “toggle theme”
  • 🟠 Global html.(light|dark) * { ... !important } overrides at weather-app/src/index.css:18, weather-app/src/index.css:34 can unintentionally wipe component-specific styles and cause hard-to-diagnose UI bugs
  • 🟠 document.documentElement.className = theme at weather-app/src/providers/ThemeProvider.jsx:11 overwrites any existing <html> classes and can break other global styling/scripts
  • 🔴 Writing to localStorage inside the reducer at weather-app/src/store/themeSlice.js:10 introduces side effects and can throw (e.g., storage blocked), crashing dispatch and breaking Redux expectations
  • 🟠 Reading localStorage during module init at weather-app/src/store/themeSlice.js:7 can throw in restricted environments and prevents safe reuse in tests/SSR

Test Quality & Coverage

  • 🟠 No automated tests were added for the new Redux/theme behavior at weather-app/src/main.jsx:10, so regressions in theme toggling/persistence may slip through CI

Code Readability & Maintainability

  • 🟠 Committed npm-generated file under node_modules at node_modules/.package-lock.json:1 bloats the repo and will cause noisy diffs/merge conflicts (node_modules should not be versioned)
  • 🟠 Heavy use of broad selectors + !important at weather-app/src/index.css:18 makes future styling/theme changes difficult to override safely
  • 🟠 Theme styles are hard-coded instead of using CSS variables at weather-app/src/index.css:13 which makes the “global theme switching via variables” claim harder to maintain and extend
  • 🟠 Unused toggleTheme import and dispatch variable at weather-app/src/providers/ThemeProvider.jsx:4, weather-app/src/providers/ThemeProvider.jsx:8 will trigger lint warnings and adds confusion
💬 Minor Issues (Nitpicks)

Code Readability & Maintainability

  • 💬 Extra whitespace/empty line at weather-app/src/components/Header.jsx:1 makes the file noisier for no benefit
  • 💬 Inline dispatch callback at weather-app/src/components/ThemeToggle.jsx:12 makes it harder to debug/extend; extract a handleToggleTheme handler
  • 💬 Removing the global font-family (was in the old reset) at weather-app/src/index.css:2 may cause inconsistent typography across browsers
  • 💬 transition: all on html at weather-app/src/index.css:9 can animate unintended properties and cause jank; target specific properties instead
  • 💬 Repeated 'light'/'dark' literals at weather-app/src/store/themeSlice.js:7 make refactors error-prone; consider shared constants

Based on 16e6dac...7445134

Comment thread weather-app/src/components/Header.jsx Outdated
Get instant weather updates for any city worldwide
</p>
</div>
<ThemeToggle /> {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🔴 Critical

Remove the stray {} after <ThemeToggle /> to avoid a JSX parse error that will break the build.

theme: localStorage.getItem('theme') === 'dark' ? 'dark' : 'light'
},
reducers: {
toggleTheme: (state) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🔴 Critical

Keep reducers pure by removing localStorage.setItem from toggleTheme; persist the theme in an effect/middleware with try/catch.

toggleTheme: (state) => {
  state.theme = state.theme === 'light' ? 'dark' : 'light'
}

const dispatch = useDispatch()

useEffect(() => {
document.documentElement.className = theme

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major

Avoid overwriting all <html> classes; toggle only the theme classes (and remove the unused dispatch/toggleTheme import).

useEffect(() => {
  document.documentElement.classList.toggle('dark', theme === 'dark')
  document.documentElement.classList.toggle('light', theme === 'light')
}, [theme])

@mergemitra

mergemitra Bot commented Feb 3, 2026

Copy link
Copy Markdown

PR Overview

PR Type: Feature

Focus Areas for Architect Review

  • Redux reducer currently mixes UI state changes with persistence concerns; consider a consistent pattern (preloadedState + effect/listener middleware) for localStorage-backed preferences.
  • The theming approach relies on very broad selectors and !important rather than CSS variables; confirm this is the intended styling strategy to avoid future styling lock-in.
  • node_modules/.package-lock.json was committed; align on dependency/lockfile policy (root lockfile only + node_modules ignored).
  • No automated tests were added for theme toggling/persistence; decide minimum coverage expectations (slice unit tests + DOM class toggle smoke test).
PR Insights

Potential PR Improvements

  • Correctness: Avoid stray JSX tokens; keep builds passing.
  • Robustness: Keep reducers pure; move localStorage writes to middleware/effects.
  • Code Maintainability: Avoid global * selectors and !important for theming.
  • Robustness: Preserve existing <html> classes when toggling theme.
  • Testing: Add automated tests for theme toggle and persistence.

PR Strengths

  • Best Practices: Used Redux Toolkit slice and store configuration cleanly.
  • Code Maintainability: Encapsulated theme DOM updates inside a dedicated provider.
  • Documentation: Provided clear manual testing steps and definition of done.
  • Correctness: Theme state derives from persisted preference for consistent UX.
  • PR Size: Change set stays focused on theming and wiring.

@mergemitra

mergemitra Bot commented Feb 4, 2026

Copy link
Copy Markdown

Tip

Need another review?

Tag me and say rereview for re-analysis after you have fixed all the issues.

@cw-pr-agent rereview

@saumya-cw

Copy link
Copy Markdown
Collaborator

@cw-pr-agent rereview

@mergemitra

mergemitra Bot commented Feb 4, 2026

Copy link
Copy Markdown

PR Scorecard

Score

Communication Quality Code Correctness & Design Quality Test Quality & Coverage Code Readability & Maintainability
Scoring Methodology

Communication Scoring Framework

The overall communication score is a weighted average:

Dimension Weight Evaluates
PR Description Quality 60% Title format (conventional commits) + Description clarity (what changed & why)
PR Size & Scope 25% Appropriate sizing, scope cohesion, and justification for size
Commit Messages 15% Conventional commits format, atomic & descriptive changes

Formula: (Description x 0.6) + (PR Size x 0.25) + (Commits x 0.15)

Code Scoring Framework

The scorecard evaluates code using 3 key reviewer questions:

Reviewer Question Category
Is this the right solution, implemented the right way? Code Correctness
Would this catch bugs if the code broke tomorrow? Test Quality
Can someone new understand and safely modify this in 6 months? Maintainability
PR Communication Notes

Description Quality

  • ❌ Title still misses conventional format; use e.g. 'feat(theme): add light/dark toggle' (add space + scope).
  • ❌ Description still lists paths like Main.jsx/AppContext.jsx/store.js that don't match current files (e.g., providers/ThemeProvider.jsx).
  • ❌ Description says 5 files changed, but PR remains 473 files/126k+ lines; update scope summary to match reality.

PR Size & Scope

  • ❌ This update is small (+6/-6 across 3 files) but the PR is still extremely large (126k+ lines, 473 files).
  • ❌ Very large diffs make review and rollback risky; try to remove generated/vendor artifacts and keep only source changes.
  • 💡 Suggestion: Split Redux/theme state wiring: weather-app/src/store/*, weather-app/src/providers/ThemeProvider.jsx, weather-app/src/main.jsx
  • 💡 Suggestion: Split UI/CSS changes: weather-app/src/components/{Header,ThemeToggle}.jsx, weather-app/src/index.css

Commit Messages

  • ❌ New commit 'fix: resolve the pr-bot comment' follows the type prefix, but future messages should describe the actual code change.
  • ❌ No other new commits since last review; keep using '(): ' going forward for consistency.

Issue Notes

Code Correctness & Design Quality

  • 🟠 Theme preference is no longer persisted after removing localStorage.setItem, so the toggle will reset on refresh and can diverge from any persisted initial theme at weather-app/src/store/themeSlice.js:10
  • 🟠 [UNRESOLVED] Reading localStorage during slice/module initialization at weather-app/src/store/themeSlice.js:7 can throw in restricted environments and crash the app before render

Test Quality & Coverage

  • 🟠 [UNRESOLVED] No automated tests cover theme toggling/persistence wiring, so regressions may ship unnoticed at weather-app/src/store/themeSlice.js:1, weather-app/src/providers/ThemeProvider.jsx:10

Code Readability & Maintainability

  • 🟠 [UNRESOLVED] dispatch is declared but unused at weather-app/src/providers/ThemeProvider.jsx:8 which will trigger lint/build failures in stricter setups and adds confusion about intended behavior

Based on 7445134...9ca410c


export function ThemeProvider({ children }) {
const theme = useSelector((state) => state.theme.theme)
const dispatch = useDispatch()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major

dispatch is unused here; remove useDispatch() (and its import) or actually use it, and if theme persistence is still desired, persist in this effect (not in the reducer) with a guarded localStorage write.

useEffect(() => {
  ...
  try { localStorage.setItem('theme', theme) } catch {}
}, [theme])

theme: localStorage.getItem('theme') === 'dark' ? 'dark' : 'light'
},
reducers: {
toggleTheme: (state) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major

If the slice still initializes from localStorage, make that read resilient (storage can throw in private mode/blocked contexts) and keep the reducer pure.

const initialTheme = (() => { try { return localStorage.getItem('theme') ?? 'light' } catch { return 'light' } })()

@@ -0,0 +1,17 @@

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major

Add automated tests for toggleTheme (and persistence/DOM-class syncing if kept) so regressions are caught by CI—at minimum a slice unit test and a ThemeProvider effect smoke test.

@mergemitra

mergemitra Bot commented Feb 4, 2026

Copy link
Copy Markdown

PR Overview

PR Type: Feature

Focus Areas for Architect Review

  • Theme persistence approach is currently unclear (write removed from reducer but no replacement shown); align on a single pattern (listener middleware / effect) with safe localStorage access.
  • Confirm the CSS theming strategy (previously broad * + !important) won’t cause unintended style overrides as the app grows.
  • Repo hygiene: ensure node_modules artifacts (e.g., node_modules/.package-lock.json) are not committed and lockfile policy is consistent.
  • Define minimum automated test coverage for UI preferences like theme (slice unit test + provider DOM side-effect smoke test).
Rereview Impressions

Progress Since Last Review

  • Stray {} after <ThemeToggle /> in Header.jsx appears fixed (build-breaking JSX parse issue resolved).
  • localStorage.setItem side effect was removed from the reducer (Redux purity issue addressed).
  • <html> class handling was updated to toggle light/dark instead of overwriting className.

Remaining Concerns

  • Persistence now looks incomplete (toggle won’t survive refresh unless persistence was re-added elsewhere).
  • ThemeProvider still declares an unused dispatch (likely also leaves an unused useDispatch import).
  • Automated tests for the theme behavior still appear missing.

New Issues Introduced (if any)

  • No new functional issues spotted in the updated hunks beyond the persistence regression risk.
PR Insights

Potential PR Improvements

  • Correctness: Theme choice no longer persists after refresh.
  • Robustness: Reading localStorage during module init can crash restricted environments.
  • Code Maintainability: Unused dispatch variable adds noise and lint risk.
  • Testing: No automated tests for toggling, persistence, and DOM class updates.
  • Description Quality: File paths and implementation details conflict across PR notes.

PR Strengths

  • Correctness: Removed stray JSX tokens that would break builds.
  • Best Practices: Reducer no longer performs localStorage side effects.
  • Robustness: Theme switching uses classList toggles instead of overwriting classes.
  • Code Maintainability: Theme DOM syncing is centralized in a provider.
  • Description Quality: Manual testing steps are clear and actionable.

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.

3 participants