mirror of
https://github.com/hex248/sprint.git
synced 2026-02-08 02:33:01 +00:00
light/dark mode
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
30
packages/frontend/src/components/theme-toggle.tsx
Normal file
30
packages/frontend/src/components/theme-toggle.tsx
Normal 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;
|
||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user