Skip to content

[Feature]: Implement dark mode toggle with persistent preference stored in localStorage #1998

Description

@prince-pokharna

Summary

DailyForge has a clean, modern UI built with React 19 + Tailwind CSS v4, but it currently has no dark mode support. Dark mode is one of the most commonly requested features in productivity apps — especially by users who work late or in low-light environments. Tailwind CSS v4 has first-class dark mode support via the dark: variant, making this straightforward to implement.

Problem

  • No dark/light mode toggle exists anywhere in the UI
  • User preference is not persisted — even if toggled, it would reset on page reload
  • The system's preferred color scheme (via prefers-color-scheme) is not respected
  • The app targets students and professionals who often work at night — dark mode is a meaningful quality-of-life improvement for this demographic

Proposed Solution

1. Create a ThemeContext for global theme state:

// src/context/ThemeContext.jsx
import { createContext, useContext, useEffect, useState } from "react";

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState(
    () => localStorage.getItem("df-theme") || 
    (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
  );

  useEffect(() => {
    document.documentElement.classList.toggle("dark", theme === "dark");
    localStorage.setItem("df-theme", theme);
  }, [theme]);

  const toggleTheme = () => setTheme((t) => (t === "dark" ? "light" : "dark"));

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export const useTheme = () => useContext(ThemeContext);

2. Add a toggle button to the Navbar:

import { Moon, Sun } from "lucide-react"; // already in dependencies
import { useTheme } from "../context/ThemeContext";

function ThemeToggle() {
  const { theme, toggleTheme } = useTheme();
  return (
    <button onClick={toggleTheme} aria-label="Toggle dark mode">
      {theme === "dark" ? <Sun size={18} /> : <Moon size={18} />}
    </button>
  );
}

3. Update tailwind.config.js to ensure darkMode: "class" is set.

4. Add dark: variants to the most prominent UI surfaces (Navbar, cards, sidebar, modals).

I will implement this incrementally — context + toggle first, then progressively apply dark: classes to components. Please assign this to me.

Labels: enhancement, UI/UX, good first issue, GSSoC 2026

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions