SignInAvatar.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { useIntl } from "react-intl";
  2. import { useState } from "react";
  3. import { _Link, useNavigate } from "react-router";
  4. import { Divider, Menu, Typography } from "antd";
  5. import { Avatar } from "antd";
  6. import { Popover } from "antd";
  7. import {
  8. UserOutlined,
  9. HomeOutlined,
  10. LogoutOutlined,
  11. SettingOutlined,
  12. } from "@ant-design/icons";
  13. import { useAppSelector } from "../../hooks";
  14. import {
  15. currentUser as _currentUser,
  16. studioList,
  17. } from "../../reducers/current-user";
  18. import type { TooltipPlacement } from "antd/lib/tooltip"
  19. import SettingModal from "./setting/SettingModal";
  20. import { AdminIcon } from "../../assets/icon";
  21. import User from "./User";
  22. import { fullUrl } from "../../utils";
  23. import Studio from "./Studio";
  24. import LoginButton from "./LoginButton";
  25. const { Title, Paragraph, Text } = Typography;
  26. interface IWidget {
  27. placement?: TooltipPlacement;
  28. style?: React.CSSProperties;
  29. }
  30. const SignInAvatarWidget = ({ style, placement = "bottomRight" }: IWidget) => {
  31. const intl = useIntl();
  32. const navigate = useNavigate();
  33. const [settingOpen, setSettingOpen] = useState(false);
  34. const user = useAppSelector(_currentUser);
  35. const studios = useAppSelector(studioList);
  36. console.debug("user", user);
  37. const canManage =
  38. user?.roles?.includes("root") || user?.roles?.includes("administrator");
  39. if (typeof user === "undefined") {
  40. return <LoginButton />;
  41. } else {
  42. const welcome = (
  43. <Paragraph>
  44. <Title level={3} style={{ fontSize: 22 }}>
  45. {user.nickName}
  46. </Title>
  47. <Text type="secondary">账户名 {user.realName}</Text>
  48. <Paragraph style={{ textAlign: "right", paddingTop: 30 }}>
  49. {intl.formatMessage({
  50. id: "buttons.welcome",
  51. })}
  52. </Paragraph>
  53. </Paragraph>
  54. );
  55. let userList = [
  56. {
  57. key: user.realName,
  58. label: <User {...user} />,
  59. },
  60. ];
  61. const studioList = studios?.map((item, _id) => {
  62. return {
  63. key: item.realName ?? "",
  64. label: <Studio data={item} />,
  65. };
  66. });
  67. if (studioList) {
  68. userList = [...userList, ...studioList];
  69. }
  70. return (
  71. <>
  72. <Popover
  73. content={
  74. <div style={{ width: 350 }}>
  75. <>{welcome}</>
  76. <Divider></Divider>
  77. <div style={{ maxHeight: 500, overflowY: "auto" }}>
  78. <Menu
  79. style={{ width: "100%" }}
  80. mode={"inline"}
  81. selectable={false}
  82. items={[
  83. {
  84. key: "account",
  85. label: "选择账户",
  86. icon: <UserOutlined />,
  87. children: userList,
  88. },
  89. {
  90. key: "setting",
  91. label: "设置",
  92. icon: <SettingOutlined />,
  93. },
  94. {
  95. key: "admin",
  96. label: intl.formatMessage({
  97. id: "buttons.admin",
  98. }),
  99. icon: <AdminIcon />,
  100. disabled: !canManage,
  101. },
  102. {
  103. key: "blog",
  104. label: intl.formatMessage({
  105. id: "columns.library.blog.label",
  106. }),
  107. icon: <HomeOutlined key="home" />,
  108. },
  109. {
  110. key: "logout",
  111. label: intl.formatMessage({
  112. id: "buttons.sign-out",
  113. }),
  114. icon: <LogoutOutlined />,
  115. },
  116. ].filter((value) => !value.disabled)}
  117. onClick={(info) => {
  118. switch (info.key) {
  119. case "setting":
  120. setSettingOpen(true);
  121. break;
  122. case "admin":
  123. window.open(fullUrl(`/admin`), "_blank");
  124. break;
  125. case "blog":
  126. const blog = `/blog/${user.realName}/overview`;
  127. window.open(fullUrl(blog), "_blank");
  128. break;
  129. case "logout":
  130. sessionStorage.removeItem("token");
  131. localStorage.removeItem("token");
  132. navigate("/anonymous/users/sign-in");
  133. break;
  134. }
  135. }}
  136. />
  137. </div>
  138. </div>
  139. }
  140. placement={placement}
  141. >
  142. <span style={style}>
  143. <Avatar
  144. style={{ backgroundColor: "#87d068" }}
  145. icon={<UserOutlined />}
  146. src={user?.avatar}
  147. size="small"
  148. >
  149. {user.nickName?.slice(0, 2)}
  150. </Avatar>
  151. </span>
  152. </Popover>
  153. <SettingModal
  154. open={settingOpen}
  155. onClose={() => setSettingOpen(false)}
  156. />
  157. </>
  158. );
  159. }
  160. };
  161. export default SignInAvatarWidget;