@blocklet/ui-react 2.12.8 → 2.12.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/lib/@types/index.d.ts +34 -0
  2. package/lib/@types/index.js +16 -0
  3. package/lib/@types/shims.d.ts +1 -0
  4. package/lib/UserCenter/components/config-profile.js +23 -1
  5. package/lib/UserCenter/components/editable-field.d.ts +22 -0
  6. package/lib/UserCenter/components/editable-field.js +159 -0
  7. package/lib/UserCenter/components/nft.d.ts +4 -0
  8. package/lib/UserCenter/components/nft.js +93 -0
  9. package/lib/UserCenter/components/settings.js +32 -15
  10. package/lib/UserCenter/components/status-selector/duration-menu.d.ts +9 -0
  11. package/lib/UserCenter/components/status-selector/duration-menu.js +75 -0
  12. package/lib/UserCenter/components/status-selector/index.d.ts +9 -0
  13. package/lib/UserCenter/components/status-selector/index.js +39 -0
  14. package/lib/UserCenter/components/status-selector/menu-item.d.ts +24 -0
  15. package/lib/UserCenter/components/status-selector/menu-item.js +24 -0
  16. package/lib/UserCenter/components/user-center.js +119 -122
  17. package/lib/UserCenter/components/user-info/clock.d.ts +4 -0
  18. package/lib/UserCenter/components/user-info/clock.js +23 -0
  19. package/lib/UserCenter/components/user-info/link-preview-input.d.ts +5 -0
  20. package/lib/UserCenter/components/user-info/link-preview-input.js +181 -0
  21. package/lib/UserCenter/components/user-info/metadata.d.ts +7 -0
  22. package/lib/UserCenter/components/user-info/metadata.js +458 -0
  23. package/lib/UserCenter/components/user-info/switch-role.js +2 -3
  24. package/lib/UserCenter/components/user-info/user-basic-info.d.ts +2 -0
  25. package/lib/UserCenter/components/user-info/user-basic-info.js +159 -90
  26. package/lib/UserCenter/components/user-info/user-info.js +2 -16
  27. package/lib/UserCenter/components/user-info/user-status.d.ts +8 -0
  28. package/lib/UserCenter/components/user-info/user-status.js +153 -0
  29. package/lib/UserCenter/components/user-info/utils.d.ts +19 -0
  30. package/lib/UserCenter/components/user-info/utils.js +86 -0
  31. package/lib/UserCenter/libs/locales.d.ts +65 -0
  32. package/lib/UserCenter/libs/locales.js +67 -2
  33. package/lib/UserSessions/components/user-sessions.js +48 -14
  34. package/package.json +8 -5
  35. package/src/@types/index.ts +39 -0
  36. package/src/@types/shims.d.ts +1 -0
  37. package/src/UserCenter/components/config-profile.tsx +20 -1
  38. package/src/UserCenter/components/editable-field.tsx +180 -0
  39. package/src/UserCenter/components/nft.tsx +122 -0
  40. package/src/UserCenter/components/settings.tsx +16 -4
  41. package/src/UserCenter/components/status-selector/duration-menu.tsx +87 -0
  42. package/src/UserCenter/components/status-selector/index.tsx +52 -0
  43. package/src/UserCenter/components/status-selector/menu-item.tsx +52 -0
  44. package/src/UserCenter/components/user-center.tsx +104 -103
  45. package/src/UserCenter/components/user-info/clock.tsx +29 -0
  46. package/src/UserCenter/components/user-info/link-preview-input.tsx +227 -0
  47. package/src/UserCenter/components/user-info/metadata.tsx +465 -0
  48. package/src/UserCenter/components/user-info/switch-role.tsx +3 -3
  49. package/src/UserCenter/components/user-info/user-basic-info.tsx +150 -87
  50. package/src/UserCenter/components/user-info/user-info.tsx +6 -16
  51. package/src/UserCenter/components/user-info/user-status.tsx +182 -0
  52. package/src/UserCenter/components/user-info/utils.ts +114 -0
  53. package/src/UserCenter/libs/locales.ts +65 -0
  54. package/src/UserSessions/components/user-sessions.tsx +68 -18
@@ -38,6 +38,39 @@ export type NFTAccount = {
38
38
  firstLoginAt: string;
39
39
  };
