Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions apps/web/app/(org)/dashboard/_components/Navbar/Mobile.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"use client";

import { LogoBadge } from "@cap/ui";
import { faMoon, faSun } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useClickAway } from "@uidotdev/usehooks";
import { AnimatePresence, motion } from "framer-motion";
import { X } from "lucide-react";
import Link from "next/link";
import { type MutableRefObject, useState } from "react";

import { ThemeToggleIcon } from "@/components/theme-toggle-icon";
import { useTheme } from "../../Contexts";
import NavItems from "./Items";

Expand Down Expand Up @@ -61,10 +61,7 @@ export const AdminMobileNav = () => {
}}
className="flex justify-center items-center rounded-full border transition-colors cursor-pointer lg:hidden bg-gray-4 hover:border-gray-6 hover:bg-gray-5 size-9 border-gray-5"
>
<FontAwesomeIcon
className="text-gray-12 size-3.5"
icon={theme === "dark" ? faSun : faMoon}
/>
<ThemeToggleIcon />
</div>
</div>
</div>
Expand Down
8 changes: 3 additions & 5 deletions apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@cap/ui";
import { faBell, faMoon, faSun } from "@fortawesome/free-solid-svg-icons";
import { faBell } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useClickAway } from "@uidotdev/usehooks";
Expand All @@ -31,6 +31,7 @@ import {
import { markAsRead } from "@/actions/notifications/mark-as-read";
import Notifications from "@/app/(org)/dashboard/_components/Notifications";
import { SignedImageUrl } from "@/components/SignedImageUrl";
import { ThemeToggleIcon } from "@/components/theme-toggle-icon";
import { UpgradeModal } from "@/components/UpgradeModal";
import { useDashboardContext, useTheme } from "../../Contexts";
import {
Expand Down Expand Up @@ -170,10 +171,7 @@ const Top = () => {
}}
className="hidden justify-center items-center rounded-full transition-colors cursor-pointer bg-gray-3 lg:flex hover:bg-gray-5 size-9"
>
<FontAwesomeIcon
className="text-gray-12 size-3.5 view-transition-theme-icon"
icon={theme === "dark" ? faMoon : faSun}
/>
<ThemeToggleIcon />
</div>
<User />
</div>
Expand Down
23 changes: 23 additions & 0 deletions apps/web/components/theme-toggle-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "@/app/(org)/dashboard/Contexts";

export const ThemeToggleIcon = () => {
const { theme } = useTheme();

return (
<button
type="button"
className="view-transition-theme-icon"
aria-label={
theme === "dark" ? "Switch to light theme" : "Switch to dark theme"
}
>
{theme === "dark" ? (
<Moon size={17} className="fill-white stroke-gray-3" />
) : (
<Sun size={17} className="stroke-gray-12" />
)}
</button>
);
};
Comment on lines 5 to 17
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Button lacks onClick handler to toggle the theme.

The button has an aria-label indicating it should toggle the theme, but there's no onClick handler attached. This makes the button non-functional—clicking it won't change the theme.

Verify what the useTheme hook returns and add the appropriate handler:

Once verified, apply a fix similar to this:

 export const ThemeToggleIcon = () => {
-	const { theme } = useTheme();
+	const { theme, toggleTheme } = useTheme();

 	return (
 		<button
 			type="button"
 			className="view-transition-theme-icon"
+			onClick={toggleTheme}
 			aria-label={
 				theme === "dark" ? "Switch to light theme" : "Switch to dark theme"
 			}
 		>

Note: Adjust the destructured property name (e.g., setTheme, toggle) based on what the context actually provides.


🏁 Script executed:

#!/bin/bash
# Check what properties/methods the ThemeContext provides
ast-grep --pattern $'export const ThemeContext = createContext<$_>($_)'

# Also check the ThemeProvider implementation to see available methods
rg -nP --type=tsx -A 10 'ThemeProvider|ThemeContext' apps/web/app/

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Search for useTheme hook definition - check common locations
fd -e ts -e tsx | xargs grep -l "useTheme" | head -5

# Search for ThemeContext definition more broadly
rg -n "ThemeContext|useTheme" --type=ts -B 2 -A 5 | head -50

# Look for hook definition in lib or hooks directories
fd "use.*theme" -i

Length of output: 3750


🏁 Script executed:

#!/bin/bash
# Find the exact location and full content of theme-toggle-icon.tsx
fd "theme-toggle-icon" -e tsx

# Check how setThemeHandler is called in Top.tsx or other files
rg -n "setThemeHandler" --type=ts -B 2 -A 2

Length of output: 3516


🏁 Script executed:

#!/bin/bash
# Get the full content of theme-toggle-icon.tsx
cat apps/web/components/theme-toggle-icon.tsx

Length of output: 530


Add onClick handler to enable theme toggling.

The button is non-functional—it has no onClick handler despite the aria-label indicating it should toggle the theme. The setThemeHandler method is available from useTheme() but is not being destructured or called.

Fix at apps/web/components/theme-toggle-icon.tsx:

 export const ThemeToggleIcon = () => {
-	const { theme } = useTheme();
+	const { theme, setThemeHandler } = useTheme();
 
 	return (
 		<button
 			type="button"
 			className="view-transition-theme-icon"
+			onClick={() => {
+				if (document.startViewTransition) {
+					document.startViewTransition(() => {
+						setThemeHandler(theme === "light" ? "dark" : "light");
+					});
+				} else {
+					setThemeHandler(theme === "light" ? "dark" : "light");
+				}
+			}}
 			aria-label={
 				theme === "dark" ? "Switch to light theme" : "Switch to dark theme"
 			}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const ThemeToggleIcon = () => {
const { theme } = useTheme();
return (
<button
type="button"
className="view-transition-theme-icon"
aria-label={
theme === "dark" ? "Switch to light theme" : "Switch to dark theme"
}
>
{theme === "dark" ? (
<Moon size={17} className="fill-white stroke-gray-3" />
) : (
<Sun size={17} className="stroke-gray-12" />
)}
</button>
);
};
export const ThemeToggleIcon = () => {
const { theme, setThemeHandler } = useTheme();
return (
<button
type="button"
className="view-transition-theme-icon"
onClick={() => {
if (document.startViewTransition) {
document.startViewTransition(() => {
setThemeHandler(theme === "light" ? "dark" : "light");
});
} else {
setThemeHandler(theme === "light" ? "dark" : "light");
}
}}
aria-label={
theme === "dark" ? "Switch to light theme" : "Switch to dark theme"
}
>
{theme === "dark" ? (
<Moon size={17} className="fill-white stroke-gray-3" />
) : (
<Sun size={17} className="stroke-gray-12" />
)}
</button>
);
};
🤖 Prompt for AI Agents
In apps/web/components/theme-toggle-icon.tsx around lines 5 to 23, the component
reads theme from useTheme but doesn't destructure or call the setThemeHandler so
the button does nothing; update the hook destructuring to get setThemeHandler
(or whatever the setter is named) and add an onClick on the button that calls it
to toggle the theme (e.g. call setThemeHandler(theme === "dark" ? "light" :
"dark") when clicked), keeping the existing aria-label logic and icon rendering
unchanged.