Files
element-call/src/UserMenu.tsx

129 lines
3.0 KiB
TypeScript
Raw Normal View History

/*
Copyright 2022-2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
import { type FC, useMemo, useState } from "react";
import { useLocation } from "react-router-dom";
2022-10-10 09:19:10 -04:00
import { useTranslation } from "react-i18next";
import { Menu, MenuItem } from "@vector-im/compound-web";
import { LinkButton } from "./button";
import { Avatar, Size } from "./Avatar";
2023-09-27 19:06:10 -04:00
import UserIcon from "./icons/User.svg?react";
import SettingsIcon from "./icons/Settings.svg?react";
import LoginIcon from "./icons/Login.svg?react";
import LogoutIcon from "./icons/Logout.svg?react";
import styles from "./UserMenu.module.css";
interface Props {
preventNavigation: boolean;
isAuthenticated: boolean;
isPasswordlessUser: boolean;
userId: string;
displayName: string;
avatarUrl?: string;
onAction: (value: string) => void;
}
2021-12-03 16:42:29 -08:00
export const UserMenu: FC<Props> = ({
preventNavigation,
2021-12-23 14:40:23 -08:00
isAuthenticated,
isPasswordlessUser,
userId,
2021-12-23 14:40:23 -08:00
displayName,
avatarUrl,
onAction,
}) => {
2022-10-10 09:19:10 -04:00
const { t } = useTranslation();
2021-12-09 12:58:30 -08:00
const location = useLocation();
2021-12-03 16:42:29 -08:00
const items = useMemo(() => {
2021-12-09 12:58:30 -08:00
const arr = [];
2021-12-23 14:40:23 -08:00
if (isAuthenticated) {
2021-12-09 12:58:30 -08:00
arr.push({
key: "user",
icon: UserIcon,
2021-12-23 14:40:23 -08:00
label: displayName,
2023-05-03 12:54:06 +01:00
dataTestid: "usermenu_user",
2021-12-09 12:58:30 -08:00
});
arr.push({
key: "settings",
icon: SettingsIcon,
label: t("common.settings"),
});
2021-12-09 12:58:30 -08:00
if (isPasswordlessUser && !preventNavigation) {
2021-12-17 11:51:12 -08:00
arr.push({
key: "login",
2023-11-20 13:22:40 +00:00
label: t("action.sign_in"),
2021-12-17 11:51:12 -08:00
icon: LoginIcon,
2023-05-03 12:54:06 +01:00
dataTestid: "usermenu_login",
2021-12-17 11:51:12 -08:00
});
}
2021-12-17 11:27:33 -08:00
if (!isPasswordlessUser && !preventNavigation) {
2021-12-17 11:51:12 -08:00
arr.push({
key: "logout",
2023-11-20 13:22:40 +00:00
label: t("action.sign_out"),
2021-12-17 11:51:12 -08:00
icon: LogoutIcon,
2023-05-03 12:54:06 +01:00
dataTestid: "usermenu_logout",
2021-12-17 11:51:12 -08:00
});
}
2021-12-03 16:42:29 -08:00
}
2021-12-09 12:58:30 -08:00
return arr;
2022-10-10 09:19:10 -04:00
}, [isAuthenticated, isPasswordlessUser, displayName, preventNavigation, t]);
const [open, setOpen] = useState(false);
2021-12-03 16:42:29 -08:00
2021-12-23 14:40:23 -08:00
if (!isAuthenticated) {
2021-12-17 11:51:12 -08:00
return (
2025-01-06 18:00:20 +01:00
<LinkButton to={{ pathname: "/login" }} state={{ from: location }}>
2023-11-22 20:07:15 +00:00
{t("log_in")}
2021-12-17 11:51:12 -08:00
</LinkButton>
);
}
2021-12-03 16:42:29 -08:00
return (
<Menu
title={t("a11y.user_menu")}
showTitle={false}
align="end"
open={open}
onOpenChange={setOpen}
trigger={
<button
aria-label={t("common.profile")}
2023-05-03 12:54:06 +01:00
className={styles.userButton}
data-testid="usermenu_open"
>
2022-01-21 16:33:43 -08:00
{isAuthenticated && (!isPasswordlessUser || avatarUrl) ? (
2021-12-23 14:40:23 -08:00
<Avatar
id={userId}
name={displayName}
size={Size.SM}
2021-12-23 14:40:23 -08:00
src={avatarUrl}
/>
) : (
<UserIcon />
2021-12-14 22:00:00 -08:00
)}
</button>
}
>
{items.map(({ key, icon: Icon, label, dataTestid }) => (
<MenuItem
key={key}
Icon={Icon}
label={label}
data-test-id={dataTestid}
onSelect={() => onAction(key)}
/>
))}
</Menu>
2021-12-03 16:42:29 -08:00
);
};