40
40
  export type ConnectedAccount = OAuthAccount | WalletAccount | NFTAccount;
41
+ export type UserMetadataLink = {
42
+ url: string;
43
+ favicon?: string;
44
+ };
45
+ export declare enum DurationEnum {
46
+ ThirtyMinutes = "30_minutes",
47
+ OneHour = "1_hour",
48
+ FourHours = "4_hours",
49
+ Today = "today",
50
+ ThisWeek = "this_week"
51
+ }
52
+ export declare enum StatusEnum {
53
+ Meeting = "meeting",
54
+ Community = "community",
55
+ Holiday = "holiday",
56
+ OffSick = "off_sick",
57
+ WorkingRemotely = "working_remotely"
58
+ }
59
+ export type UserMetadata = {
60
+ bio?: string;
61
+ location?: string;
62
+ timezone?: string;
63
+ joinedAt?: string;
64
+ status?: {
65
+ value: string;
66
+ duration?: DurationEnum;
67
+ dateRange?: Date[];
68
+ };
69
+ links?: UserMetadataLink[];
70
+ cover?: string;
71
+ email?: string;
72
+ phone?: string;
73
+ };
41
74
  export type User = UserPublicInfo & {
42
75
  role: string;
43
76
  email?: string;
@@ -55,6 +88,7 @@ export type User = UserPublicInfo & {
55
88
  inviter?: string;
56
89
  emailVerified?: boolean;
57
90
  phoneVerified?: boolean;
91
+ metadata?: UserMetadata;
58
92
  };
59
93
  export type UserCenterTab = {
60
94
  value: string;
@@ -0,0 +1,16 @@
1
+ export var DurationEnum = /* @__PURE__ */ ((DurationEnum2) => {
2
+ DurationEnum2["ThirtyMinutes"] = "30_minutes";
3
+ DurationEnum2["OneHour"] = "1_hour";
4
+ DurationEnum2["FourHours"] = "4_hours";
5
+ DurationEnum2["Today"] = "today";
6
+ DurationEnum2["ThisWeek"] = "this_week";
7
+ return DurationEnum2;
8
+ })(DurationEnum || {});
9
+ export var StatusEnum = /* @__PURE__ */ ((StatusEnum2) => {
10
+ StatusEnum2["Meeting"] = "meeting";
11
+ StatusEnum2["Community"] = "community";
12
+ StatusEnum2["Holiday"] = "holiday";
13
+ StatusEnum2["OffSick"] = "off_sick";
14
+ StatusEnum2["WorkingRemotely"] = "working_remotely";
15
+ return StatusEnum2;
16
+ })(StatusEnum || {});
@@ -6,6 +6,7 @@ declare module '@arcblock/ux/lib/ErrorBoundary';
6
6
 
7
7
  declare module '@arcblock/did-connect/*';
8
8
  declare module '@arcblock/did-connect/lib/Session';
9
+ declare module '@abtnode/constant';
9
10
 
10
11
  declare module 'is-url';
11
12
 
@@ -4,6 +4,8 @@ import { useMemoizedFn, useReactive } from "ahooks";
4
4
  import { translate } from "@arcblock/ux/lib/Locale/util";
5
5
  import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
6
6
  import Toast from "@arcblock/ux/lib/Toast";
7
+ import { temp as colors } from "@arcblock/ux/lib/Colors";
8
+ import ArrowDownwardIcon from "@arcblock/icons/lib/ArrowDown";
7
9
  import { translations } from "../libs/locales.js";
8
10
  import { client } from "../../libs/client.js";
9
11
  import { formatAxiosError } from "../libs/utils.js";
@@ -61,7 +63,27 @@ export default function ConfigProfile({ user, onSave }) {
61
63
  }
62
64
  }
63
65
  ),
