Skip to content

feat: Add dark mode support and fix GitHub repository links#41

Merged
rishabh3562 merged 8 commits intorishabh3562:mainfrom
aryadharmadhikari:feat/dark-theme
Oct 27, 2025
Merged

feat: Add dark mode support and fix GitHub repository links#41
rishabh3562 merged 8 commits intorishabh3562:mainfrom
aryadharmadhikari:feat/dark-theme

Conversation

@aryadharmadhikari
Copy link
Contributor

@aryadharmadhikari aryadharmadhikari commented Oct 24, 2025

User description

Description

This PR implements comprehensive dark mode functionality for the ToolBox application with a theme toggle button in the navigation header. Additionally, it fixes GitHub repository links throughout the application to point to the official repository instead of the generic GitHub homepage.

Type of Change

  • New tool addition
  • Tool improvement/update
  • Bug fix
  • Documentation update
  • UI/UX improvement
  • Refactoring
  • Other (please describe):

Related Issue

Changes Made

  • Added dark mode toggle button (sun/moon icons) in the navigation header
  • Implemented theme persistence using localStorage with key devtools-theme
  • Added support for system color scheme preference detection
  • Created ThemeProvider wrapper in layout.tsx for global theme management
  • Built theme-toggle.tsx component with hydration-safe rendering
  • Cleaned up conflicting @media (prefers-color-scheme: dark) queries in globals.css
  • Fixed HSL color format in prose styles for proper dark mode support
  • Updated all GitHub links from https://github.com to https://github.com/rishabh3562/ToolBox
  • Installed dependencies: next-themes for theme management and lucide-react for icons

Updated to address feedback:

  • Resolved the next.js version 16.0.0 up-gradation issue by convincing and proving it is stable.
  • Fixed tsconfig.json jsx setting to 'preserve'
  • Added JSDoc documentation to improve coverage

Screenshots (if applicable)

  1. Light Mode
Screenshot 2025-10-24 at 11 36 26 AM
  1. Dark Mode
Screenshot 2025-10-24 at 11 36 43 AM

Testing

  • I have tested the changes locally
  • All links are working and valid
  • Information provided is accurate and up-to-date
  • Theme toggle switches between light and dark modes
  • Theme preference persists after page reload
  • System preference is respected on first visit
  • No hydration errors in browser console
  • GitHub links redirect to correct repository

Checklist

  • I have read the CONTRIBUTING.md guidelines (if available)
  • My code follows the project's style guidelines
  • I have checked for duplicate tools/issues before submitting
  • My changes do not introduce any breaking changes

Additional Context

Technical Implementation

  • Uses class-based dark mode (darkMode: ["class"]) with Tailwind CSS
  • Leverages existing CSS variable system for automatic dark mode support across all pages
  • Implements mounted check pattern to prevent hydration mismatches
  • Smooth icon transitions using Tailwind's dark: variants

GitHub Links Fixed

  • Updated GitHub repository links in navigation header, body, and footer
  • X (Twitter) social platform link remains unchanged as I don't have access to the official account URL

Suggestions for Future Improvements

While implementing this PR, I noticed some UI/UX enhancements that could improve the navigation:

  • Navigation alignment: Move Home and Tools items to the right side of the header (before the theme toggle button) for better visual balance
  • Logo spacing: Add padding to the DevTools logo and text to prevent it from touching the left border
  • Footer alignment: Center the footer content instead of left-alignment for improved aesthetics
  • X/Twitter link: Update the X social platform link once the official account URL is provided

I would be happy to implement these improvements in a follow-up PR if you and the other maintainers agree with these suggestions.


PR Type

Enhancement, Bug fix


Description

  • Implement dark mode support with theme toggle button

    • Added ThemeProvider wrapper using next-themes library
    • Created ThemeToggle component with sun/moon icons
    • Theme persists via localStorage with key devtools-theme
    • System color scheme preference detected on first visit
  • Fix GitHub repository links throughout application

    • Updated all GitHub links from generic homepage to official repository
    • Links now point to https://github.com/rishabh3562/ToolBox
  • Clean up CSS and improve dark mode compatibility

    • Removed conflicting @media (prefers-color-scheme: dark) queries
    • Fixed HSL color format in prose styles for proper dark mode support
  • Update dependencies and configuration

    • Added next-themes and lucide-react packages
    • Updated Next.js to version 16, React Syntax Highlighter to 16
    • Modified TypeScript configuration for improved compatibility

Diagram Walkthrough

flowchart LR
  A["User Interaction"] -->|Click Theme Toggle| B["ThemeToggle Component"]
  B -->|setTheme| C["next-themes Provider"]
  C -->|Update Class| D["HTML Element"]
  D -->|Apply Styles| E["Dark/Light Mode"]
  C -->|Save Preference| F["localStorage devtools-theme"]
  F -->|Restore on Reload| C
  G["GitHub Links"] -->|Updated URLs| H["Official Repository"]
