Spaces:
Running
Running
import { forwardRef, useEffect, useRef, useState } from "react"; | |
import { useClickAway } from "react-use"; | |
import classNames from "classnames"; | |
import Image from "next/image"; | |
import LinkComp from "next/link"; | |
import { | |
ChevronDownIcon, | |
CheckCircleIcon, | |
ArrowCircleLeftIcon, | |
XIcon, | |
ThumbUpIcon, | |
} from "@heroicons/react/solid"; | |
import { login, useUser } from "utils/auth"; | |
import { Link } from "./link"; | |
import { UserMenu } from "./user-menu"; | |
import { FormattedMessage } from "react-intl"; | |
const LINKS = [ | |
{ | |
name: "navigation.menus.iconsEditor", | |
link: "/icons-editor", | |
icon: () => <ThumbUpIcon className="w-6 text-dark-300" />, | |
}, | |
{ | |
name: "navigation.menus.badgeEditor", | |
link: "/badges-editor", | |
icon: () => <ThumbUpIcon className="w-6 text-dark-300" />, | |
}, | |
{ | |
name: "navigation.menus.supportServer", | |
link: "https://discord.gg/RX3QnVY4UA", | |
icon: () => <CheckCircleIcon className="w-6 text-dark-300" />, | |
}, | |
]; | |
export const Navigation = () => { | |
const { user } = useUser(); | |
const [open, setOpen] = useState(false); | |
const ref = useRef<any>(null); | |
useClickAway(ref, () => setOpen(false)); | |
return ( | |
<div className="w-full absolute left-0 top-0 z-30"> | |
<div className="container pt-6 lg:pt-8 pb-6 px-6 lg:px-0 lg:pb-14 grid grid-cols-2 lg:grid-cols-2 mx-auto"> | |
<LinkComp | |
href="/" | |
className="flex items-center font-title text-white font-extrabold text-2xl" | |
> | |
<Image | |
src="/logo.svg" | |
width={24} | |
height={24} | |
className="mr-2" | |
alt="logo" | |
/> | |
<span className="inline-block">discotools.xyz</span> | |
</LinkComp> | |
{/* <div className="hidden lg:flex items-end justify-center gap-6"></div> */} | |
<div className="hidden lg:flex justify-end gap-7 items-center"> | |
{LINKS.map((link, i) => ( | |
<Link key={i} {...link} /> | |
))} | |
{/* {user?.id ? ( | |
<UserMenu> | |
<div className="flex items-center gap-2"> | |
<img | |
src={ | |
user.avatar | |
? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png` | |
: `https://cdn.discordapp.com/embed/avatars/${ | |
user.discriminator % 5 | |
}.png` | |
} | |
className="w-12 h-12 rounded-full border-2 border-white" | |
/> | |
<ChevronDownIcon className="text-white w-6" /> | |
</div> | |
</UserMenu> | |
) : ( | |
<button | |
className="bg-white rounded-lg px-5 py-3 text-blue uppercase text-sm font-bold transition-duration hover:scale-110 duration-200" | |
onClick={login} | |
> | |
<FormattedMessage id="navigation.menus.logIn" /> | |
</button> | |
)} */} | |
</div> | |
<div | |
className="flex justify-end lg:hidden" | |
onClick={() => setOpen(true)} | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
fill="none" | |
viewBox="0 0 24 24" | |
strokeWidth={1.5} | |
stroke="currentColor" | |
className="w-8 text-white" | |
> | |
<path | |
strokeLinecap="round" | |
strokeLinejoin="round" | |
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" | |
/> | |
</svg> | |
</div> | |
<NavigationMobile | |
ref={ref} | |
open={open} | |
onClose={() => setOpen(false)} | |
/> | |
</div> | |
</div> | |
); | |
}; | |
export const NavigationMobile = forwardRef( | |
( | |
{ | |
open, | |
onClose, | |
}: { | |
open: boolean; | |
onClose: () => void; | |
}, | |
ref | |
) => { | |
const { user, logout } = useUser(); | |
return ( | |
<div | |
ref={ref as any} | |
className={classNames( | |
"lg:hidden bg-white w-[calc(100%-64px)] z-30 shadow-xl h-screen fixed top-0 right-0 transition-all duration-200 transform p-6 flex flex-col justify-between", | |
{ | |
"opacity-0 pointer-events-none translate-x-full": !open, | |
} | |
)} | |
> | |
<div> | |
<div className="flex items-center justify-between"> | |
<XIcon className="w-6 text-dark-200" onClick={onClose} /> | |
{user?.id ? ( | |
<div className="flex items-center justify-end gap-2"> | |
<p className="text-dark-600 font-semibold tracking-wider mr-2 text-lg"> | |
{user.username}#{user.discriminator} | |
</p> | |
<img | |
src={ | |
user.avatar | |
? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png` | |
: `https://cdn.discordapp.com/embed/avatars/${ | |
user.discriminator % 5 | |
}.png` | |
} | |
className="w-10 h-10 rounded-full border-2 border-white ring-1 ring-blue" | |
/> | |
</div> | |
) : ( | |
<button | |
className="bg-blue rounded-lg px-5 py-2.5 text-white uppercase text-sm font-bold transition-duration hover:scale-110 duration-200 block ml-auto" | |
onClick={login} | |
> | |
<FormattedMessage id="navigation.menus.logIn" /> | |
</button> | |
)} | |
</div> | |
<div className="mt-6"> | |
<p className="text-dark-200 font-semibold uppercase text-sm tracking-wider"> | |
<FormattedMessage id="navigation.menus.title" /> | |
</p> | |
<ul className="mt-4 grid grid-cols-1 gap-5"> | |
{LINKS.map((link: any) => { | |
const Component = link.comingSoong ? "div" : "a"; | |
return ( | |
<Component | |
key={link.name} | |
href={!link.comingSoon ? link.link ?? link.url : "#"} | |
target={link.url ? "_blank" : ""} | |
> | |
<li | |
className={classNames( | |
"flex items-center justify-start gap-3 text-dark-600 font-semibold text-lg tracking-wide", | |
{ | |
"text-opacity-50 cursor-not-allowed": link.comingSoon, | |
} | |
)} | |
onClick={onClose} | |
> | |
{link.icon()} | |
<FormattedMessage id={link.name} /> | |
{link.comingSoon && ( | |
<span className="text-xs bg-yellow bg-opacity-30 text-yellow rounded-full px-2 py-1 text-opacity-100"> | |
<FormattedMessage id="badge.comingSoon" /> | |
</span> | |
)} | |
</li> | |
</Component> | |
); | |
})} | |
{user?.id && ( | |
<li | |
className="flex items-center justify-start gap-3 text-[#f02727] font-semibold text-lg tracking-wide" | |
onClick={logout} | |
> | |
<ArrowCircleLeftIcon className="w-6 text-[#f02727]" /> | |
<FormattedMessage id="navigation.menus.logOut" /> | |
</li> | |
)} | |
</ul> | |
</div> | |
</div> | |
<div className="flex items-center font-title text-dark-100 font-semibold text-base"> | |
<span className="font-title">discotools.xyz</span> | |
</div> | |
</div> | |
); | |
} | |
); | |