All files / src/componentsV2/SideMenu/components/UserSection ProfileMenu.tsx

84% Statements 21/25
84.37% Branches 27/32
60% Functions 6/10
91.3% Lines 21/23

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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                            12x 5x 5x 5x 5x 5x 5x   5x   5x 5x 4x                     5x   5x   5x 1x                         5x 4x     5x                                                                                                       12x   42x       5x                                
import { IconButton, Avatar, Stack, Theme, useMediaQuery } from "@mui/material";
import NiceModal from "@ebay/nice-modal-react";
import { LOGOUT_MODAL, PROFILE_MODAL } from "modals/modal_names";
import GiveAvatar from "@shared/Avatar/GiveAvatar";
import useUserReducer from "@hooks/Reducers/useUserReducer";
import { styled } from "@theme/v2/Provider";
import ContextualMenu from "@shared/ContextualMenu/ContextualMenu";
import { useMemo, useState } from "react";
import { PencilSimpleIcon, SignOutIcon } from "@phosphor-icons/react";
import GiveText from "@shared/Text/GiveText";
import GiveTruncateText from "@shared/Text/GiveTruncateText";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import { useGetFeatureFlagValues } from "FeatureFlags/useGetFeatureFlagValues";
 
const ProfileMenu = ({ open }: { open?: boolean }) => {
  const { img, globalName, email } = useUserReducer();
  const { isMobileView } = useCustomThemeV2();
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const { isNewConversationsEnabled } = useGetFeatureFlagValues();
  const onCloseMenu = () => setAnchorEl(null);
  const onOpenMenu = (event: React.MouseEvent<HTMLElement>) =>
    setAnchorEl(event.currentTarget);
  const openProfileModal = () =>
    NiceModal.show(PROFILE_MODAL, { goBack: onOpenMenu });
  const openLogoutModal = () => NiceModal.show(LOGOUT_MODAL);
  const actions = useMemo(
    () => [
      {
        text: "Edit Profile",
        IconRight: PencilSimpleIcon,
        onClick: openProfileModal,
      },
      { text: "Log out", IconRight: SignOutIcon, onClick: openLogoutModal },
    ],
    [],
  );
 
  const hasName = Boolean(globalName?.firstName || globalName?.lastName);
  const isNameEmpty =
    globalName && !globalName.firstName && !globalName.lastName;
 
  const ProfileDetails = () => (
    <Stack gap="12px" padding="20px 12px" alignItems="center">
      <GiveAvatar imageUrl={img} size="64px" />
      <Stack alignItems="center">
        <GiveText variant="bodyS" color="primary">
          {globalName?.firstName} {globalName?.lastName}
        </GiveText>
        <GiveTruncateText variant="bodyXXS" color="secondary" lineClamp={1}>
          {email}
        </GiveTruncateText>
      </Stack>
    </Stack>
  );
 
  const isMediumUp = useMediaQuery((theme: Theme) =>
    theme.breakpoints.between(768, 1338.95),
  );
 
  return (
    <>
      <AvatarBtn
        size="large"
        version="two"
        onClick={onOpenMenu}
        isNewConversationsEnabled={isNewConversationsEnabled}
        open={open}
      >
        <GiveAvatar size="32px" imageUrl={img} />
        {isNewConversationsEnabled && open && (
          <Stack
            direction="row"
            alignItems="center"
            gap="4px"
            ml={1}
            maxWidth="150px"
          >
            {/* <GiveTruncateText variant="bodyS" color="secondary" lineClamp={1}>
              {globalName?.firstName || globalName?.lastName
                ? `${globalName?.firstName ?? ""} ${
                    globalName?.lastName ?? ""
                  }`.trim()
                : email}
            </GiveTruncateText> */}
            <GiveTruncateText variant="bodyS" color="secondary" lineClamp={1}>
              {hasName
                ? `${globalName.firstName ?? ""} ${
                    globalName.lastName ?? ""
                  }`.trim()
                : isNameEmpty
                ? ""
                : email}
            </GiveTruncateText>
          </Stack>
        )}
      </AvatarBtn>
      <ContextualMenu
        Header={<ProfileDetails />}
        menuWidth={isMediumUp ? 240 : 200}
        handleClose={onCloseMenu}
        anchorEl={anchorEl}
        color={isMobileView ? "primary" : "secondary"}
        texture={isMobileView ? "solid" : "blurred"}
        options={actions}
        anchorOrigin={{ vertical: -25, horizontal: "left" }}
        transformOrigin={{ vertical: "bottom", horizontal: "left" }}
      />
    </>
  );
};
 
const AvatarBtn = styled(IconButton, {
  shouldForwardProp: (prop) =>
    prop !== "isNewConversationsEnabled" && prop !== "open",
})<{
  isNewConversationsEnabled?: boolean;
  open?: boolean;
}>(({ isNewConversationsEnabled, open, theme }) => ({
  border: "4px solid transparent",
  padding: isNewConversationsEnabled && open ? "10px 5px" : 0,
  borderRadius: isNewConversationsEnabled ? "12px" : "50%",
  fontFamily: "inherit",
 
  "&:hover": isNewConversationsEnabled
    ? {
        backgroundColor: theme.palette.surface?.secondary,
      }
    : {
        border: `4px solid ${theme.palette.border?.primary}`,
      },
}));
 
export default ProfileMenu;