import { FC, memo, useCallback, useEffect, } from 'react'; import { SidebarContentsType, SidebarMode } from '~/interfaces/ui'; import { useSWRxInAppNotificationStatus } from '~/stores/in-app-notification'; import { useDefaultSocket } from '~/stores/socket-io'; import { useCollapsedContentsOpened, useCurrentSidebarContents, useSidebarMode } from '~/stores/ui'; import styles from './PrimaryItems.module.scss'; /** * @returns String for className to switch the indicator is active or not */ const useIndicator = (sidebarMode: SidebarMode, isSelected: boolean): string => { const { data: isCollapsedContentsOpened } = useCollapsedContentsOpened(); if (sidebarMode === SidebarMode.COLLAPSED && !isCollapsedContentsOpened) { return ''; } return isSelected ? 'active' : ''; }; const NotificationIconWithCountBadge = (): JSX.Element => { const { data: socket } = useDefaultSocket(); const { data: notificationCount, mutate: mutateNotificationCount } = useSWRxInAppNotificationStatus(); useEffect(() => { if (socket != null) { socket.on('notificationUpdated', () => { mutateNotificationCount(); }); // clean up return () => { socket.off('notificationUpdated'); }; } }, [mutateNotificationCount, socket]); return (
{ notificationCount != null && notificationCount > 0 && ( {notificationCount} ) } notifications
); }; type PrimaryItemProps = { contents: SidebarContentsType, label: string, iconName: string, sidebarMode: SidebarMode, onHover?: (contents: SidebarContentsType) => void, } const PrimaryItem: FC = (props: PrimaryItemProps) => { const { contents, label, iconName, sidebarMode, onHover, } = props; const { data: currentContents, mutateAndSave: mutateContents } = useCurrentSidebarContents(); const indicatorClass = useIndicator(sidebarMode, contents === currentContents); const selectThisItem = useCallback(() => { mutateContents(contents, false); }, [contents, mutateContents]); const itemClickedHandler = useCallback(() => { // do nothing ONLY WHEN the collapse mode if (sidebarMode === SidebarMode.COLLAPSED) { return; } selectThisItem(); }, [selectThisItem, sidebarMode]); const mouseEnteredHandler = useCallback(() => { // ignore other than collapsed mode if (sidebarMode !== SidebarMode.COLLAPSED) { return; } selectThisItem(); onHover?.(contents); }, [contents, onHover, selectThisItem, sidebarMode]); const labelForTestId = label.toLowerCase().replace(' ', '-'); return ( ); }; type Props = { onItemHover?: (contents: SidebarContentsType) => void, } export const PrimaryItems = memo((props: Props) => { const { onItemHover } = props; const { data: sidebarMode } = useSidebarMode(); if (sidebarMode == null) { return <>; } return (
); });