diff --git a/client/src/components/app-sidebar.tsx b/client/src/components/app-sidebar.tsx
index 5245ad8febd..e47a067b9d9 100644
--- a/client/src/components/app-sidebar.tsx
+++ b/client/src/components/app-sidebar.tsx
@@ -1,16 +1,17 @@
import { Calendar, Home, Inbox, Search, Settings } from "lucide-react";
import { useParams } from "react-router-dom";
+import { ThemeToggle } from "@/components/theme-toggle";
import {
Sidebar,
SidebarContent,
+ SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
- SidebarTrigger,
} from "@/components/ui/sidebar";
// Menu items.
@@ -51,6 +52,9 @@ export function AppSidebar() {
+
+
+
);
}
diff --git a/client/src/components/theme-toggle.tsx b/client/src/components/theme-toggle.tsx
new file mode 100644
index 00000000000..91677a4a78b
--- /dev/null
+++ b/client/src/components/theme-toggle.tsx
@@ -0,0 +1,19 @@
+import { Moon, Sun } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { useTheme } from "@/hooks/use-theme";
+
+export function ThemeToggle() {
+ const { theme, setTheme } = useTheme();
+
+ return (
+
+ );
+}
diff --git a/client/src/hooks/use-theme.tsx b/client/src/hooks/use-theme.tsx
new file mode 100644
index 00000000000..8dd3f1cd2b6
--- /dev/null
+++ b/client/src/hooks/use-theme.tsx
@@ -0,0 +1,32 @@
+import { useEffect, useState } from "react";
+
+type Theme = "dark" | "light" | "system";
+
+function useTheme() {
+ const [theme, setTheme] = useState(
+ () => (localStorage.getItem("theme") as Theme) || "system"
+ );
+
+ useEffect(() => {
+ const media = window.matchMedia("(prefers-color-scheme: dark)");
+
+ function applyTheme() {
+ const root = window.document.documentElement;
+ const systemTheme = media.matches ? "dark" : "light";
+ const activeTheme = theme === "system" ? systemTheme : theme;
+
+ root.classList.remove("light", "dark");
+ root.classList.add(activeTheme);
+ localStorage.setItem("theme", theme);
+ }
+
+ applyTheme();
+ media.addEventListener("change", applyTheme);
+ return () => media.removeEventListener("change", applyTheme);
+ }, [theme]);
+
+ return { theme, setTheme } as const;
+}
+
+export { useTheme };
+export type { Theme };
diff --git a/client/src/main.tsx b/client/src/main.tsx
index 9b1aa69de2d..1c467c7d849 100644
--- a/client/src/main.tsx
+++ b/client/src/main.tsx
@@ -5,6 +5,12 @@ import "./index.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RouterProvider } from "react-router-dom";
import { router } from "./router.tsx";
+
+// Initialize theme
+const theme = localStorage.getItem("theme") || "system";
+const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
+document.documentElement.classList.add(theme === "system" ? systemTheme : theme);
+
// Create a client
const queryClient = new QueryClient();