light/dark mode

This commit is contained in:
Oliver Bryan
2026-01-11 16:23:13 +00:00
parent 5d7faa9ed7
commit 7f40e73678
4 changed files with 54 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="dark">
<html lang="en" class="">
<!-- class="dark" makes the app dark mode -->
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
@@ -8,10 +10,25 @@
<style> <style>
html, html,
body { body {
background-color: oklch(0.145 0 0); background-color: var(--background);
color: oklch(0.985 0 0); color: var(--foreground);
} }
</style> </style>
<script>
const theme = localStorage.getItem("theme");
if (theme === "dark") document.documentElement.classList.add("dark");
else if (theme === "light")
document.documentElement.classList.remove("dark");
if (theme === null) {
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
if (prefersDark) document.documentElement.classList.add("dark");
else document.documentElement.classList.remove("dark");
}
</script>
</head> </head>
<body> <body>

View File

@@ -0,0 +1,30 @@
import { Moon, Sun } from "lucide-react";
import { useTheme } from "@/components/theme-provider";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
function ThemeToggle({ className }: { className?: string }) {
const { theme, setTheme } = useTheme();
const resolvedTheme =
theme === "system"
? window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: theme;
const isDark = resolvedTheme === "dark";
return (
<Button
type="button"
variant="dummy"
size="icon"
className={cn("hover:text-muted-foreground", className)}
onClick={() => setTheme(isDark ? "light" : "dark")}
title={isDark ? "Switch to light mode" : "Switch to dark mode"}
>
{isDark ? <Sun className="size-5" /> : <Moon className="size-5" />}
</Button>
);
}
export default ThemeToggle;

View File

@@ -19,6 +19,7 @@ import { ProjectSelect } from "@/components/project-select";
import { ServerConfigurationDialog } from "@/components/server-configuration-dialog"; import { ServerConfigurationDialog } from "@/components/server-configuration-dialog";
import { useAuthenticatedSession } from "@/components/session-provider"; import { useAuthenticatedSession } from "@/components/session-provider";
import SmallUserDisplay from "@/components/small-user-display"; import SmallUserDisplay from "@/components/small-user-display";
import ThemeToggle from "@/components/theme-toggle";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
DropdownMenu, DropdownMenu,
@@ -388,6 +389,7 @@ export default function App() {
)} )}
</div> </div>
<div className={`flex gap-${BREATHING_ROOM} items-center`}> <div className={`flex gap-${BREATHING_ROOM} items-center`}>
<ThemeToggle />
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger className="text-sm"> <DropdownMenuTrigger className="text-sm">
<SmallUserDisplay user={user} /> <SmallUserDisplay user={user} />

View File

@@ -1,6 +1,7 @@
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { useSession } from "@/components/session-provider"; import { useSession } from "@/components/session-provider";
import ThemeToggle from "@/components/theme-toggle";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
export default function Landing() { export default function Landing() {
@@ -11,6 +12,7 @@ export default function Landing() {
<header className="relative flex items-center justify-center p-2 border-b"> <header className="relative flex items-center justify-center p-2 border-b">
<div className="text-3xl font-basteleur font-700">Issue</div> <div className="text-3xl font-basteleur font-700">Issue</div>
<nav className="absolute right-2 flex items-center gap-4"> <nav className="absolute right-2 flex items-center gap-4">
<ThemeToggle />
{!isLoading && user ? ( {!isLoading && user ? (
<> <>
{user && ( {user && (