Loading

File Walkthrough

Relevant files
Enhancement
globals.css
Fix CSS color format and remove conflicting media queries

app/globals.css

  • Removed conflicting @media (prefers-color-scheme: dark) CSS rules
  • Fixed color format from rgb(var(...)) to hsl(var(...)) in prose styles
  • Updated prose pre, table borders, and blockquote styles for HSL
    compatibility
  • Cleaned up CSS variable declarations for cleaner dark mode support
+4/-17   
layout.tsx
Add ThemeProvider wrapper for dark mode support                   

app/layout.tsx

  • Wrapped layout with ThemeProvider from next-themes
  • Added suppressHydrationWarning to html element
  • Configured theme provider with system preference detection and
    localStorage persistence
  • Set default theme to "system" with storage key devtools-theme
+15/-6   
site-header.tsx
Add theme toggle and fix GitHub link in header                     

components/site-header.tsx

  • Added ThemeToggle component import and integration
  • Inserted theme toggle button in header navigation
  • Updated GitHub button link to official repository URL
  • Changed href from https://github.com to
    https://github.com/rishabh3562/ToolBox
+3/-1     
theme-toggle.tsx
Create ThemeToggle component with icon animations               

components/theme-toggle.tsx

  • Created new client component for theme switching functionality
  • Implemented hydration-safe rendering with mounted state check
  • Added sun/moon icon animations using Tailwind dark mode variants
  • Includes accessibility features with aria-label and sr-only text
+30/-0   
Bug fix
page.tsx
Fix GitHub repository link in home page                                   

app/page.tsx

  • Updated GitHub link from generic homepage to official repository URL
  • Changed href from https://github.com to
    https://github.com/rishabh3562/ToolBox
+1/-1     
site-footer.tsx
Fix GitHub repository links in footer                                       

components/site-footer.tsx

  • Updated two GitHub links to point to official repository
  • Changed href from https://github.com to
    https://github.com/rishabh3562/ToolBox
  • Applied fix to both text link and GitHub icon link
+2/-2     
Dependencies
package.json
Update dependencies and add Upstash packages                         

package.json

  • Added @upstash/ratelimit and @upstash/redis dependencies
  • Updated Next.js from 13.5.1 to 16.0.0
  • Updated React Syntax Highlighter from 15.5.0 to 16.0.0
  • Updated PostCSS from 8.4.30 to 8.5.6
  • Reorganized dependency order for consistency
+6/-6     
Configuration changes
tsconfig.json
Update TypeScript configuration for Next.js 16                     

tsconfig.json

  • Changed JSX setting from "preserve" to "react-jsx"
  • Reformatted compiler options with improved array formatting
  • Added .next/dev/types/**/*.ts to include paths
  • Improved readability with consistent multi-line formatting
+20/-5   

Summary by CodeRabbit

  • New Features

    • Theme toggle in the header with system-aware detection and theme persistence; app layout now wraps content with a theme provider.
  • Bug Fixes

    • Further reduced SSR/hydration mismatches (delayed theme rendering, hydration warning suppression).
  • Style

    • Standardized color formats (HSL) and adjusted prose/border color tokens affecting theme appearance.
  • Chores

    • Updated repository links across the site.
    • Removed unused dependencies and added a dependency-install step in CI.

@github-actions
Copy link

Contributor License Agreement (CLA)

Thank you for your contribution to ToolBox.

By submitting this pull request, you automatically agree to our Contributor License Agreement (CLA).

Key Terms

  • You grant the project owner exclusive commercial rights to this project
  • You waive any claims to commercialization or royalties
  • You retain rights to use your contributions for non-commercial purposes
  • You confirm your contributions are your original work
  • This agreement is automatic upon submission

Full Agreement

Please review the complete CLA for all terms and conditions.

Questions

If you have questions about the CLA, please comment on this pull request or open a discussion.


By continuing with this pull request, you confirm your acceptance of the CLA.

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Wraps the app with a next-themes provider, adds a ThemeToggle client component and header integration, standardizes some CSS token uses to HSL and removes explicit light/dark custom presets, updates GitHub links to the specific repo, removes two Upstash deps, and adds an "Install dependencies" CI step.

Changes

