117 lines
4.2 KiB
TypeScript
117 lines
4.2 KiB
TypeScript
import { useState } from "react";
|
|
|
|
import ROUTE_CONSTANTS from "../types/routes.ts";
|
|
import { useLocation } from "react-router-dom";
|
|
import ShoppingListIcon from "./icons/ShoppingListIcon.tsx";
|
|
|
|
export default function Navigation() {
|
|
const [displayHamburgerMenu, setDisplayHamburgerMenu] = useState<boolean>(false);
|
|
|
|
const location = useLocation();
|
|
|
|
return (
|
|
<>
|
|
<nav className="block md:fixed w-full z-20">
|
|
<div
|
|
className="relative w-full px-8 md:px-44 p-4 border-b border-gray-300 shadow-sm shadow-gray-300 bg-white flex justify-between items-center"
|
|
>
|
|
<div>
|
|
<a href={ROUTE_CONSTANTS.Home}>
|
|
<p className="select-none">Potion</p>
|
|
</a>
|
|
</div>
|
|
<div className="hidden md:flex lg:flex items-center gap-8 select-none">
|
|
<NavigationLink name="Home" url={ROUTE_CONSTANTS.Home} current={location.pathname === ROUTE_CONSTANTS.Home} />
|
|
<NavigationLink name="Favorites" url={ROUTE_CONSTANTS.Favorites} current={location.pathname === ROUTE_CONSTANTS.Favorites} />
|
|
<NavigationLink name="Create" url={ROUTE_CONSTANTS.Create} current={location.pathname === ROUTE_CONSTANTS.Create} />
|
|
<NavigationLink name="Profile" url={ROUTE_CONSTANTS.Profile} current={location.pathname === ROUTE_CONSTANTS.Profile} />
|
|
<IconNavigationLink icon={<ShoppingListIcon current={location.pathname === ROUTE_CONSTANTS.ShoppingList} />} url={ROUTE_CONSTANTS.ShoppingList} />
|
|
</div>
|
|
<div className="md:hidden grid place-content-center">
|
|
<button onClick={() => setDisplayHamburgerMenu(!displayHamburgerMenu)} className="p-2">
|
|
<svg
|
|
className={`${displayHamburgerMenu ? "flex" : "hidden"} size-5`}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 320 512"
|
|
>
|
|
<path
|
|
d="M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l256 0c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z"
|
|
></path>
|
|
</svg>
|
|
<svg
|
|
className={`${displayHamburgerMenu ? "hidden" : "flex"} size-5`}
|
|
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
<path
|
|
fill="currentColor"
|
|
d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"
|
|
></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<HamburgerMenu show={displayHamburgerMenu} />
|
|
|
|
</div>
|
|
</nav>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
interface HamburgerMenuProps {
|
|
show: boolean;
|
|
};
|
|
|
|
function HamburgerMenu({ show }: HamburgerMenuProps) {
|
|
return (
|
|
<div className={`${show ? "flex" : "hidden"} w-full flex-col items-center absolute top-[100%] left-0 py-2 bg-white border-b border-gray-300 shadow-sm shadow-gray-300 z-20`}>
|
|
<DropdownLink name="Home" url={ROUTE_CONSTANTS.Home} />
|
|
<DropdownLink name="Favorites" url={ROUTE_CONSTANTS.Favorites} />
|
|
<DropdownLink name="Create" url={ROUTE_CONSTANTS.Create} />
|
|
<DropdownLink name="Profile" url={ROUTE_CONSTANTS.Profile} />
|
|
<DropdownLink name="Shopping List" url={ROUTE_CONSTANTS.ShoppingList} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DropdownLinkProps {
|
|
name: string;
|
|
url: string;
|
|
}
|
|
|
|
function DropdownLink({ name, url }: DropdownLinkProps) {
|
|
return (
|
|
<a className="py-2" href={url}>
|
|
{name}
|
|
</a>
|
|
);
|
|
};
|
|
|
|
interface NavigationLinkProps {
|
|
name: string;
|
|
url: string;
|
|
current: boolean;
|
|
}
|
|
|
|
function NavigationLink({ name, url, current }: NavigationLinkProps) {
|
|
return (
|
|
<a href={url} className={`${current ? "border-blue-500" : "hover:border-blue-400 border-white"} duration-150 text-gray-700 border-b-2 px-1 cursor-pointer`}>
|
|
{name}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
interface IconNavigationLinkProps {
|
|
icon: React.ReactElement;
|
|
url: string;
|
|
}
|
|
|
|
function IconNavigationLink({ icon, url }: IconNavigationLinkProps) {
|
|
return (
|
|
<a href={url} className="px-1 cursor-pointer">
|
|
{icon}
|
|
</a>
|
|
);
|
|
}
|