generated from nhcarrigan/template
85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
|
"use client";
|
||
|
import React, { useState, useEffect } from "react";
|
||
|
import Image from "next/image";
|
||
|
import { Rule } from "./rule";
|
||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||
|
import {
|
||
|
faBars,
|
||
|
faTimes,
|
||
|
faSun,
|
||
|
faMoon,
|
||
|
} from "@fortawesome/free-solid-svg-icons";
|
||
|
import { NavItems } from "@/config/NavItems";
|
||
|
import { usePathname } from "next/navigation";
|
||
|
|
||
|
const Navigation = (): JSX.Element => {
|
||
|
const [isOpen, setIsOpen] = useState(false);
|
||
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
||
|
|
||
|
useEffect(() => {
|
||
|
const savedTheme = localStorage.getItem("theme");
|
||
|
const prefersDark = window.matchMedia(
|
||
|
"(prefers-color-scheme: dark)",
|
||
|
).matches;
|
||
|
const isDark = savedTheme === "dark" || (!savedTheme && prefersDark);
|
||
|
document.documentElement.classList.toggle("dark", isDark);
|
||
|
setIsDarkMode(isDark);
|
||
|
}, []);
|
||
|
|
||
|
const toggleMenu = () => {
|
||
|
setIsOpen(!isOpen);
|
||
|
};
|
||
|
|
||
|
const toggleDarkMode = () => {
|
||
|
document.documentElement.classList.toggle("dark", !isDarkMode);
|
||
|
localStorage.setItem("theme", !isDarkMode ? "dark" : "light");
|
||
|
setIsDarkMode(!isDarkMode);
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<div className="fixed w-full top-0 z-50">
|
||
|
<nav className="w-full flex justify-between items-center h-14 px-4 bg-[--background] text-[--foreground]">
|
||
|
<a href="/">
|
||
|
<Image
|
||
|
src="https://cdn.nhcarrigan.com/logo.png"
|
||
|
alt="nhcarrigan's logo"
|
||
|
width={50}
|
||
|
height={50}
|
||
|
/>
|
||
|
</a>
|
||
|
<div className="flex items-center">
|
||
|
<button onClick={toggleDarkMode} className="mr-4">
|
||
|
<FontAwesomeIcon icon={isDarkMode ? faSun : faMoon} size="lg" />
|
||
|
</button>
|
||
|
<button onClick={toggleMenu}>
|
||
|
<FontAwesomeIcon icon={isOpen ? faTimes : faBars} size="2x" />
|
||
|
</button>
|
||
|
</div>
|
||
|
</nav>
|
||
|
{isOpen && (
|
||
|
<div className="bg-[--background] text-[--foreground]">
|
||
|
{NavItems.map((item, index) => (
|
||
|
<a
|
||
|
key={item.href}
|
||
|
href={item.href}
|
||
|
className="block py-2 px-4 text-2xl hover:bg-[--foreground] hover:text-[--background]"
|
||
|
onClick={() => setIsOpen(false)}
|
||
|
>
|
||
|
{index % 2 ? "🩷" : "🩵"} {item.text}
|
||
|
</a>
|
||
|
))}
|
||
|
</div>
|
||
|
)}
|
||
|
<Rule />
|
||
|
</div>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export function ClientNavigation() {
|
||
|
const pathname = usePathname();
|
||
|
const isRootPath = pathname === "/";
|
||
|
|
||
|
if (isRootPath) return null;
|
||
|
return <Navigation />;
|
||
|
}
|