All files / app/components/Navigation BottomNavigation.tsx

69.69% Statements 23/33
50% Branches 4/8
40% Functions 4/10
77.77% Lines 21/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 941x 1x 1x 1x 1x 1x 1x   1x   1x                 1x                                 1x 1x 1x     1x   1x   1x 1x 1x 1x 1x     1x                                                                                  
import { BottomNavigation as MuiBottomNavigation, BottomNavigationAction, Paper, styled } from "@mui/material";
import { CalendarIcon, ChatBubbleIcon, HomeIcon, PersonIcon, SearchIcon } from "components/Icons";
import { GLOBAL } from "i18n/namespaces";
import { useRouter } from "next/router";
import { useTranslation } from "next-i18next";
import { useMemo } from "react";
import { communitiesRoute, dashboardRoute, eventsRoute, messagesRoute, searchRoute } from "routes";
 
import { BOTTOM_NAV_BASE_HEIGHT } from "./constants";
 
const StyledPaper = styled(Paper)(() => ({
  position: "fixed",
  bottom: "var(--cookie-banner-height, 0px)",
  left: 0,
  right: 0,
  zIndex: 1100,
  boxShadow: "0 -1px 3px rgba(0,0,0,0.1)",
}));
 
const StyledBottomNavigation = styled(MuiBottomNavigation)(({ theme }) => ({
  // the height must account for the safe area (e.g. iOS notch) + MUI base height
  height: `calc(${BOTTOM_NAV_BASE_HEIGHT}px + env(safe-area-inset-bottom, 0px))`,
  paddingBottom: "env(safe-area-inset-bottom, 0px)",
  "& .MuiBottomNavigationAction-root": {
    minWidth: "auto",
    padding: theme.spacing(1, 0),
  },
  "& .MuiBottomNavigationAction-label": {
    fontSize: "10px",
    paddingTop: theme.spacing(0.25),
    "&.Mui-selected": {
      fontSize: "10px",
    },
  },
}));
 
export default function BottomNavigation() {
  const router = useRouter();
  const { t } = useTranslation(GLOBAL);
 
  // Strip locale prefix from pathname to determine current route
  const currentRoute = useMemo(() => {
    // Remove locale prefix (e.g., /en/, /es/, etc.) from pathname
    const pathWithoutLocale = router.pathname.replace(/^\/[a-z]{2}(-[A-Z][a-z]+)?\//, "/");
 
    Iif (pathWithoutLocale.startsWith("/messages")) return messagesRoute;
    Iif (pathWithoutLocale.startsWith("/communities")) return communitiesRoute;
    Iif (pathWithoutLocale.startsWith("/search")) return searchRoute;
    Iif (pathWithoutLocale.startsWith("/events")) return eventsRoute;
    return dashboardRoute;
  }, [router.pathname]);
 
  const handleNavigation = (route: string) => {
    router.push(route);
  };
 
  return (
    <StyledPaper elevation={3}>
      <StyledBottomNavigation value={currentRoute} showLabels>
        <BottomNavigationAction
          label={t("nav.home")}
          value={dashboardRoute}
          icon={<HomeIcon />}
          onClick={() => handleNavigation(dashboardRoute)}
        />
        <BottomNavigationAction
          label={t("nav.messages")}
          value={messagesRoute}
          icon={<ChatBubbleIcon />}
          onClick={() => handleNavigation(messagesRoute)}
        />
        <BottomNavigationAction
          label={t("nav.communities")}
          value={communitiesRoute}
          icon={<PersonIcon />}
          onClick={() => handleNavigation(communitiesRoute)}
        />
        <BottomNavigationAction
          label={t("nav.map_search")}
          value={searchRoute}
          icon={<SearchIcon />}
          onClick={() => handleNavigation(searchRoute)}
        />
        <BottomNavigationAction
          label={t("nav.events")}
          value={eventsRoute}
          icon={<CalendarIcon />}
          onClick={() => handleNavigation(eventsRoute)}
        />
      </StyledBottomNavigation>
    </StyledPaper>
  );
}