Cohort / File(s) Summary
Layout / Providers
app/layout.tsx, components/providers.tsx
Adds Providers wrapper using next-themes around app content; suppressHydrationWarning added on <html>; new client Providers component exported.
Theme Toggle
components/theme-toggle.tsx
New client ThemeToggle component using next-themes, mounted-state to avoid SSR mismatch, toggles between dark and light, includes accessibility labels and icons.
Header Integration
components/site-header.tsx
Imports and renders ThemeToggle in header action group; updates GitHub link to https://github.com/rishabh3562/ToolBox.
Footer & Page Links
components/site-footer.tsx, app/page.tsx
Replaced generic GitHub links with https://github.com/rishabh3562/ToolBox.
Global Styles
app/globals.css
Removed explicit light/dark custom property presets; switched several prose color usages from rgb(var(...)) to hsl(var(...)); preserved base/dark adjustments.
Dependencies
package.json
Removed @upstash/ratelimit and @upstash/redis from dependencies.
CI Workflow
.github/workflows/ci-cd-pipeline.yml
Added "Install dependencies" step (npm ci --prefer-offline) before Vercel CLI install in Deploy Preview job.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Browser
    participant Providers as ThemeProvider
    participant ThemeToggle
    participant Storage as localStorage

    rect rgb(235,245,255)
    User->>Browser: Visit app
    Browser->>ThemeProvider: Initialize (attribute="class", default=system)
    ThemeProvider->>Storage: read "devtools-theme" or detect OS
    Storage-->>ThemeProvider: theme value
    ThemeProvider->>Browser: apply theme class on <html>
    end

    rect rgb(255,250,235)
    User->>ThemeToggle: Click toggle
    ThemeToggle->>ThemeProvider: setTheme("dark"/"light")
    ThemeProvider->>Storage: persist "devtools-theme"
    ThemeProvider->>Browser: update <html> class -> UI reflects theme
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Check hydration handling in components/theme-toggle.tsx and suppressHydrationWarning usage.
  • Verify next-themes configuration in components/providers.tsx (storageKey, disableTransitionOnChange).
  • Confirm HSL token changes in app/globals.css preserve intended contrast across themes.
  • Validate updated CI step order and that removed Upstash deps do not break builds.

Possibly related PRs

Poem

🐰 I hopped in with a toggle, bright and small,

Sun in one paw, Moon in the other to call.
Hues now hum in HSL delight,
Saved beneath a tiny key at night.
Click, I flip — the world feels right. 🌙☀️

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR contains at least one out-of-scope change: the removal of @upstash/ratelimit and @upstash/redis from package.json. This change is unrelated to the stated PR objectives (dark mode support and GitHub repository link fixes) and has no explanation in the PR objectives or comments. Additionally, the CI/CD workflow change adding an "npm ci --prefer-offline" installation step appears tangentially related to infrastructure changes but lacks clear justification as a necessity for the dark mode feature. While the GitHub link updates are explicitly mentioned in the PR title and the NODE_VERSION workflow change was intentionally retained, the Upstash package removal cannot be justified within the scope of the stated objectives. Remove the Upstash package removal from package.json (restore @upstash/ratelimit and @upstash/redis) unless there is a clear reason for their removal that should be documented in the PR. Alternatively, clarify in the PR description why the Upstash packages are being removed and whether the CI/CD workflow npm ci change is necessary for dark mode deployment. If these changes are truly required, they should be documented or separated into a distinct PR focused on dependency cleanup and infrastructure updates.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: Add dark mode support and fix GitHub repository links" accurately reflects the main changes in the changeset. The title clearly summarizes two distinct objectives: implementing dark mode functionality (including the ThemeToggle component, Providers wrapper, and theme persistence) and updating GitHub repository links from the generic URL to the specific ToolBox repository URL. The title is concise, avoids vague language, and provides meaningful information about the primary changes.
Linked Issues Check ✅ Passed The PR successfully implements all four main coding requirements from linked issue #1 (Add Dark Mode Support). A dark mode toggle button was added to the navigation header via the new ThemeToggle component. Dark mode styles were implemented using Tailwind's dark mode feature with corresponding CSS updates in globals.css and the new Providers component. User theme preference is persisted to localStorage via next-themes under the key "devtools-theme". Support for dark mode was extended to all tool pages by wrapping the root layout with the Providers component, ensuring theme functionality is globally available. All explicit coding tasks from the issue have been addressed through the component additions and CSS modifications.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7cc4b2 and 196c37b.

📒 Files selected for processing (2)
  • app/layout.tsx (2 hunks)
  • components/providers.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/layout.tsx
🔇 Additional comments (1)
components/providers.tsx (1)

1-17: LGTM! Clean implementation of theme provider.

The Providers component correctly integrates next-themes with appropriate configuration:

  • attribute="class" enables Tailwind's dark mode
  • defaultTheme="system" respects user's system preference
  • storageKey="devtools-theme" persists theme choice
  • disableTransitionOnChange prevents jarring CSS transition flashes

The "use client" directive is properly placed, and the component follows Next.js 13+ patterns for client-side theming.


Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link

qodo-code-review bot commented Oct 24, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Dependency upgrade risk

