Challenge: Build a Theme and Notifications Panel

Build a small theme and notifications settings panel that uses a segmented theme context, a reducer-based reusable toggle component, and a correct derived state for a summary counter.

Problem statement

You are tasked with building a SettingsPanel component that allows users to manage theme preferences and notification settings. This panel will be part of a larger application, so it should be modular, reusable, and follow good React architecture patterns. The panel consists of two main sections: Theme and Notifications.

  • Theme section:

    • Toggle between light and dark modes using a labeled toggle (“Dark mode”).

    • Display current theme: Current theme: light or Current theme: dark.

    • Manage theme globally via useReducer with segmented context (state and dispatch separated).

  • Notifications section:

    • Manage two notification preferences: marketing emails and product updates, each with a reusable toggle.

    • Display summary: Enabled: X / 2, derived via useMemo from local state (do not store separately).

    • The notification state should be local to this section.

Technical requirements: Implement the following features step by step:

ThemeContext.js:

  • Implement themeReducer with "TOGGLE_MODE".

  • Provide ThemeStateContext and ThemeDispatchContext.

  • Export ThemeProvider, useThemeState, and useThemeDispatch.

Toggle.js:

  • Use useReducer with an internal reducer handling "TOGGLE".

  • Implement getButtonProps that merges the user’s onClick and sets aria-pressed.

  • Expose the Toggle as a compound component.

ThemeSettingsSection.js:

  • Read the current theme using useThemeState.

  • Dispatch "TOGGLE_MODE" using useThemeDispatch when the Toggle is clicked.

  • Display label, Toggle, and Current theme: light | dark.

NotificationsSettingsSection.js:

  • Manage local notification state.

  • Use Toggle for Marketing Emails and Product Updates.

  • Compute enabledCount using useMemo from the notification state.

  • Display summary: Enabled: X / 2.

Expected output

When your implementation is correct:

  • Theme section:

    • Row: “Dark mode” with a toggle.

    • Toggle switches between light/dark.

    • Text below shows Current theme: light or Current theme: dark.

  • Notifications section:

    • Summary: Enabled: X / 2 updates dynamically.

The rendered page would look like this: