mirror of
https://git.aramjonghu.nl/AramJonghu/aramjonghu-site.git
synced 2026-06-07 01:28:24 +02:00
Dark/light mode added + switcher
This commit is contained in:
+10
-10
@@ -1,12 +1,12 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<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" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>aramjonghu-site</title>
|
<title>aramjonghu-site</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-ctp-base">
|
<body class="bg-ctp-base">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.jsx"></script>
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default function Footer() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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">
|
<p className="text-sm text-ctp-text">
|
||||||
© {currentYear} AramJonghu. All rights reserved.
|
© {currentYear} AramJonghu. All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,27 +1,14 @@
|
|||||||
import Aku from "../assets/images/aku.png";
|
import Aku from "../assets/images/aku.png";
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header({ theme }) {
|
||||||
|
const { theme: currentTheme, toggleTheme } = theme;
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{
|
{ label: "Nextcloud", url: "https://aramjonghu.nl/nextcloud" },
|
||||||
label: "Nextcloud",
|
{ label: "Navidrome", url: "https://music.aramjonghu.nl" },
|
||||||
url: "https://aramjonghu.nl/nextcloud",
|
{ label: "Forgejo Git", url: "https://git.aramjonghu.nl" },
|
||||||
},
|
{ label: "Stream", url: "https://stream.aramjonghu.nl" },
|
||||||
{
|
{ label: "SearXNG", url: "https://xng.aramjonghu.nl" },
|
||||||
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 = () => {
|
const goHome = () => {
|
||||||
@@ -29,7 +16,7 @@ export default function Header() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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
|
<img
|
||||||
className="size-16 cursor-pointer"
|
className="size-16 cursor-pointer"
|
||||||
src={Aku}
|
src={Aku}
|
||||||
@@ -48,6 +35,15 @@ export default function Header() {
|
|||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</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>
|
</header>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import Footer from "./Footer";
|
import Footer from "./Footer";
|
||||||
import Header from "./Header";
|
import Header from "./Header";
|
||||||
|
import { useTheme } from "../hooks/useTheme";
|
||||||
|
|
||||||
export default function Layout({ children }) {
|
export default function Layout({ children }) {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-screen min-h-screen bg-ctp-base">
|
<div className="flex flex-col w-screen min-h-screen bg-ctp-base">
|
||||||
<Header />
|
<Header theme={theme} />
|
||||||
<main className="flex-1">{children}</main>
|
<main className="flex-1">{children}</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</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