Description: Upgrading Next.js from 13.5.1 to ^16.0.0 without corresponding config/migration changes
may introduce runtime or build-time vulnerabilities or misconfigurations; verify
compatibility and security implications of major version jump.
package.json [57-75]

Referred Code
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.3.0",
"eslint": "8.49.0",
"eslint-config-next": "13.5.1",
"input-otp": "^1.2.4",
"lucide-react": "^0.446.0",
"mongodb": "^6.18.0",
"mongoose": "^8.17.0",
"next": "^16.0.0",
"next-themes": "^0.3.0",
"postcss": "^8.5.6",
"react": "18.2.0",
"react-day-picker": "^9.11.1",
"react-dom": "18.2.0",
"react-hook-form": "^7.53.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^2.1.3",
"react-syntax-highlighter": "^16.0.0",
"recharts": "^2.12.7",
Client-side storage use

Description: Using localStorage-backed theme via next-themes could expose or be tampered by client
script to force dark/light but has low security impact; ensure no sensitive logic depends
on theme storage key 'devtools-theme'.
layout.tsx [24-30]

Referred Code
<ThemeProvider
  attribute="class"
  defaultTheme="system"
  enableSystem
  storageKey="devtools-theme"
  disableTransitionOnChange
>
Ticket Compliance
🟡
🎫 #1
🟢 Add a dark mode toggle button in the navigation.
Implement dark mode styles using Tailwind's dark mode feature.
Persist user's theme preference in localStorage.
Update all tool pages to support dark mode.
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Oct 24, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Separate framework upgrade from feature implementation

The PR should be split into two: one for the Next.js version upgrade and another
for the dark mode feature. This separation helps isolate risks and simplifies
testing and review.

Examples:

package.json [65]
    "next": "^16.0.0",
components/theme-toggle.tsx [1-30]
"use client";

import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

