import { ClockIcon, CogIcon, ExclamationIcon, SparklesIcon, UsersIcon, XIcon, } from '@heroicons/react/outline'; import Link from 'next/link'; import { useRouter } from 'next/router'; import type { ReactNode } from 'react'; import React, { useRef } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import useClickOutside from '../../../hooks/useClickOutside'; import { Permission, useUser } from '../../../hooks/useUser'; import Transition from '../../Transition'; import VersionStatus from '../VersionStatus'; const messages = defineMessages({ dashboard: 'Discover', requests: 'Requests', issues: 'Issues', users: 'Users', settings: 'Settings', }); interface SidebarProps { open?: boolean; setClosed: () => void; } interface SidebarLinkProps { href: string; svgIcon: ReactNode; messagesKey: keyof typeof messages; activeRegExp: RegExp; as?: string; requiredPermission?: Permission | Permission[]; permissionType?: 'and' | 'or'; dataTestId?: string; } const SidebarLinks: SidebarLinkProps[] = [ { href: '/', messagesKey: 'dashboard', svgIcon: , activeRegExp: /^\/(discover\/?(movies|tv)?)?$/, }, { href: '/requests', messagesKey: 'requests', svgIcon: , activeRegExp: /^\/requests/, }, { href: '/issues', messagesKey: 'issues', svgIcon: ( ), activeRegExp: /^\/issues/, requiredPermission: [ Permission.MANAGE_ISSUES, Permission.CREATE_ISSUES, Permission.VIEW_ISSUES, ], permissionType: 'or', }, { href: '/users', messagesKey: 'users', svgIcon: , activeRegExp: /^\/users/, requiredPermission: Permission.MANAGE_USERS, dataTestId: 'sidebar-menu-users', }, { href: '/settings', messagesKey: 'settings', svgIcon: , activeRegExp: /^\/settings/, requiredPermission: Permission.MANAGE_SETTINGS, }, ]; const Sidebar: React.FC = ({ open, setClosed }) => { const navRef = useRef(null); const router = useRouter(); const intl = useIntl(); const { hasPermission } = useUser(); useClickOutside(navRef, () => setClosed()); return ( <> <> setClosed()} > {SidebarLinks.filter((link) => link.requiredPermission ? hasPermission(link.requiredPermission, { type: link.permissionType ?? 'and', }) : true ).map((sidebarLink) => { return ( setClosed()} onKeyDown={(e) => { if (e.key === 'Enter') { setClosed(); } }} role="button" tabIndex={0} className={`flex items-center rounded-md px-2 py-2 text-base font-medium leading-6 text-white transition duration-150 ease-in-out focus:outline-none ${ router.pathname.match( sidebarLink.activeRegExp ) ? 'bg-gradient-to-br from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500' : 'hover:bg-gray-700 focus:bg-gray-700' } `} data-testid={`${sidebarLink.dataTestId}-mobile`} > {sidebarLink.svgIcon} {intl.formatMessage( messages[sidebarLink.messagesKey] )} ); })} {hasPermission(Permission.ADMIN) && ( setClosed()} /> )} {/* */} > {SidebarLinks.filter((link) => link.requiredPermission ? hasPermission(link.requiredPermission, { type: link.permissionType ?? 'and', }) : true ).map((sidebarLink) => { return ( {sidebarLink.svgIcon} {intl.formatMessage(messages[sidebarLink.messagesKey])} ); })} {hasPermission(Permission.ADMIN) && ( )} > ); }; export default Sidebar;