64
- /* @__PURE__ */ jsx(Select, { value: currentState.locale, onChange: handleChange, size: "small", sx: { minWidth: 300 }, children: (window.blocklet.languages || languages).map((x) => /* @__PURE__ */ jsx(MenuItem, { value: x.code, children: x.name }, x.code)) })
66
+ /* @__PURE__ */ jsx(
67
+ Select,
68
+ {
69
+ value: currentState.locale,
70
+ onChange: handleChange,
71
+ size: "small",
72
+ IconComponent: (props) => /* @__PURE__ */ jsx(ArrowDownwardIcon, { ...props, width: 20, height: 20 }),
73
+ sx: {
74
+ minWidth: 300,
75
+ "&:hover": {
76
+ "fieldset.MuiOutlinedInput-notchedOutline": {
77
+ borderColor: colors.dividerColor
78
+ }
79
+ },
80
+ fieldset: {
81
+ borderColor: colors.dividerColor
82
+ }
83
+ },
84
+ children: (window.blocklet.languages || languages).map((x) => /* @__PURE__ */ jsx(MenuItem, { value: x.code, children: x.name }, x.code))
85
+ }
86
+ )
65
87
  ] })
66
88
  ]
67
89
  }
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { TooltipProps } from '@mui/material';
3
+ interface EditableFieldProps {
4
+ value: string;
5
+ onChange?: (value: string) => void;
6
+ onValueValidate?: (value: string) => void;
7
+ editable: boolean;
8
+ component?: 'input' | 'textarea';
9
+ placeholder?: string;
10
+ rows?: number;
11
+ maxLength?: number;
12
+ icon?: React.ReactNode;
13
+ label?: string;
14
+ children?: React.ReactNode;
15
+ tooltip?: TooltipProps['title'];
16
+ inline?: boolean;
17
+ style?: React.CSSProperties;
18
+ verified?: boolean;
19
+ errorMsg?: string;
20
+ }
21
+ declare function EditableField({ value, onChange, onValueValidate, errorMsg, editable, component, placeholder, rows, maxLength, icon, label, children, tooltip, inline, style, verified, }: EditableFieldProps): JSX.Element | null;
22
+ export default EditableField;
@@ -0,0 +1,159 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, TextField, Typography, Tooltip } from "@mui/material";
3
+ import { useCreation, useMemoizedFn } from "ahooks";
4
+ import { temp as colors } from "@arcblock/ux/lib/Colors";
5
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
6
+ import { translate } from "@arcblock/ux/lib/Locale/util";
7
+ import VerifiedIcon from "@mui/icons-material/Verified";
8
+ import { translations } from "../libs/locales.js";
9
+ const inputFieldStyle = {
10
+ width: "100%",
11
+ ".MuiOutlinedInput-root": {
12
+ "&:hover": {
13
+ fieldset: {
14
+ borderColor: colors.dividerColor
15
+ }
16
+ },
17
+ "&.Mui-focused": {
18
+ fieldset: {
19
+ borderColor: colors.dividerColor
20
+ }
21
+ }
22
+ },
23
+ fieldset: {
24
+ borderColor: colors.dividerColor
25
+ }
26
+ };
27
+ function EditableField({
28
+ value,
29
+ onChange = () => {
30
+ },
31
+ onValueValidate = () => {
32
+ },
33
+ errorMsg = "",
34
+ editable = false,
35
+ component = "input",
36
+ placeholder = "",
37
+ rows = 2,
38
+ maxLength,
39
+ icon,
40
+ label = "",
41
+ children,
42
+ tooltip,
43
+ inline = true,
44
+ style = {},
45
+ verified = false
46
+ }) {
47
+ const { locale } = useLocaleContext();
48
+ const t = useMemoizedFn((key, data = {}) => {
49
+ return translate(translations, key, locale, "en", data);
50
+ });
51
+ const handleChange = useMemoizedFn((v) => {
52
+ if (onChange) {
53
+ onChange(v);
54
+ }
55
+ if (onValueValidate) {
56
+ onValueValidate(v);
57
+ }
58
+ });
59
+ const content = useCreation(() => {
60
+ if (children) {
61
+ return children;
62
+ }
63
+ if (component === "input") {
64
+ return /* @__PURE__ */ jsx(
65
+ TextField,
66
+ {
67
+ variant: "outlined",
68
+ className: "editable-field",
69
+ InputProps: {
70
+ sx: { backgroundColor: "transparent" },
71
+ placeholder
72
+ },
73
+ value,
74
+ onChange: (e) => handleChange(e.target.value),
75
+ sx: inputFieldStyle,
76
+ error: Boolean(errorMsg),
77
+ helperText: errorMsg
78
+ }
79
+ );
80
+ }
81
+ const isTooLong = value.length > (maxLength || 300);
82
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", children: [
83
+ /* @__PURE__ */ jsx(
84
+ TextField,
85
+ {
86
+ variant: "outlined",
87
+ InputProps: {
88
+ multiline: true,
89
+ minRows: rows,
90
+ placeholder
91
+ },
92
+ sx: inputFieldStyle,
93
+ value,
94
+ onChange: (e) => handleChange(e.target.value),
95
+ error: Boolean(errorMsg),
96
+ helperText: errorMsg
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsxs(
100
+ Typography,
101
+ {
102
+ position: "absolute",
103
+ bottom: -22,
104
+ right: 2,
105
+ variant: "caption",
106
+ fontSize: "12px",
107
+ component: "span",
108
+ color: isTooLong ? "error" : "text.secondary",
109
+ children: [
110
+ isTooLong ? `(${t("profile.maxInputLength")} ${maxLength}) ` : "",
111
+ value.length,
112
+ " / ",
113
+ maxLength
114
+ ]
115
+ }
116
+ )
117
+ ] });
118
+ }, [value, handleChange, component, placeholder, rows, children]);
119
+ if (!editable) {
120
+ return value ? /* @__PURE__ */ jsx(Tooltip, { title: tooltip, placement: "top", children: /* @__PURE__ */ jsxs(
121
+ Typography,
122
+ {
123
+ variant: "subtitle1",
124
+ component: "p",
125
+ gutterBottom: true,
126
+ sx: {
127
+ width: "100%",
128
+ mb: 0,
129
+ lineHeight: 1.4,
130
+ overflow: "hidden"
131
+ },
132
+ display: "flex",
133
+ alignItems: "center",
134
+ gap: 1,
135
+ children: [
136
+ icon,
137
+ /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "row", alignItems: "center", width: "90%", children: [
138
+ /* @__PURE__ */ jsx(
139
+ Typography,
140
+ {
141
+ sx: {
142
+ whiteSpace: "pre-wrap",
143
+ ...inline ? { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" } : {}
144
+ },
145
+ children: value
146
+ }
147
+ ),
148
+ verified && /* @__PURE__ */ jsx(VerifiedIcon, { color: "success", style: { fontSize: 16, width: 16, marginLeft: 4, flexShrink: 0 } })
149
+ ] })
150
+ ]
151
+ }
152
+ ) }) : null;
153
+ }
154
+ return /* @__PURE__ */ jsxs(Box, { sx: { width: "100%" }, style, children: [
155
+ label && /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", gutterBottom: true, sx: { mb: 0.5, fontSize: "12px", color: "#4B5563" }, children: label }),
156
+ content
157
+ ] });
158
+ }
159
+ export default EditableField;
@@ -0,0 +1,4 @@
1
+ import { User } from '../../@types';
2
+ export default function Nft({ user }: {
3
+ user: User;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,93 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Box, Pagination, Skeleton, Typography } from "@mui/material";
3
+ import { useCreation, useMemoizedFn, useReactive, useRequest } from "ahooks";
4
+ import axios from "axios";
5
+ import { temp as colors } from "@arcblock/ux/lib/Colors";
6
+ import NFTDisplay from "@arcblock/ux/lib/NFTDisplay";
7
+ import Empty from "@arcblock/ux/lib/Empty";
8
+ import { WELLKNOWN_SERVICE_PATH_PREFIX } from "@abtnode/constant";
9
+ import { translate } from "@arcblock/ux/lib/Locale/util";
10
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
11
+ import { translations } from "../libs/locales.js";
12
+ export default function Nft({ user }) {
13
+ const { locale } = useLocaleContext();
14
+ const t = useMemoizedFn((key, data2 = {}) => {
15
+ return translate(translations, key, locale, "en", data2);
16
+ });
17
+ const paging = useReactive({
18
+ page: 1,
19
+ size: 20
20
+ });
21
+ const userState = useRequest(
22
+ async (pagination = paging) => {
23
+ const response = await axios.get(`${WELLKNOWN_SERVICE_PATH_PREFIX}/ocap/listAssets`, {
24
+ params: {
25
+ ownerAddress: user.did,
26
+ ...pagination
27
+ }
28
+ });
29
+ return response.data;
30
+ },
31
+ {
32
+ defaultParams: [paging],
33
+ refreshDeps: [user.did, paging]
34
+ }
35
+ );
36
+ const { loading, data } = userState;
37
+ const dataPage = data?.page ?? { cursor: 0, next: false, total: 0 };
38
+ const handlePageChange = (event, value) => {
39
+ paging.page = value;
40
+ userState.run(paging);
41
+ };
42
+ const content = useCreation(() => {
43
+ if (loading) {
44
+ return /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [
45
+ /* @__PURE__ */ jsx(Skeleton, { width: "20%" }),
46
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rectangular", height: 200, sx: { borderRadius: 2 } })
47
+ ] });
48
+ }
49
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ /* @__PURE__ */ jsx(
51
+ Typography,
52
+ {
53
+ sx: {
54
+ color: colors.foregroundsFgBase,
55
+ fontWeight: 600,
56
+ mb: 2.5
57
+ },
58
+ children: t("common.nft")
59
+ }
60
+ ),
61
+ /* @__PURE__ */ jsxs(Box, { className: "nft-list-wrapper", display: "flex", flexDirection: "row", gap: 2, children: [
62
+ data?.assets?.map((item) => /* @__PURE__ */ jsx(Box, { width: 166, height: 166, children: /* @__PURE__ */ jsx(
63
+ NFTDisplay,
64
+ {
65
+ data: item.display,
66
+ address: item.address,
67
+ inset: true,
68
+ imageFilter: {
69
+ imageFilter: "resize",
70
+ w: "500",
71
+ f: "webp"
72
+ }
73
+ }
74
+ ) }, item.address)),
75
+ data?.assets?.length === 0 && !loading && /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", width: "100%", height: "100%", children: /* @__PURE__ */ jsx(Empty, { children: t("common.noNFT") }) })
76
+ ] }),
77
+ dataPage.next || paging.page > 1 ? /* @__PURE__ */ jsx(
78
+ Pagination,
79
+ {
80
+ sx: {
81
+ display: "flex",
82
+ justifyContent: "end"
83
+ },
84
+ page: paging.page,
85
+ onChange: handlePageChange,
86
+ count: Math.ceil(dataPage.total / paging.size),
87
+ size: "small"
88
+ }
89
+ ) : null
90
+ ] });
91
+ }, [loading, dataPage, paging.page, paging.size, handlePageChange]);
92
+ return /* @__PURE__ */ jsx(Box, { sx: { border: `1px solid ${colors.dividerColor}`, borderRadius: 2, p: 2, mb: 5 }, children: content });
93
+ }
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useEffect } from "react";
3
- import { Box, Divider, Typography } from "@mui/material";
3
+ import { Box, Typography } from "@mui/material";
4
4
  import { useCreation, useMemoizedFn } from "ahooks";
