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> | |
| ); | |
| } | |
| ); | |