diff --git a/source/frontend/src/components/layout/SideNavBar/NavIcon.tsx b/source/frontend/src/components/layout/SideNavBar/NavIcon.tsx index 3a2c9194d5..1e1f919efd 100644 --- a/source/frontend/src/components/layout/SideNavBar/NavIcon.tsx +++ b/source/frontend/src/components/layout/SideNavBar/NavIcon.tsx @@ -10,6 +10,7 @@ import useKeycloakWrapper from '@/hooks/useKeycloakWrapper'; interface INavIconProps { icon: React.ReactElement; text: string; + isNavActive: boolean; showText: boolean; onClick: () => void; roles?: Roles[]; @@ -20,7 +21,15 @@ interface INavIconProps { * Component that creates a nav, with an icon, and optional text. * @param {INavIconProps} param0 */ -export const NavIcon = ({ icon, text, showText, onClick, roles, claims }: INavIconProps) => { +export const NavIcon = ({ + icon, + text, + isNavActive, + showText, + onClick, + roles, + claims, +}: INavIconProps) => { const { hasRole, hasClaim } = useKeycloakWrapper(); const displayIcon = @@ -31,11 +40,15 @@ export const NavIcon = ({ icon, text, showText, onClick, roles, claims }: INavIc onClick={onClick} data-testid={`nav-tooltip-${text.replaceAll(' ', '').toLowerCase()}`} > - + {icon} - {showText && {text}} + {showText && ( + + {text} + + )} ) : null; @@ -46,10 +59,6 @@ const StyledNav = styled(Nav.Item)` margin-bottom: 2rem; fill: ${({ theme }) => theme.css.pimsWhite}; - svg { - min-width: max-content; - } - &:hover { label { color: ${({ theme }) => theme.css.hoverActionColor}; @@ -65,13 +74,24 @@ const StyledLink = styled(Nav.Link)` display: flex; flex-direction: row; align-items: center; + + svg { + fill: white; + min-width: max-content; + } + + &.active { + svg { + fill: ${({ theme }) => theme.css.focusNavbarActionColor}; + } + } `; const StyledLabel = styled.label` margin-left: 1rem; margin-bottom: 0; - font-size: 1.2rem; color: white; + font-size: 1.2rem; word-break: break-word; white-space: break-spaces; transition: width 0.25s; @@ -82,6 +102,9 @@ const StyledLabel = styled.label` &.show { width: 100%; } + &.active { + color: ${({ theme }) => theme.css.focusNavbarActionColor}; + } `; export default NavIcon; diff --git a/source/frontend/src/components/layout/SideNavBar/SideNavbar.tsx b/source/frontend/src/components/layout/SideNavBar/SideNavbar.tsx index f12de6702b..6e731816e8 100644 --- a/source/frontend/src/components/layout/SideNavBar/SideNavbar.tsx +++ b/source/frontend/src/components/layout/SideNavBar/SideNavbar.tsx @@ -1,6 +1,6 @@ import clsx from 'classnames'; -import { useContext, useState } from 'react'; -import { useHistory } from 'react-router-dom'; +import { useContext, useMemo, useState } from 'react'; +import { matchPath, useHistory, useLocation } from 'react-router-dom'; import AcquisitionFileIcon from '@/assets/images/acquisition-icon.svg?react'; import AdminIcon from '@/assets/images/admin-icon.svg?react'; @@ -28,6 +28,97 @@ export const SideNavBar = () => { const [expanded, setExpanded] = useState(false); const { setTrayPage, trayPage } = useContext(SidebarStateContext); const history = useHistory(); + const location = useLocation(); + + const isHomeMap = useMemo( + () => + matchPath(location.pathname, { + path: ['/mapview/sidebar/property/*', '/mapview'], + exact: true, + strict: true, + }), + [location], + ); + + const isProject = useMemo( + () => + matchPath(location.pathname, { + path: ['/project/*', '/mapview/sidebar/project/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isResearch = useMemo( + () => + matchPath(location.pathname, { + path: ['/research/*', '/mapview/sidebar/research/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isAcquisition = useMemo( + () => + matchPath(location.pathname, { + path: ['/acquisition/*', '/mapview/sidebar/acquisition/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isLease = useMemo( + () => + matchPath(location.pathname, { + path: ['/lease/*', '/mapview/sidebar/lease/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isDisposition = useMemo( + () => + matchPath(location.pathname, { + path: ['/disposition/*', '/mapview/sidebar/disposition/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isConsSub = useMemo( + () => + matchPath(location.pathname, { + path: ['/mapview/sidebar/subdivision/*', '/mapview/sidebar/consolidation/*'], + exact: true, + strict: true, + }), + [location], + ); + + const isContacts = useMemo( + () => + matchPath(location.pathname, { + path: '/contact/*', + exact: true, + strict: true, + }), + [location], + ); + + const isAdminTools = useMemo( + () => + matchPath(location.pathname, { + path: '/admin/*', + exact: true, + strict: true, + }), + [location], + ); return ( @@ -38,6 +129,7 @@ export const SideNavBar = () => { icon={} text="Map View" showText={expanded} + isNavActive={isHomeMap != null} /> setTrayPage(SidebarContextType.PROJECT)} @@ -45,36 +137,42 @@ export const SideNavBar = () => { text="Project" showText={expanded} claims={[Claims.PROJECT_VIEW]} + isNavActive={isProject != null} /> setTrayPage(SidebarContextType.RESEARCH)} icon={} text="Research" showText={expanded} + isNavActive={isResearch != null} /> setTrayPage(SidebarContextType.ACQUISITION)} icon={} text="Acquisition" showText={expanded} + isNavActive={isAcquisition != null} /> setTrayPage(SidebarContextType.LEASE)} icon={} text="Leases & Licences" showText={expanded} + isNavActive={isLease != null} /> setTrayPage(SidebarContextType.DISPOSITION)} icon={} text="Disposition" showText={expanded} + isNavActive={isDisposition != null} /> setTrayPage(SidebarContextType.SUBDCONS)} icon={} text="Subdivision & Consolidation" showText={expanded} + isNavActive={isConsSub != null} /> setTrayPage(SidebarContextType.CONTACT)} @@ -82,6 +180,7 @@ export const SideNavBar = () => { text="Contacts" showText={expanded} claims={[Claims.CONTACT_VIEW]} + isNavActive={isContacts != null} /> setTrayPage(SidebarContextType.ADMIN)} @@ -89,6 +188,7 @@ export const SideNavBar = () => { text="Admin Tools" showText={expanded} roles={[Roles.SYSTEM_ADMINISTRATOR]} + isNavActive={isAdminTools != null} /> renders 1`] = ` } .c1 .nav-item svg { - fill: white; min-width: 2.4rem; } @@ -328,12 +327,6 @@ exports[`SideNavbar display and logic > renders 1`] = ` fill: #f2f2f2; } -.c2 svg { - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; -} - .c2:hover label { color: #8ec6ff; } @@ -356,6 +349,17 @@ exports[`SideNavbar display and logic > renders 1`] = ` align-items: center; } +.c3 svg { + fill: white; + min-width: -webkit-max-content; + min-width: -moz-max-content; + min-width: max-content; +} + +.c3.active svg { + fill: #FDB913; +} + @media (max-width:1225px) { .c6 { width: 32rem; diff --git a/source/frontend/src/components/layout/SideNavBar/styles.ts b/source/frontend/src/components/layout/SideNavBar/styles.ts index ae3b76e6df..a01ea22726 100644 --- a/source/frontend/src/components/layout/SideNavBar/styles.ts +++ b/source/frontend/src/components/layout/SideNavBar/styles.ts @@ -32,7 +32,6 @@ export const SideNavBar = styled.div` width: 16rem; } .nav-item svg { - fill: white; min-width: 2.4rem; } .to-bottom {