5
5
  import { translate } from "@arcblock/ux/lib/Locale/util";
6
6
  import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
@@ -74,25 +74,42 @@ export default function Settings({
74
74
  ...rest,
75
75
  sx: {
76
76
  ...rest?.sx,
77
+ display: "flex",
78
+ flexDirection: "column",
79
+ gap: 2.5,
77
80
  minWidth: {
78
81
  md: 500
79
82
  },
80
83
  maxWidth: "100%"
81
84
  },
82
- children: tabs.map((tab, index) => /* @__PURE__ */ jsxs(Box, { id: tab.value, children: [
83
- /* @__PURE__ */ jsx(
84
- Typography,
85
- {
86
- sx: {
87
- color: colors.foregroundsFgBase,
88
- fontWeight: 600
89
- },
90
- children: tab.label
91
- }
92
- ),
93
- /* @__PURE__ */ jsx(Box, { mt: 2.5, children: tab.content }),
94
- index < tabs.length - 1 ? /* @__PURE__ */ jsx(Divider, { sx: { mt: 2.5, mb: 2.5, borderColor: colors.dividerColor } }) : null
95
- ] }, tab.value))
85
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs(
86
+ Box,
87
+ {
88
+ id: tab.value,
89
+ sx: {
90
+ border: `1px solid ${colors.dividerColor}`,
91
+ borderRadius: 2,
92
+ p: 2,
93
+ "&:last-child": {
94
+ mb: 5
95
+ }
96
+ },
97
+ children: [
98
+ /* @__PURE__ */ jsx(
99
+ Typography,
100
+ {
101
+ sx: {
102
+ color: colors.foregroundsFgBase,
103
+ fontWeight: 600
104
+ },
105
+ children: tab.label
106
+ }
107
+ ),
108
+ /* @__PURE__ */ jsx(Box, { mt: 2.5, children: tab.content })
109
+ ]
110
+ },
111
+ tab.value
112
+ ))
96
113
  }
