import { menuMessages } from '@app/components/Layout/Sidebar'; import useClickOutside from '@app/hooks/useClickOutside'; import { Permission, useUser } from '@app/hooks/useUser'; import { Transition } from '@headlessui/react'; import { ClockIcon, CogIcon, EllipsisHorizontalIcon, ExclamationTriangleIcon, FilmIcon, SparklesIcon, TvIcon, UsersIcon, } from '@heroicons/react/24/outline'; import { ClockIcon as FilledClockIcon, CogIcon as FilledCogIcon, ExclamationTriangleIcon as FilledExclamationTriangleIcon, FilmIcon as FilledFilmIcon, SparklesIcon as FilledSparklesIcon, TvIcon as FilledTvIcon, UsersIcon as FilledUsersIcon, XMarkIcon, } from '@heroicons/react/24/solid'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { cloneElement, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; interface MenuLink { href: string; svgIcon: JSX.Element; svgIconSelected: JSX.Element; content: React.ReactNode; activeRegExp: RegExp; as?: string; requiredPermission?: Permission | Permission[]; permissionType?: 'and' | 'or'; dataTestId?: string; } const MobileMenu = () => { const ref = useRef(null); const intl = useIntl(); const [isOpen, setIsOpen] = useState(false); const { hasPermission } = useUser(); const router = useRouter(); useClickOutside(ref, () => { setTimeout(() => { if (isOpen) { setIsOpen(false); } }, 150); }); const toggle = () => setIsOpen(!isOpen); const menuLinks: MenuLink[] = [ { href: '/', content: intl.formatMessage(menuMessages.dashboard), svgIcon: , svgIconSelected: , activeRegExp: /^\/(discover\/?)?$/, }, { href: '/discover/movies', content: intl.formatMessage(menuMessages.browsemovies), svgIcon: , svgIconSelected: , activeRegExp: /^\/discover\/movies$/, }, { href: '/discover/tv', content: intl.formatMessage(menuMessages.browsetv), svgIcon: , svgIconSelected: , activeRegExp: /^\/discover\/tv$/, }, { href: '/requests', content: intl.formatMessage(menuMessages.requests), svgIcon: , svgIconSelected: , activeRegExp: /^\/requests/, }, { href: '/issues', content: intl.formatMessage(menuMessages.issues), svgIcon: , svgIconSelected: , activeRegExp: /^\/issues/, requiredPermission: [ Permission.MANAGE_ISSUES, Permission.CREATE_ISSUES, Permission.VIEW_ISSUES, ], permissionType: 'or', }, { href: '/users', content: intl.formatMessage(menuMessages.users), svgIcon: , svgIconSelected: , activeRegExp: /^\/users/, requiredPermission: Permission.MANAGE_USERS, dataTestId: 'sidebar-menu-users', }, { href: '/settings', content: intl.formatMessage(menuMessages.settings), svgIcon: , svgIconSelected: , activeRegExp: /^\/settings/, requiredPermission: Permission.ADMIN, dataTestId: 'sidebar-menu-settings', }, ]; const filteredLinks = menuLinks.filter( (link) => !link.requiredPermission || hasPermission(link.requiredPermission, { type: link.permissionType ?? 'and', }) ); return (
{filteredLinks.map((link) => { const isActive = router.pathname.match(link.activeRegExp); return ( { if (e.key === 'Enter') { setIsOpen(false); } }} onClick={() => setIsOpen(false)} role="button" tabIndex={0} > {cloneElement(isActive ? link.svgIconSelected : link.svgIcon, { className: 'h-5 w-5', })} {link.content} ); })}
{filteredLinks .slice(0, filteredLinks.length === 5 ? 5 : 4) .map((link) => { const isActive = router.pathname.match(link.activeRegExp) && !isOpen; return ( {cloneElement( isActive ? link.svgIconSelected : link.svgIcon, { className: 'h-6 w-6', } )} ); })} {filteredLinks.length > 4 && filteredLinks.length !== 5 && ( )}
); }; export default MobileMenu;