mirror of
https://git.aramjonghu.nl/AramJonghu/aramjonghu-site.git
synced 2026-06-06 17:18:24 +02:00
Dark/light mode added + switcher
This commit is contained in:
@@ -9,7 +9,7 @@ export default function Footer() {
|
||||
};
|
||||
|
||||
return (
|
||||
<footer className="flex items-center justify-between px-24 py-6 border-t border-ctp-lavender-800 mt-10">
|
||||
<footer className="bg-ctp-mantle flex items-center justify-between px-24 py-6 border-t border-ctp-lavender-800 mt-10">
|
||||
<p className="text-sm text-ctp-text">
|
||||
© {currentYear} AramJonghu. All rights reserved.
|
||||
</p>
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
import Aku from "../assets/images/aku.png";
|
||||
|
||||
export default function Header() {
|
||||
export default function Header({ theme }) {
|
||||
const { theme: currentTheme, toggleTheme } = theme;
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
label: "Nextcloud",
|
||||
url: "https://aramjonghu.nl/nextcloud",
|
||||
},
|
||||
{
|
||||
label: "Navidrome",
|
||||
url: "https://music.aramjonghu.nl",
|
||||
},
|
||||
{
|
||||
label: "Forgejo Git",
|
||||
url: "https://git.aramjonghu.nl",
|
||||
},
|
||||
{
|
||||
label: "Stream",
|
||||
url: "https://stream.aramjonghu.nl",
|
||||
},
|
||||
{
|
||||
label: "SearXNG",
|
||||
url: "https://xng.aramjonghu.nl",
|
||||
},
|
||||
{ label: "Nextcloud", url: "https://aramjonghu.nl/nextcloud" },
|
||||
{ label: "Navidrome", url: "https://music.aramjonghu.nl" },
|
||||
{ label: "Forgejo Git", url: "https://git.aramjonghu.nl" },
|
||||
{ label: "Stream", url: "https://stream.aramjonghu.nl" },
|
||||
{ label: "SearXNG", url: "https://xng.aramjonghu.nl" },
|
||||
];
|
||||
|
||||
const goHome = () => {
|
||||
@@ -29,7 +16,7 @@ export default function Header() {
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="flex justify-center items-center px-12 py-6 gap-6 border-b border-ctp-lavender-800">
|
||||
<header className="bg-ctp-mantle flex justify-between items-center px-12 py-6 gap-6 border-b border-ctp-lavender-800">
|
||||
<img
|
||||
className="size-16 cursor-pointer"
|
||||
src={Aku}
|
||||
@@ -48,6 +35,15 @@ export default function Header() {
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div>
|
||||
<button
|
||||
className="text-ctp-text hover:text-ctp-green-900 border rounded border-ctp-white-800 hover:border-ctp-green-900 cursor-pointer px-3 py-1"
|
||||
onClick={toggleTheme}
|
||||
>
|
||||
{currentTheme === "macchiato" ? "🌙 Dark" : "☀️ Light"}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import Footer from "./Footer";
|
||||
import Header from "./Header";
|
||||
import { useTheme } from "../hooks/useTheme";
|
||||
|
||||
export default function Layout({ children }) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-screen min-h-screen bg-ctp-base">
|
||||
<Header />
|
||||
<Header theme={theme} />
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getInitialTheme, applyTheme, toggleTheme } from "../utils/theme";
|
||||
|
||||
export function useTheme() {
|
||||
const [theme, setTheme] = useState(getInitialTheme);
|
||||
|
||||
useEffect(() => {
|
||||
applyTheme(theme);
|
||||
}, [theme]);
|
||||
|
||||
const handleToggle = () => {
|
||||
setTheme((prev) => toggleTheme(prev));
|
||||
};
|
||||
|
||||
return { theme, toggleTheme: handleToggle };
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
const LIGHT = "latte";
|
||||
const DARK = "macchiato";
|
||||
|
||||
export function getSystemTheme() {
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? DARK
|
||||
: LIGHT;
|
||||
}
|
||||
|
||||
export function getStoredTheme() {
|
||||
return localStorage.getItem("theme");
|
||||
}
|
||||
|
||||
export function getInitialTheme() {
|
||||
return getStoredTheme() || getSystemTheme();
|
||||
}
|
||||
|
||||
export function applyTheme(theme) {
|
||||
const root = document.documentElement;
|
||||
|
||||
root.classList.remove(LIGHT, DARK);
|
||||
|
||||
root.classList.add(theme);
|
||||
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
|
||||
export function toggleTheme(current) {
|
||||
return current === DARK ? LIGHT : DARK;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
darkMode: "class",
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
Reference in New Issue
Block a user