97
114
  );
98
115
  }
@@ -0,0 +1,9 @@
1
+ import { BaseStatusProps, StatusItem } from './menu-item';
2
+ interface StatusDurationMenuProps extends BaseStatusProps {
3
+ data: StatusItem;
4
+ }
5
+ declare function DurationMenu({ data, selected, onSelect }: StatusDurationMenuProps): import("react").JSX.Element;
6
+ export default DurationMenu;
7
+ export declare const MenuDiv: import("@emotion/styled").StyledComponent<import("@mui/material").MenuProps & {
8
+ theme?: import("@emotion/react").Theme;
9
+ }, {}, {}>;
@@ -0,0 +1,75 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Menu, Typography } from "@mui/material";
3
+ import styled from "@emotion/styled";
4
+ import { temp as colors } from "@arcblock/ux/lib/Colors";
5
+ import { useState } from "react";
6
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
7
+ import { useMemoizedFn } from "ahooks";
8
+ import { translate } from "@arcblock/ux/lib/Locale/util";
9
+ import { translations } from "../../libs/locales.js";
10
+ import StatusMenuItem, { StyledMenu } from "./menu-item.js";
11
+ function DurationMenu({ data, selected, onSelect }) {
12
+ const { locale } = useLocaleContext();
13
+ const t = useMemoizedFn((key, _data = {}) => {
14
+ return translate(translations, key, locale, "en", _data);
15
+ });
16
+ const [anchorEl, setAnchorEl] = useState(null);
17
+ const open = Boolean(anchorEl);
18
+ const openSubMenu = (e) => {
19
+ setAnchorEl(e.currentTarget);
20
+ };
21
+ const closeSubMenu = () => {
22
+ setAnchorEl(null);
23
+ };
24
+ const onSelectStatus = (e) => {
25
+ openSubMenu(e);
26
+ };
27
+ const onSelectDuration = (e, item) => {
28
+ onSelect({
29
+ ...selected ?? {},
30
+ value: data.id,
31
+ duration: item.id
32
+ });
33
+ closeSubMenu();
34
+ };
35
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
36
+ /* @__PURE__ */ jsx(StatusMenuItem, { icon: data.icon, selected: selected?.value === data.id, onClick: onSelectStatus, children: data.name }),
37
+ /* @__PURE__ */ jsxs(
38
+ StyledMenu,
39
+ {
40
+ anchorOrigin: {
41
+ vertical: "top",
42
+ horizontal: "right"
43
+ },
44
+ transformOrigin: {
45
+ vertical: "top",
46
+ horizontal: "left"
47
+ },
48
+ open,
49
+ onClose: closeSubMenu,
50
+ anchorEl,
51
+ children: [
52
+ /* @__PURE__ */ jsx(Typography, { component: "span", color: "text.secondary", pl: 2, fontSize: "14px", children: t("profile.removeStatusAfter") }),
53
+ data.children?.map((item) => /* @__PURE__ */ jsx(
54
+ StatusMenuItem,
55
+ {
56
+ selected: selected?.duration === item.id,
57
+ onClick: (e) => onSelectDuration(e, item),
58
+ children: item.name
59
+ },
60
+ item.id
61
+ ))
62
+ ]
63
+ }
64
+ )
65
+ ] });
66
+ }
67
+ export default DurationMenu;
68
+ export const MenuDiv = styled(Menu)`
69
+ .MuiList-root {
70
+ min-width: 160px;
71
+ }
72
+ .selected {
73
+ background-color: ${colors.backgroundsBgSubtitle};
74
+ }
75
+ `;
@@ -0,0 +1,9 @@
1
+ import { PopoverProps } from '@mui/material';
2
+ import { BaseStatusProps, StatusItem } from './menu-item';
3
+ interface StatusSelectorProps extends BaseStatusProps {
4
+ data: Array<StatusItem>;
5
+ open: boolean;
6
+ anchorEl?: PopoverProps['anchorEl'];
7
+ }
8
+ declare function StatusSelector({ data, open, onSelect, anchorEl, selected }: StatusSelectorProps): import("react").JSX.Element;
9
+ export default StatusSelector;
@@ -0,0 +1,39 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Typography } from "@mui/material";
3
+ import { translate } from "@arcblock/ux/lib/Locale/util";
4
+ import { useMemoizedFn } from "ahooks";
5
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
6
+ import StatusDurationMenu from "./duration-menu.js";
7
+ import StatusMenuItem, { StyledMenu } from "./menu-item.js";
8
+ import { translations } from "../../libs/locales.js";
9
+ function StatusSelector({ data, open, onSelect, anchorEl, selected }) {
10
+ const { locale } = useLocaleContext();
11
+ const t = useMemoizedFn((key, _data = {}) => {
12
+ return translate(translations, key, locale, "en", _data);
13
+ });
14
+ const onSelectStatus = (v) => {
15
+ onSelect(v);
16
+ };
17
+ const renderMenuItems = () => {
18
+ return data.map((item) => {
19
+ if (item.children) {
20
+ return /* @__PURE__ */ jsx(StatusDurationMenu, { data: item, selected, onSelect: onSelectStatus }, item.id);
21
+ }
22
+ return /* @__PURE__ */ jsx(
23
+ StatusMenuItem,
24
+ {
25
+ icon: item.icon,
26
+ selected: selected?.value === item.id,
27
+ onClick: () => onSelectStatus({ value: item.id }),
28
+ children: item.name
29
+ },
30
+ item.id
31
+ );
32
+ });
33
+ };
34
+ return /* @__PURE__ */ jsxs(StyledMenu, { open, onClose: () => onSelectStatus(), anchorEl, children: [
35
+ /* @__PURE__ */ jsx(Typography, { component: "span", color: "text.secondary", pl: 2, fontSize: "14px", children: t("profile.setStatus") }),
36
+ renderMenuItems()
37
+ ] });
38
+ }
39
+ export default StatusSelector;
@@ -0,0 +1,24 @@
1
+ import { SvgIconProps } from '@mui/material/SvgIcon';
2
+ import React from 'react';
3
+ import { UserMetadata } from '../../../@types';
4
+ interface StatusMenuItemProps {
5
+ icon?: React.FC<SvgIconProps>;
6
+ selected?: boolean;
7
+ onClick: (e: React.MouseEvent<HTMLElement>) => void;
8
+ children: React.ReactNode;
9
+ }
10
+ export default function StatusMenuItem({ icon, selected, onClick, children }: StatusMenuItemProps): JSX.Element;
11
+ export declare const StyledMenu: import("@emotion/styled").StyledComponent<import("@mui/material").MenuProps & {
12
+ theme?: import("@emotion/react").Theme;
13
+ }, {}, {}>;
14
+ export interface StatusItem {
15
+ id: string;
16
+ name: string;
17
+ icon?: React.FC<SvgIconProps>;
18
+ children?: Array<StatusItem>;
19
+ }
20
+ export interface BaseStatusProps {
21
+ selected: UserMetadata['status'];
22
+ onSelect: (v: UserMetadata['status']) => void;
23
+ }
24
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { ListItemIcon, MenuItem, Menu } from "@mui/material";
3
+ import React from "react";
4
+ import styled from "@emotion/styled";
5
+ import { temp as colors } from "@arcblock/ux/lib/Colors";
6
+ export default function StatusMenuItem({ icon, selected, onClick, children }) {
7
+ return /* @__PURE__ */ jsxs(MenuItem, { onClick, className: selected ? "selected" : "", children: [
8
+ icon && /* @__PURE__ */ jsx(ListItemIcon, { style: { minWidth: "24px" }, children: React.createElement(icon, {
9
+ style: { fontSize: "16px", width: "16px", height: "16px" }
10
+ }) }),
11
+ children
12
+ ] });
13
+ }
14
+ export const StyledMenu = styled(Menu)`
15
+ .MuiPaper-root {
16
+ box-shadow: 0px 6px 24px rgba(0, 0, 0, 0.15);
17
+ }
18
+ .MuiList-root {
19
+ min-width: 160px;
20
+ }
21
+ .selected {
22
+ background-color: ${colors.backgroundsBgSubtitle};
23
+ }
24
+ `;