2023-02-20 23:50:57 +01:00
|
|
|
import React, { useCallback, useRef, useState } from "react";
|
2020-05-02 03:03:19 +02:00
|
|
|
import { Link } from "react-router-dom";
|
2020-05-02 21:46:41 +02:00
|
|
|
import { User } from "../api/entities/user";
|
2020-05-02 03:03:19 +02:00
|
|
|
import { useAuth } from "../hooks/use-auth";
|
2023-05-19 22:39:10 +02:00
|
|
|
import { useOutsideClick } from "../hooks/use-outside-click";
|
2023-02-20 23:50:57 +01:00
|
|
|
import { CogwheelIcon } from "../icons/Cogwheel";
|
2020-05-02 03:03:19 +02:00
|
|
|
import { SpotifyLogo } from "../icons/Spotify";
|
|
|
|
|
|
|
|
|
|
export const NavBar: React.FC = () => {
|
|
|
|
|
const { user, loginWithSpotifyProps } = useAuth();
|
|
|
|
|
|
|
|
|
|
return (
|
2022-07-24 17:45:29 +02:00
|
|
|
<div className="flex items-center justify-between flex-wrap bg-green-500 dark:bg-gray-800 p-6">
|
2022-06-25 14:23:39 +02:00
|
|
|
<div className="flex items-center shrink-0 text-white mr-6">
|
2020-05-02 03:03:19 +02:00
|
|
|
<span className="font-semibold text-xl tracking-tight">Listory</span>
|
|
|
|
|
</div>
|
2022-06-25 14:23:39 +02:00
|
|
|
<nav className="w-full block grow lg:flex lg:items-center lg:w-auto ">
|
|
|
|
|
<div className="text-sm lg:grow">
|
2020-05-02 03:03:19 +02:00
|
|
|
{user && (
|
2020-05-02 21:46:41 +02:00
|
|
|
<>
|
|
|
|
|
<Link to="/">
|
|
|
|
|
<NavItem>Home</NavItem>
|
|
|
|
|
</Link>
|
|
|
|
|
<Link to="/listens">
|
|
|
|
|
<NavItem>Your Listens</NavItem>
|
|
|
|
|
</Link>
|
2020-05-09 19:22:43 +02:00
|
|
|
<Link to="/reports/listens">
|
|
|
|
|
<NavItem>Listens Report</NavItem>
|
|
|
|
|
</Link>
|
2020-05-31 23:26:06 +02:00
|
|
|
<Link to="/reports/top-artists">
|
|
|
|
|
<NavItem>Top Artists</NavItem>
|
|
|
|
|
</Link>
|
2020-11-15 02:43:23 +01:00
|
|
|
<Link to="/reports/top-albums">
|
|
|
|
|
<NavItem>Top Albums</NavItem>
|
|
|
|
|
</Link>
|
2021-05-22 14:57:28 +02:00
|
|
|
<Link to="/reports/top-tracks">
|
|
|
|
|
<NavItem>Top Tracks</NavItem>
|
|
|
|
|
</Link>
|
2021-10-26 20:09:52 +02:00
|
|
|
<Link to="/reports/top-genres">
|
|
|
|
|
<NavItem>Top Genres</NavItem>
|
|
|
|
|
</Link>
|
2020-05-02 21:46:41 +02:00
|
|
|
</>
|
2020-05-02 03:03:19 +02:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
{!user && (
|
|
|
|
|
<a {...loginWithSpotifyProps()}>
|
|
|
|
|
<NavItem>
|
|
|
|
|
Login with Spotify{" "}
|
|
|
|
|
<SpotifyLogo className="w-6 h-6 ml-2 mb-1 inline fill-current text-white" />
|
|
|
|
|
</NavItem>
|
|
|
|
|
</a>
|
|
|
|
|
)}
|
|
|
|
|
{user && <NavUserInfo user={user} />}
|
|
|
|
|
</div>
|
2021-05-24 18:54:34 +02:00
|
|
|
</nav>
|
|
|
|
|
</div>
|
2020-05-02 03:03:19 +02:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2023-02-20 23:50:57 +01:00
|
|
|
const NavItem: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
|
|
|
return (
|
|
|
|
|
<span className="block mt-4 lg:inline-block lg:mt-0 text-green-200 hover:text-white mr-4">
|
|
|
|
|
{children}
|
|
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-02 03:03:19 +02:00
|
|
|
const NavUserInfo: React.FC<{ user: User }> = ({ user }) => {
|
2023-02-20 23:50:57 +01:00
|
|
|
const [menuOpen, setMenuOpen] = useState<boolean>(false);
|
|
|
|
|
const closeMenu = useCallback(() => setMenuOpen(false), [setMenuOpen]);
|
|
|
|
|
|
|
|
|
|
const wrapperRef = useRef(null);
|
|
|
|
|
useOutsideClick(wrapperRef, closeMenu);
|
|
|
|
|
|
2020-05-02 03:03:19 +02:00
|
|
|
return (
|
2023-02-20 23:50:57 +01:00
|
|
|
<div ref={wrapperRef}>
|
|
|
|
|
<div
|
|
|
|
|
className="flex items-center mr-4 mt-4 lg:mt-0 cursor-pointer"
|
|
|
|
|
onClick={() => setMenuOpen(!menuOpen)}
|
|
|
|
|
>
|
|
|
|
|
<span className="text-green-200 text-sm">{user.displayName}</span>
|
|
|
|
|
{user.photo && (
|
|
|
|
|
<img
|
|
|
|
|
className="w-6 h-6 rounded-full ml-4"
|
|
|
|
|
src={user.photo}
|
|
|
|
|
alt="Profile of logged in user"
|
|
|
|
|
></img>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{menuOpen ? <NavUserInfoMenu closeMenu={closeMenu} /> : null}
|
2020-05-02 03:03:19 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2023-02-20 23:50:57 +01:00
|
|
|
const NavUserInfoMenu: React.FC<{ closeMenu: () => void }> = ({
|
|
|
|
|
closeMenu,
|
|
|
|
|
}) => {
|
2020-05-02 03:03:19 +02:00
|
|
|
return (
|
2023-02-20 23:50:57 +01:00
|
|
|
<div className="relative">
|
|
|
|
|
<div className="drop-down w-48 overflow-hidden bg-green-100 dark:bg-gray-700 text-gray-700 dark:text-green-200 rounded-md shadow absolute top-3 right-3">
|
|
|
|
|
<ul>
|
|
|
|
|
<li className="px-3 py-3 text-sm font-medium flex items-center space-x-2 hover:bg-green-200 hover:text-gray-800 dark:hover:text-white">
|
|
|
|
|
<span>
|
|
|
|
|
<CogwheelIcon className="w-5 h-5 fill-current" />
|
|
|
|
|
</span>
|
|
|
|
|
<Link to="/auth/api-tokens" onClick={closeMenu}>
|
|
|
|
|
API Tokens
|
|
|
|
|
</Link>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2020-05-02 03:03:19 +02:00
|
|
|
);
|
|
|
|
|
};
|