All files / src/features/Drawer SwitchAccountsMenu.tsx

46.15% Statements 12/26
10% Branches 1/10
20% Functions 2/10
52.17% Lines 12/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                                                                21x           71x 71x 71x   71x   71x       71x                   71x 37x   37x           37x                                                 71x                                              
import React, { useMemo, useState } from "react";
// utils
import { capitalize, sortBy } from "lodash";
import { toast } from "react-toastify";
// components
// TODO: the toast to be replaced with a rebranded one
import { ToastMessage } from "@common/Toast/ToastMessage";
import { TParsedAccount } from "@pages/Login/modals/hooks/useAccountSelectionModal";
// assets
// TODO: the toast icon to be replaced by a phosphor icon
import { SwitchAccountToastIcon } from "@assets/icons/SwitchAccountToastIcon";
// redux
import { useAppSelector } from "@redux/hooks";
import { selectSelectedAccount } from "@redux/slices/auth/accounts";
import { addSizeToImage } from "@components/UploadAvatar/UploadAvatar";
import ContextualMenu from "@shared/ContextualMenu/ContextualMenu";
import { ContextualMenuOptionProps } from "@shared/ContextualMenu/ContextualMenu.types";
import { CheckIcon } from "@phosphor-icons/react";
import { useAppTheme } from "@theme/v2/Provider";
import GiveThumbnail from "@shared/Thumbnail/GiveThumbnail";
import { showMessage } from "@common/Toast";
 
interface Props {
  accountList: TParsedAccount[];
 
  chooseAccount(index: number): boolean | void;
 
  drawerOpen?: boolean;
  anchorEl: HTMLElement | null;
  onCloseMenu: () => void;
}
 
const SwitchAccountsMenu = ({
  accountList,
  chooseAccount,
  anchorEl,
  onCloseMenu,
}: Props) => {
  const selectedAccount = useAppSelector(selectSelectedAccount);
  const [searchAccount, setSearchAccount] = useState("");
  const { palette } = useAppTheme();
 
  const handleChange = (val: string) => setSearchAccount(val);
 
  const clearSearch = () => {
    setSearchAccount("");
  };
 
  const onChangeAccount = React.useCallback(
    (index: number, accountName: string) => {
      const accName = accountName?.replace(/^./, accountName[0].toUpperCase());
      const hadChanged = chooseAccount(index);
      hadChanged &&
        showMessage("Switch", "", true, `Switched to ${accName}`, 2000);
    },
    [chooseAccount],
  );
 
  const accountMenuOptions = useMemo(() => {
    const sortedAccountList = sortBy(accountList, "name");
 
    const searchedAccounts = sortedAccountList?.filter((account) => {
      if (!searchAccount) return true;
 
      return account.name.toLowerCase().includes(searchAccount.toLowerCase());
    });
 
    return searchedAccounts?.map((account) => {
      const selected = account.id === selectedAccount?.id;
 
      return {
        text: account?.name,
        description: capitalize(account?.merchType),
        Image: (
          <GiveThumbnail
            imageUrl={addSizeToImage(account.img, "thumb")}
            size={"small"}
            type={account?.merchType || "merchant"}
          />
        ),
        onClick: () => {
          const switchIndex = accountList.findIndex((a) => a.id === account.id);
          onChangeAccount(switchIndex, account.merchType);
        },
        ...(selected && {
          IconRight: CheckIcon,
          onClick: () => null,
        }),
      };
    }) as ContextualMenuOptionProps[];
  }, [accountList, searchAccount, selectedAccount]);
 
  return (
    <ContextualMenu
      anchorEl={anchorEl}
      options={accountMenuOptions}
      handleClose={onCloseMenu}
      color="secondary"
      texture="blurred"
      emptySection="empty-search"
      onCloseEmptyState={clearSearch}
      searchBarProps={
        accountList?.length > 5
          ? {
              value: searchAccount,
              handleChange: handleChange,
            }
          : undefined
      }
      menuWidth={270}
    />
  );
};
 
export default SwitchAccountsMenu;