export function ThemeToggle() {
  const [mounted, setMounted] = React.useState(false);
  const { theme, setTheme } = useTheme();


 ... (clipped 20 lines)

Solution Walkthrough:

Before:

// Current PR: Feature + Upgrade

// package.json
"dependencies": {
  "next": "^16.0.0", // Upgraded
  "next-themes": "^0.3.0", // New feature dependency
  ...
}

// components/theme-toggle.tsx
// New file for dark mode feature
export function ThemeToggle() { ... }

After:

// PR 1: Upgrade only
// package.json
"dependencies": {
  "next": "^16.0.0", // Upgraded
  ...
}
// No other feature files are added.

// PR 2: Feature only
// package.json
"dependencies": {
  "next": "13.5.1", // Unchanged
  "next-themes": "^0.3.0", // New feature dependency
  ...
}
// components/theme-toggle.tsx is added.
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a major framework upgrade (Next.js v13 to v16) bundled with a new feature, which is a significant risk and violates the best practice of separating unrelated, high-impact changes.

High
General
Use resolved theme for toggling
Suggestion Impact:The commit replaced theme with resolvedTheme in the hook destructuring and updated the toggle logic to use resolvedTheme.

code diff:

-  const { theme, setTheme } = useTheme();
+  const { resolvedTheme, setTheme } = useTheme(); // Changed: use resolvedTheme
 
   React.useEffect(() => {
     setMounted(true);
@@ -18,7 +18,7 @@
 
   return (
     <button
-      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
+      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")} // Changed: use resolvedTheme

Destructure resolvedTheme from the useTheme hook instead of theme. This is
necessary to correctly determine the currently active visual theme ('light' or
'dark'), especially when the user's preference is set to 'system'.

components/theme-toggle.tsx [9]

-const { theme, setTheme } = useTheme();
+const { resolvedTheme, setTheme } = useTheme();

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that using theme is problematic when the initial theme is 'system'. Using resolvedTheme is the standard practice with next-themes for a toggle button, as it correctly reflects the currently displayed theme. This change is a prerequisite for fixing the toggle logic.

Medium
Possible issue
Improve theme toggling logic
Suggestion Impact:The commit updated the handler to use resolvedTheme for toggling and adjusted the hook destructuring accordingly, matching the suggestion.

code diff:

-  const { theme, setTheme } = useTheme();
+  const { resolvedTheme, setTheme } = useTheme(); // Changed: use resolvedTheme
 
   React.useEffect(() => {
     setMounted(true);
@@ -18,7 +18,7 @@
 
   return (
     <button
-      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
+      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")} // Changed: use resolvedTheme
       className="relative inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors"

Update the onClick handler to use resolvedTheme for toggling. This ensures the
theme correctly switches between 'light' and 'dark', even when the initial theme
is 'system'.

components/theme-toggle.tsx [21]

-onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
+onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: This suggestion correctly fixes the theme toggling logic. The original code fails on the first click if the theme is 'system'. Using resolvedTheme ensures the toggle always switches between the currently displayed 'light' and 'dark' modes, which is the expected behavior for this type of component.

Medium
  • Update

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: 2

🧹 Nitpick comments (2)
components/theme-toggle.tsx (1)

7-29: Consider handling "system" theme in toggle logic.

The toggle currently switches between "dark" and "light", but users could be on "system" theme (as configured in layout.tsx). When a user on "system" theme clicks the toggle, consider which explicit theme to switch to based on the current resolved theme.

You can use resolvedTheme from useTheme() to determine the actual theme being displayed:

 export function ThemeToggle() {
   const [mounted, setMounted] = React.useState(false);
-  const { theme, setTheme } = useTheme();
+  const { resolvedTheme, setTheme } = useTheme();

   React.useEffect(() => {
     setMounted(true);
   }, []);

   if (!mounted) {
     return null;
   }

   return (
     <button
-      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
+      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
       className="relative inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors"
       aria-label="Toggle theme"
     >
       <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
       <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
       <span className="sr-only">Toggle theme</span>
     </button>
   );
 }
app/globals.css (1)

33-33: Optional: Remove trailing whitespace.

There's a trailing whitespace on line 33 that could be removed for consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7e70f5 and eb0b766.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • app/globals.css (3 hunks)
  • app/layout.tsx (2 hunks)
  • app/page.tsx (1 hunks)
  • components/site-footer.tsx (2 hunks)
  • components/site-header.tsx (2 hunks)
  • components/theme-toggle.tsx (1 hunks)
  • package.json (3 hunks)
  • tsconfig.json (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
app/layout.tsx (1)
components/site-header.tsx (1)
  • SiteHeader (15-54)
components/site-header.tsx (1)
components/theme-toggle.tsx (1)
  • ThemeToggle (7-30)
🔇 Additional comments (7)
app/page.tsx (1)

78-78: LGTM! GitHub link correctly updated.

The GitHub link now points to the specific repository, consistent with the changes throughout the PR.

components/site-footer.tsx (1)

16-16: LGTM! GitHub links properly updated.

Both GitHub references now point to the specific repository, maintaining consistency across the footer.

Also applies to: 26-26

package.json (1)

51-52: Verify whether Upstash dependencies should be removed.

The AI summary indicates that @upstash/ratelimit and @upstash/redis were removed, but these dependencies are still present in the package.json. Please clarify whether these should be removed or if the summary is incorrect.

app/globals.css (1)

98-98: LGTM! Color format corrected to HSL.

The changes from rgb() to hsl() properly align with the HSL-based CSS custom properties defined in the :root and .dark selectors.

Also applies to: 110-110, 115-115

components/site-header.tsx (2)

8-8: LGTM! ThemeToggle properly integrated.

The ThemeToggle component is correctly imported and rendered in the header's action area, providing easy access to theme switching.

Also applies to: 44-44


46-46: LGTM! GitHub link updated consistently.

The GitHub link now points to the specific repository, matching the updates in other components.

app/layout.tsx (1)

6-6: LGTM! ThemeProvider integration is well-configured.

The ThemeProvider setup follows best practices:

  • suppressHydrationWarning prevents hydration mismatches
  • Configuration properly enables system theme detection
  • Storage key matches the PR objectives
  • disableTransitionOnChange prevents visual glitches during theme switches

Also applies to: 22-36

@aryadharmadhikari
Copy link
Contributor Author

@rishabh3562 the CI/CD failures are due to the workflow using Node.js 18.20.8, but my PR updates Next.js to v16.0.0 which requires Node.js ≥20.9.0.​

Next.js 16 has many benefits, to convince you:

  1. 5-10x faster Fast Refresh with stable Turbopack​
  2. React 19 support with latest features​
  3. Better performance with React Compiler and optimized routing​

Fix:

I'm updating the workflow in this PR (line 31 in .github/workflows/ci-cd-pipeline.yml):

Code:

NODE_VERSION: '20.x' # Changed from '18.x'

This will resolve all failing checks. The workflow changes will apply immediately when I push the commit.​

aryadharmadhikari and others added 3 commits October 24, 2025 14:35
Reverted package versions to match main branch:
- next: 16.0.0 → 13.5.1
- postcss: ^8.5.6 → 8.4.30
- react-syntax-highlighter: ^16.0.0 → ^15.5.0
- tsconfig.json: jsx setting updated to "preserve" for Next.js compatibility

The workflow's Node.js version upgrade to 20.x is retained.

This fixes the CI/CD pipeline error where `next lint` was failing
due to version incompatibilities introduced by the Next.js 16 upgrade.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add "docs" to tsconfig.json exclude list to prevent TypeScript errors
  from Docusaurus files that don't have their dependencies installed
- Sync tsconfig.json formatting with main branch
- This fixes the CI/CD TypeScript check failure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@rishabh3562
Copy link
Owner

Hi @aryadharmadhikari,

I’ve pushed a fix to this PR to keep it consistent with the main branch:

Reverted Next.js to 13.5.1 (was upgraded to 16)

Reverted postcss and react-syntax-highlighter to match main

Updated tsconfig.json (jsx: preserve) for Next.js 13

Kept the Node 20.x workflow upgrade

While I agree that Next.js 16 is the way forward, 16.0.0 is not recommended yet, especially since several forks are still actively working on 13.5.1. This ensures stability and compatibility for everyone currently working on the project.

The PR now contains only the dark mode and GitHub link updates, and the CI/CD pipeline should pass.

- Add "npm ci" before building in deploy-preview job
- This fixes "next: not found" error when vercel build falls back to npm run build
- Dependencies are now installed before attempting to build the project

The error occurred because:
1. Vercel build failed (VERCEL_TOKEN not configured)
2. Fallback to npm run build was triggered
3. But dependencies were never installed, causing "next: not found"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@rishabh3562
Copy link
Owner

@CodeRabbit in deployment of this i can see dark mode but the toggle is not working , please check this pr and tell me if this is a logic issue or what is happening

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the ThemeToggle component implementation
cat components/theme-toggle.tsx

Length of output: 1294


🏁 Script executed:

#!/bin/bash
# Read the layout.tsx implementation
cat app/layout.tsx

Length of output: 1123


🏁 Script executed:

#!/bin/bash
# Check if next-themes is properly installed
cat package.json | grep -A2 -B2 "next-themes"

Length of output: 125


🏁 Script executed:

#!/bin/bash
# Check the globals.css to see dark mode setup
cat app/globals.css | head -100

Length of output: 2526


🏁 Script executed:

#!/bin/bash
# Check tailwind config for dark mode setup
cat tailwind.config.ts 2>/dev/null || cat tailwind.config.js 2>/dev/null || echo "Tailwind config not found in root"

Length of output: 3484


🏁 Script executed:

#!/bin/bash
# Find tailwind config in any location
fd "tailwind.config" --type f

Length of output: 42


@rishabh3562 I found the issue! There's a logic bug in the theme toggle component. Here's what's happening:

The Problem

In components/theme-toggle.tsx, the toggle uses theme instead of resolvedTheme:

onClick={() => setTheme(theme === "dark" ? "light" : "dark")}

When defaultTheme="system" is set:

  • If a user has dark system preference, the page displays in dark mode
  • But theme value is "system" (not "dark")
  • First click: theme !== "dark", so it sets to "dark"no visual change because it's already dark!
  • Second click: theme === "dark", so it sets to "light" → now it changes

The Fix

Update components/theme-toggle.tsx to use resolvedTheme:

"use client";

import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

export function ThemeToggle() {
  const [mounted, setMounted] = React.useState(false);
  const { resolvedTheme, setTheme } = useTheme(); // Changed: use resolvedTheme

  React.useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return null;
  }

  return (
    <button
      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")} // Changed: use resolvedTheme
      className="relative inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors"
      aria-label="Toggle theme"
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </button>
  );
}

What changed: themeresolvedTheme (in both destructuring and onClick)

resolvedTheme returns the actual theme being displayed (either "light" or "dark"), accounting for system preferences, while theme returns the user's preference (which can be "system", "light", or "dark").

Additional Deployment Checks

If the fix doesn't work immediately in deployment:

  1. Clear build cache:

    rm -rf .next
    npm run build
  2. Clear browser storage (in browser DevTools Console):

    localStorage.removeItem('devtools-theme');
    location.reload();
  3. Verify JavaScript is loading - Check browser console for any errors

Let me know once you apply this fix and I can verify the solution! 🐰

@rishabh3562
Copy link
Owner

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain
🏁 Script executed:

#!/bin/bash
# Read the ThemeToggle component implementation
cat components/theme-toggle.tsx

Length of output: 1294

🏁 Script executed:

#!/bin/bash
# Read the layout.tsx implementation
cat app/layout.tsx

Length of output: 1123

🏁 Script executed:

#!/bin/bash
# Check if next-themes is properly installed
cat package.json | grep -A2 -B2 "next-themes"

Length of output: 125

🏁 Script executed:

#!/bin/bash
# Check the globals.css to see dark mode setup
cat app/globals.css | head -100

Length of output: 2526

🏁 Script executed:

#!/bin/bash
# Check tailwind config for dark mode setup
cat tailwind.config.ts 2>/dev/null || cat tailwind.config.js 2>/dev/null || echo "Tailwind config not found in root"

Length of output: 3484

🏁 Script executed:

#!/bin/bash
# Find tailwind config in any location
fd "tailwind.config" --type f

Length of output: 42

@rishabh3562 I found the issue! There's a logic bug in the theme toggle component. Here's what's happening:

The Problem

In components/theme-toggle.tsx, the toggle uses theme instead of resolvedTheme:

onClick={() => setTheme(theme === "dark" ? "light" : "dark")}

When defaultTheme="system" is set:

  • If a user has dark system preference, the page displays in dark mode
  • But theme value is "system" (not "dark")
  • First click: theme !== "dark", so it sets to "dark"no visual change because it's already dark!
  • Second click: theme === "dark", so it sets to "light" → now it changes

The Fix

Update components/theme-toggle.tsx to use resolvedTheme:

"use client";

import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

export function ThemeToggle() {
  const [mounted, setMounted] = React.useState(false);
  const { resolvedTheme, setTheme } = useTheme(); // Changed: use resolvedTheme

  React.useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return null;
  }

  return (
    <button
      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")} // Changed: use resolvedTheme
      className="relative inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors"
      aria-label="Toggle theme"
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </button>
  );
}

What changed: themeresolvedTheme (in both destructuring and onClick)

resolvedTheme returns the actual theme being displayed (either "light" or "dark"), accounting for system preferences, while theme returns the user's preference (which can be "system", "light", or "dark").

Additional Deployment Checks

If the fix doesn't work immediately in deployment:

  1. Clear build cache:
    rm -rf .next
    npm run build
  2. Clear browser storage (in browser DevTools Console):
    localStorage.removeItem('devtools-theme');
    location.reload();
  3. Verify JavaScript is loading - Check browser console for any errors

Let me know once you apply this fix and I can verify the solution! 🐰

@aryadharmadhikari please fix this , i am requesting changes

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: 0

🧹 Nitpick comments (1)
components/theme-toggle.tsx (1)

7-30: Consider adding a three-way toggle cycle (optional enhancement).

The current implementation toggles between "dark" and "light" only. A common UX pattern is to cycle through three states: light → dark → system, allowing users to return to system preference after a manual override.

Example implementation:

   return (
     <button
-      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
+      onClick={() => {
+        const { theme } = useTheme();
+        if (theme === "light") setTheme("dark");
+        else if (theme === "dark") setTheme("system");
+        else setTheme("light");
+      }}
       className="relative inline-flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition-colors"
       aria-label="Toggle theme"
     >

Note: You would need to destructure theme from useTheme() in addition to resolvedTheme to check the current theme setting (which can be "system"), and update the icon display logic to show a third icon (e.g., a Monitor/Laptop icon) when theme === "system".

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e42b684 and c7cc4b2.

📒 Files selected for processing (2)
  • .github/workflows/ci-cd-pipeline.yml (1 hunks)
  • components/theme-toggle.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci-cd-pipeline.yml
🔇 Additional comments (1)
components/theme-toggle.tsx (1)

9-9: LGTM! The resolvedTheme fix correctly addresses the toggle bug.

Using resolvedTheme instead of theme ensures the toggle works correctly when the theme is set to "system". The resolvedTheme property always returns the actual applied theme ("dark" or "light"), while theme can be "system", which would have caused the toggle logic to fail.

Also applies to: 21-21

@rishabh3562
Copy link
Owner

@CodeRabbit what is the issue , the toggle is still not working, pin point the error so that i can fix it , secondly everything else looks good to me , whats your take (yes or no)

@coderabbitai
Copy link

coderabbitai bot commented Oct 25, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the current implementation of theme-toggle.tsx
echo "=== Current theme-toggle.tsx implementation ==="
cat components/theme-toggle.tsx

echo -e "\n=== Current layout.tsx implementation ==="
cat app/layout.tsx

echo -e "\n=== Check next-themes version ==="
cat package.json | grep -A1 "next-themes"

echo -e "\n=== Check tailwind.config for dark mode ==="
if [ -f tailwind.config.ts ]; then
  cat tailwind.config.ts | grep -A3 "darkMode"
elif [ -f tailwind.config.js ]; then
  cat tailwind.config.js | grep -A3 "darkMode"
fi

echo -e "\n=== Check for any TypeScript errors in theme-toggle ==="
cat components/theme-toggle.tsx | head -30

Length of output: 3631


@rishabh3562 Good news! The code is actually correct now - the fix has been applied properly. The issue is deployment/caching, not the code itself.

🎯 Pinpointed Issue: Deployment Cache

The theme-toggle.tsx correctly uses resolvedTheme, ThemeProvider is properly configured, and Tailwind's dark mode is set up correctly. The toggle not working in deployment is because:

The deployed build is using cached/old JavaScript files.

🔧 How to Fix (Choose One):

Option 1: Force Vercel Rebuild (Recommended)

# In your local terminal
git commit --allow-empty -m "trigger rebuild"
git push

Option 2: Clear Vercel Build Cache

  1. Go to Vercel Dashboard → Project Settings
  2. Navigate to "General" → "Build & Development Settings"
  3. Click "Clear Build Cache" and redeploy

Option 3: Manual Deployment Command

# If you have Vercel CLI
vercel --prod --force

After redeploying, users should hard refresh their browsers (Ctrl+Shift+R or Cmd+Shift+R) to clear cached JavaScript.

✅ My Take: YES

Everything else in the PR is excellent:

Dark mode implementation: Properly configured with next-themes, class-based, system preference support
GitHub links: All updated correctly to repository URL
globals.css: Conflicting media queries removed, HSL formats fixed
Hydration handling: suppressHydrationWarning and mounted state correctly implemented
Accessibility: Proper ARIA labels and sr-only text
Dependencies: next-themes and lucide-react properly added

Recommendation: Approve and merge once the deployment cache is cleared.

The code is production-ready. The toggle will work perfectly after a fresh build is deployed. 🐰

@vercel
Copy link

vercel bot commented Oct 25, 2025

@rishabh3562 is attempting to deploy a commit to the rishabh's projects Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link

vercel bot commented Oct 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
tool-box Ready Ready Preview Comment Oct 25, 2025 8:32pm

…mpatibility

- Extract ThemeProvider into a separate client component (components/providers.tsx)
- Fix theme toggle functionality by ensuring ThemeProvider runs on client-side
- Resolves hydration mismatch and theme state persistence issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@rishabh3562
Copy link
Owner

Thanks for the PR and the detailed implementation! I noticed that the dark mode setup is causing hydration/rendering issues because ThemeProvider from next-themes is used directly in app/layout.tsx, which is a server component.

To fix this, wrap ThemeProvider in a client component (with "use client";) and use that wrapper in layout.tsx. This ensures the theme logic only runs in the browser, preventing hydration mismatches and making the theme toggle functional.

Once this is addressed, CI/CD and local testing should work correctly without SSR issues.

@aryadharmadhikari
Copy link
Contributor Author

aryadharmadhikari commented Oct 26, 2025

Thanks for the PR and the detailed implementation! I noticed that the dark mode setup is causing hydration/rendering issues because ThemeProvider from next-themes is used directly in app/layout.tsx, which is a server component.

To fix this, wrap ThemeProvider in a client component (with "use client";) and use that wrapper in layout.tsx. This ensures the theme logic only runs in the browser, preventing hydration mismatches and making the theme toggle functional.

Once this is addressed, CI/CD and local testing should work correctly without SSR issues.

@rishabh3562 I just checked the CI/CD pipeline PR opened and merged by you. It has been mentioned over there that the deployments will be skipped until the GitHub secrets are configured, and similar errors of it being not configured are visible during the CI/CD Deploy Preview check. Have you configured them?

Additionally the API routes(templates and health) are currently static export, this will further cause an issue.

@rishabh3562
Copy link
Owner

@aryadharmadhikari The repo secrets are already configured. GitHub doesn’t pass them to workflows triggered from forks, which is why the deploy preview initially failed. I’ve run the workflow manually, and the deployment works fine now. I’ll be merging this soon. Thanks for your patience! If you’d like to discuss further, feel free to continue the conversation on this PR or in the discussions channel.

Starring the repo and following me is appreciated.

@rishabh3562 rishabh3562 merged commit 007787a into rishabh3562:main Oct 27, 2025
11 of 13 checks passed
@rishabh3562 rishabh3562 added the hacktoberfest-accepted Label to mark PRs accepted for Hacktoberfest label Oct 27, 2025
@aryadharmadhikari
Copy link
Contributor Author

@rishabh3562 Thank you so much for your collaboration and for the time you invested in reviewing and implementing improvements to this PR!

This being one of my early open source contributions, I have gained invaluable experience navigating real-world CI/CD issues, understanding Next.js architecture decisions, and learning how production projects are structured and maintained. Your guidance and patience throughout this process have been incredibly helpful.

I really appreciate the opportunity to contribute to ToolBox, and I would like to continue contributing beyond Hacktoberfest whenever I can. Looking forward to collaborating on future improvements!

@rishabh3562
Copy link
Owner

Glad to hear this experience helped you understand how things work in real-world workflows; that’s exactly what open source should deliver. You’re welcome to continue contributing to ToolBox beyond Hacktoberfest

@rishabh3562 rishabh3562 mentioned this pull request Oct 27, 2025
19 tasks
@aryadharmadhikari aryadharmadhikari deleted the feat/dark-theme branch October 27, 2025 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hacktoberfest-accepted Label to mark PRs accepted for Hacktoberfest Review effort 3/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Dark Mode Support

2 participants