@blocklet/ui-react 2.11.3 → 2.11.5
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.
- package/lib/UserCenter/components/passport.js +1 -1
- package/lib/UserCenter/components/third-party-login/third-party-item.js +3 -0
- package/lib/UserCenter/components/user-center.js +3 -7
- package/lib/UserSessions/components/user-sessions.js +37 -27
- package/package.json +8 -7
- package/src/UserCenter/components/passport.tsx +1 -1
- package/src/UserCenter/components/third-party-login/third-party-item.tsx +3 -0
- package/src/UserCenter/components/user-center.tsx +3 -7
- package/src/UserSessions/components/user-sessions.tsx +56 -40
|
@@ -55,6 +55,9 @@ export default function ThirdPartyItem({
|
|
|
55
55
|
title: t("thirdPartyLogin.confirmUnbind", { name: title }),
|
|
56
56
|
content: t("thirdPartyLogin.confirmUnbindDescription", { name: title }),
|
|
57
57
|
confirmButtonText: t("common.confirm"),
|
|
58
|
+
confirmButtonProps: {
|
|
59
|
+
color: "error"
|
|
60
|
+
},
|
|
58
61
|
cancelButtonText: t("common.cancel"),
|
|
59
62
|
onConfirm(close) {
|
|
60
63
|
unbindOAuth({
|
|
@@ -14,7 +14,7 @@ import { translate } from "@arcblock/ux/lib/Locale/util";
|
|
|
14
14
|
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
15
15
|
import { ErrorFallback } from "@arcblock/ux/lib/ErrorBoundary";
|
|
16
16
|
import cloneDeep from "lodash/cloneDeep";
|
|
17
|
-
import { getQuery, withQuery, joinURL } from "ufo";
|
|
17
|
+
import { getQuery, withQuery, joinURL, withoutTrailingSlash } from "ufo";
|
|
18
18
|
import { PROFILE_URL } from "@arcblock/ux/lib/Util/constant";
|
|
19
19
|
import Footer from "../../Footer/index.js";
|
|
20
20
|
import Header from "../../Header/index.js";
|
|
@@ -157,7 +157,7 @@ export default function UserCenter({
|
|
|
157
157
|
}).filter((x) => isMyself || !x.isPrivate);
|
|
158
158
|
}, [formattedBlocklet, userState.data, privacyState?.data, locale, defaultTabs, isMyself]);
|
|
159
159
|
const currentActiveTab = useCreation(() => {
|
|
160
|
-
return userCenterTabs.find((x) => x.value === currentTab);
|
|
160
|
+
return userCenterTabs.find((x) => withoutTrailingSlash(x.value) === withoutTrailingSlash(currentTab));
|
|
161
161
|
}, [userCenterTabs]);
|
|
162
162
|
const handleChangeTab = useMemoizedFn((value) => {
|
|
163
163
|
const findTab = userCenterTabs.find((x) => x.value === value);
|
|
@@ -198,10 +198,6 @@ export default function UserCenter({
|
|
|
198
198
|
Box,
|
|
199
199
|
{
|
|
200
200
|
sx: {
|
|
201
|
-
width: {
|
|
202
|
-
sx: "100%",
|
|
203
|
-
md: 420
|
|
204
|
-
},
|
|
205
201
|
maxWidth: "100%",
|
|
206
202
|
position: "relative"
|
|
207
203
|
},
|
|
@@ -322,7 +318,7 @@ export default function UserCenter({
|
|
|
322
318
|
orientation: isMobile ? "horizontal" : "vertical",
|
|
323
319
|
variant: "line",
|
|
324
320
|
tabs: userCenterTabs,
|
|
325
|
-
current: currentTab,
|
|
321
|
+
current: currentActiveTab?.value ?? currentTab,
|
|
326
322
|
onChange: handleChangeTab,
|
|
327
323
|
sx: {
|
|
328
324
|
width: isMobile ? "100%" : 180,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Datatable from "@arcblock/ux/lib/Datatable";
|
|
3
|
-
import { useCreation, useMemoizedFn, useRequest } from "ahooks";
|
|
3
|
+
import { useCreation, useMemoizedFn, useReactive, useRequest } 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 RelativeTime from "@arcblock/ux/lib/RelativeTime";
|
|
@@ -9,13 +9,14 @@ import UAParser from "ua-parser-js";
|
|
|
9
9
|
import { getVisitorId } from "@arcblock/ux/lib/Util";
|
|
10
10
|
import { useConfirm } from "@arcblock/ux/lib/Dialog";
|
|
11
11
|
import pAll from "p-all";
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
12
|
+
import PQueue from "p-queue";
|
|
13
|
+
import { Box, Button, CircularProgress, Tooltip, Typography } from "@mui/material";
|
|
14
|
+
import { memo, useContext, useEffect } from "react";
|
|
14
15
|
import { SessionContext } from "@arcblock/did-connect/lib/Session";
|
|
15
16
|
import UserSessionInfo from "./user-session-info.js";
|
|
16
17
|
import { client } from "../../libs/client.js";
|
|
17
18
|
import { translations } from "../libs/locales.js";
|
|
18
|
-
import {
|
|
19
|
+
import { ip2Region } from "../libs/utils.js";
|
|
19
20
|
const parseUa = (ua) => {
|
|
20
21
|
const parser = new UAParser(ua, {
|
|
21
22
|
// eslint-disable-next-line no-useless-escape
|
|
@@ -24,6 +25,30 @@ const parseUa = (ua) => {
|
|
|
24
25
|
const result = parser.getResult();
|
|
25
26
|
return result;
|
|
26
27
|
};
|
|
28
|
+
const queue = new PQueue({ concurrency: 1 });
|
|
29
|
+
const UserSessionIp = memo(({ userSession }) => {
|
|
30
|
+
const currentState = useReactive({
|
|
31
|
+
loading: true,
|
|
32
|
+
ipRegion: ""
|
|
33
|
+
});
|
|
34
|
+
const { t } = useLocaleContext();
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
queue.add(async () => {
|
|
37
|
+
try {
|
|
38
|
+
currentState.ipRegion = await ip2Region(userSession.lastLoginIp);
|
|
39
|
+
} finally {
|
|
40
|
+
currentState.loading = false;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}, [currentState, userSession.lastLoginIp]);
|
|
44
|
+
return /* @__PURE__ */ jsx(Box, { children: currentState.ipRegion ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
45
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: currentState.ipRegion }),
|
|
46
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "grey", children: userSession.lastLoginIp || t("unknown") })
|
|
47
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48
|
+
/* @__PURE__ */ jsx(Typography, { children: userSession.lastLoginIp || t("unknown") }),
|
|
49
|
+
currentState.loading ? /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "grey", sx: { textAlign: "center" }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 12, color: "inherit" }) }) : null
|
|
50
|
+
] }) });
|
|
51
|
+
});
|
|
27
52
|
export default function UserSessions({
|
|
28
53
|
user,
|
|
29
54
|
showAction = true,
|
|
@@ -39,18 +64,9 @@ export default function UserSessions({
|
|
|
39
64
|
const getData = useMemoizedFn(async () => {
|
|
40
65
|
let data = user?.userSessions || [];
|
|
41
66
|
try {
|
|
42
|
-
if (!
|
|
67
|
+
if (!user?.userSessions && session.user) {
|
|
43
68
|
data = await client.userSession.getMyLoginSessions();
|
|
44
69
|
}
|
|
45
|
-
const ipIndexList = data?.map((x, index) => [index, x.lastLoginIp]).filter((x) => !!x[1]);
|
|
46
|
-
const ipList = ipIndexList?.map((x) => x[1]);
|
|
47
|
-
const result = await batchIp2Region(ipList);
|
|
48
|
-
for (let index = 0; index < result.length; index++) {
|
|
49
|
-
const x = result[index];
|
|
50
|
-
const ipIndexItem = ipIndexList[index];
|
|
51
|
-
const dataItem = data[ipIndexItem[0]];
|
|
52
|
-
dataItem.ipRegion = x;
|
|
53
|
-
}
|
|
54
70
|
} catch (e) {
|
|
55
71
|
console.warn("Failed to convert ip to region");
|
|
56
72
|
console.error(e);
|
|
@@ -67,20 +83,14 @@ export default function UserSessions({
|
|
|
67
83
|
const safeData = useCreation(() => {
|
|
68
84
|
return pageState.data || [];
|
|
69
85
|
}, [pageState.data]);
|
|
70
|
-
const ipRegionMap = useCreation(() => {
|
|
71
|
-
return safeData.reduce(
|
|
72
|
-
(acc, x) => {
|
|
73
|
-
acc[x.lastLoginIp] = x.ipRegion;
|
|
74
|
-
return acc;
|
|
75
|
-
},
|
|
76
|
-
{}
|
|
77
|
-
);
|
|
78
|
-
}, [safeData]);
|
|
79
86
|
const logout = useMemoizedFn(({ visitorId }) => {
|
|
80
87
|
confirmApi.open({
|
|
81
88
|
title: t("logoutThisSession"),
|
|
82
89
|
content: t("logoutThisSessionConfirm"),
|
|
83
90
|
confirmButtonText: t("confirm"),
|
|
91
|
+
confirmButtonProps: {
|
|
92
|
+
color: "error"
|
|
93
|
+
},
|
|
84
94
|
cancelButtonText: t("cancel"),
|
|
85
95
|
onConfirm: async () => {
|
|
86
96
|
await client.user.logout({ visitorId });
|
|
@@ -98,6 +108,9 @@ export default function UserSessions({
|
|
|
98
108
|
title: t("logoutAllSession"),
|
|
99
109
|
content: t("logoutAllSessionConfirm"),
|
|
100
110
|
confirmButtonText: t("confirm"),
|
|
111
|
+
confirmButtonProps: {
|
|
112
|
+
color: "error"
|
|
113
|
+
},
|
|
101
114
|
cancelButtonText: t("cancel"),
|
|
102
115
|
onConfirm: async () => {
|
|
103
116
|
const list = otherUserSessions.map((x) => {
|
|
@@ -210,10 +223,7 @@ export default function UserSessions({
|
|
|
210
223
|
options: {
|
|
211
224
|
customBodyRenderLite: (rawIndex) => {
|
|
212
225
|
const x = safeData[rawIndex];
|
|
213
|
-
return /* @__PURE__ */ jsx(
|
|
214
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: ipRegionMap[x.lastLoginIp] }),
|
|
215
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "grey", children: x.lastLoginIp || t("unknown") })
|
|
216
|
-
] }) : /* @__PURE__ */ jsx(Typography, { children: x.lastLoginIp || t("unknown") }) });
|
|
226
|
+
return /* @__PURE__ */ jsx(UserSessionIp, { userSession: x });
|
|
217
227
|
}
|
|
218
228
|
}
|
|
219
229
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/ui-react",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.5",
|
|
4
4
|
"description": "Some useful front-end web components that can be used in Blocklets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"url": "https://github.com/ArcBlock/ux/issues"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@arcblock/bridge": "^2.11.
|
|
36
|
-
"@arcblock/react-hooks": "^2.11.
|
|
35
|
+
"@arcblock/bridge": "^2.11.5",
|
|
36
|
+
"@arcblock/react-hooks": "^2.11.5",
|
|
37
37
|
"@blocklet/did-space-react": "^0.5.83",
|
|
38
38
|
"@iconify-icons/logos": "^1.2.36",
|
|
39
39
|
"@iconify-icons/material-symbols": "^1.2.58",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"is-url": "^1.2.4",
|
|
48
48
|
"lodash": "^4.17.21",
|
|
49
49
|
"p-all": "^5.0.0",
|
|
50
|
+
"p-queue": "^6.6.2",
|
|
50
51
|
"p-wait-for": "^5.0.2",
|
|
51
52
|
"prop-types": "^15.8.1",
|
|
52
53
|
"react-error-boundary": "^3.1.4",
|
|
@@ -56,9 +57,9 @@
|
|
|
56
57
|
"ufo": "^1.5.3"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
|
-
"@arcblock/did-connect": "^2.
|
|
60
|
-
"@arcblock/ux": "^2.
|
|
61
|
-
"@blocklet/js-sdk": "^1.16.
|
|
60
|
+
"@arcblock/did-connect": "^2.11.3",
|
|
61
|
+
"@arcblock/ux": "^2.11.3",
|
|
62
|
+
"@blocklet/js-sdk": "^1.16.36",
|
|
62
63
|
"@emotion/react": "^11.10.4",
|
|
63
64
|
"@emotion/styled": "^11.10.4",
|
|
64
65
|
"@mui/icons-material": "^5.15.0",
|
|
@@ -80,5 +81,5 @@
|
|
|
80
81
|
"jest": "^29.7.0",
|
|
81
82
|
"unbuild": "^2.0.0"
|
|
82
83
|
},
|
|
83
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "ad0f1851be1f8ee0f655131ad3734fceb807f9de"
|
|
84
85
|
}
|
|
@@ -71,6 +71,9 @@ export default function ThirdPartyItem({
|
|
|
71
71
|
title: t('thirdPartyLogin.confirmUnbind', { name: title }),
|
|
72
72
|
content: t('thirdPartyLogin.confirmUnbindDescription', { name: title }),
|
|
73
73
|
confirmButtonText: t('common.confirm'),
|
|
74
|
+
confirmButtonProps: {
|
|
75
|
+
color: 'error',
|
|
76
|
+
},
|
|
74
77
|
cancelButtonText: t('common.cancel'),
|
|
75
78
|
onConfirm(close: () => void) {
|
|
76
79
|
unbindOAuth({
|
|
@@ -15,7 +15,7 @@ import { translate } from '@arcblock/ux/lib/Locale/util';
|
|
|
15
15
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
16
16
|
import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
|
|
17
17
|
import cloneDeep from 'lodash/cloneDeep';
|
|
18
|
-
import { getQuery, withQuery, joinURL } from 'ufo';
|
|
18
|
+
import { getQuery, withQuery, joinURL, withoutTrailingSlash } from 'ufo';
|
|
19
19
|
import type { AxiosError } from 'axios';
|
|
20
20
|
import type { UserPublicInfo } from '@blocklet/js-sdk';
|
|
21
21
|
|
|
@@ -190,7 +190,7 @@ export default function UserCenter({
|
|
|
190
190
|
}, [formattedBlocklet, userState.data, privacyState?.data, locale, defaultTabs, isMyself]);
|
|
191
191
|
|
|
192
192
|
const currentActiveTab = useCreation(() => {
|
|
193
|
-
return userCenterTabs.find((x) => x.value === currentTab);
|
|
193
|
+
return userCenterTabs.find((x) => withoutTrailingSlash(x.value) === withoutTrailingSlash(currentTab));
|
|
194
194
|
}, [userCenterTabs]);
|
|
195
195
|
|
|
196
196
|
const handleChangeTab = useMemoizedFn((value) => {
|
|
@@ -235,10 +235,6 @@ export default function UserCenter({
|
|
|
235
235
|
return (
|
|
236
236
|
<Box
|
|
237
237
|
sx={{
|
|
238
|
-
width: {
|
|
239
|
-
sx: '100%',
|
|
240
|
-
md: 420,
|
|
241
|
-
},
|
|
242
238
|
maxWidth: '100%',
|
|
243
239
|
position: 'relative',
|
|
244
240
|
}}>
|
|
@@ -364,7 +360,7 @@ export default function UserCenter({
|
|
|
364
360
|
orientation={isMobile ? 'horizontal' : 'vertical'}
|
|
365
361
|
variant="line"
|
|
366
362
|
tabs={userCenterTabs}
|
|
367
|
-
current={currentTab}
|
|
363
|
+
current={currentActiveTab?.value ?? currentTab}
|
|
368
364
|
onChange={handleChangeTab}
|
|
369
365
|
sx={{
|
|
370
366
|
width: isMobile ? '100%' : 180,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
2
|
/* eslint-disable react/no-unstable-nested-components */
|
|
3
3
|
import Datatable from '@arcblock/ux/lib/Datatable';
|
|
4
|
-
import { useCreation, useMemoizedFn, useRequest } from 'ahooks';
|
|
4
|
+
import { useCreation, useMemoizedFn, useReactive, useRequest } from 'ahooks';
|
|
5
5
|
import { translate } from '@arcblock/ux/lib/Locale/util';
|
|
6
6
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
7
7
|
import RelativeTime from '@arcblock/ux/lib/RelativeTime';
|
|
@@ -10,8 +10,9 @@ import UAParser from 'ua-parser-js';
|
|
|
10
10
|
import { getVisitorId } from '@arcblock/ux/lib/Util';
|
|
11
11
|
import { useConfirm } from '@arcblock/ux/lib/Dialog';
|
|
12
12
|
import pAll from 'p-all';
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
13
|
+
import PQueue from 'p-queue';
|
|
14
|
+
import { Box, Button, CircularProgress, Tooltip, Typography } from '@mui/material';
|
|
15
|
+
import { memo, ReactElement, useContext, useEffect } from 'react';
|
|
15
16
|
import { UserSession } from '@blocklet/js-sdk';
|
|
16
17
|
import { SessionContext } from '@arcblock/did-connect/lib/Session';
|
|
17
18
|
|
|
@@ -19,7 +20,7 @@ import UserSessionInfo from './user-session-info';
|
|
|
19
20
|
import { User, SessionContext as TSessionContext } from '../../@types';
|
|
20
21
|
import { client } from '../../libs/client';
|
|
21
22
|
import { translations } from '../libs/locales';
|
|
22
|
-
import {
|
|
23
|
+
import { ip2Region } from '../libs/utils';
|
|
23
24
|
|
|
24
25
|
const parseUa = (ua: string) => {
|
|
25
26
|
const parser = new UAParser(ua, {
|
|
@@ -30,6 +31,49 @@ const parseUa = (ua: string) => {
|
|
|
30
31
|
return result;
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
const queue = new PQueue({ concurrency: 1 });
|
|
35
|
+
|
|
36
|
+
const UserSessionIp = memo(({ userSession }: { userSession: any }) => {
|
|
37
|
+
const currentState = useReactive({
|
|
38
|
+
loading: true,
|
|
39
|
+
ipRegion: '',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const { t } = useLocaleContext();
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
queue.add(async () => {
|
|
46
|
+
try {
|
|
47
|
+
currentState.ipRegion = await ip2Region(userSession.lastLoginIp);
|
|
48
|
+
} finally {
|
|
49
|
+
currentState.loading = false;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}, [currentState, userSession.lastLoginIp]);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Box>
|
|
56
|
+
{currentState.ipRegion ? (
|
|
57
|
+
<>
|
|
58
|
+
<Typography variant="body2">{currentState.ipRegion}</Typography>
|
|
59
|
+
<Typography variant="body2" color="grey">
|
|
60
|
+
{userSession.lastLoginIp || t('unknown')}
|
|
61
|
+
</Typography>
|
|
62
|
+
</>
|
|
63
|
+
) : (
|
|
64
|
+
<>
|
|
65
|
+
<Typography>{userSession.lastLoginIp || t('unknown')}</Typography>
|
|
66
|
+
{currentState.loading ? (
|
|
67
|
+
<Typography variant="body2" color="grey" sx={{ textAlign: 'center' }}>
|
|
68
|
+
<CircularProgress size={12} color="inherit" />
|
|
69
|
+
</Typography>
|
|
70
|
+
) : null}
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
73
|
+
</Box>
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
33
77
|
export default function UserSessions({
|
|
34
78
|
user,
|
|
35
79
|
showAction = true,
|
|
@@ -51,20 +95,9 @@ export default function UserSessions({
|
|
|
51
95
|
const getData: () => Promise<(UserSession & { ipRegion?: string })[]> = useMemoizedFn(async () => {
|
|
52
96
|
let data = (user?.userSessions || []) as (UserSession & { ipRegion?: string })[];
|
|
53
97
|
try {
|
|
54
|
-
if (!
|
|
55
|
-
// 依赖新版 js-sdk
|
|
98
|
+
if (!user?.userSessions && session.user) {
|
|
56
99
|
data = await client.userSession.getMyLoginSessions();
|
|
57
100
|
}
|
|
58
|
-
// FIXME: @zhanghan 优化获取 IP 信息的处理逻辑
|
|
59
|
-
const ipIndexList = data?.map((x, index) => [index, x.lastLoginIp] as [number, string]).filter((x) => !!x[1]);
|
|
60
|
-
const ipList = ipIndexList?.map((x) => x[1]);
|
|
61
|
-
const result = await batchIp2Region(ipList);
|
|
62
|
-
for (let index = 0; index < result.length; index++) {
|
|
63
|
-
const x = result[index];
|
|
64
|
-
const ipIndexItem = ipIndexList[index];
|
|
65
|
-
const dataItem = data[ipIndexItem[0]];
|
|
66
|
-
dataItem.ipRegion = x;
|
|
67
|
-
}
|
|
68
101
|
} catch (e) {
|
|
69
102
|
console.warn('Failed to convert ip to region');
|
|
70
103
|
console.error(e);
|
|
@@ -85,21 +118,14 @@ export default function UserSessions({
|
|
|
85
118
|
return pageState.data || [];
|
|
86
119
|
}, [pageState.data]);
|
|
87
120
|
|
|
88
|
-
const ipRegionMap = useCreation(() => {
|
|
89
|
-
return safeData.reduce(
|
|
90
|
-
(acc, x) => {
|
|
91
|
-
acc[x.lastLoginIp] = x.ipRegion;
|
|
92
|
-
return acc;
|
|
93
|
-
},
|
|
94
|
-
{} as { [key: string]: string | undefined }
|
|
95
|
-
);
|
|
96
|
-
}, [safeData]);
|
|
97
|
-
|
|
98
121
|
const logout = useMemoizedFn(({ visitorId }) => {
|
|
99
122
|
confirmApi.open({
|
|
100
123
|
title: t('logoutThisSession'),
|
|
101
124
|
content: t('logoutThisSessionConfirm'),
|
|
102
125
|
confirmButtonText: t('confirm'),
|
|
126
|
+
confirmButtonProps: {
|
|
127
|
+
color: 'error',
|
|
128
|
+
},
|
|
103
129
|
cancelButtonText: t('cancel'),
|
|
104
130
|
onConfirm: async () => {
|
|
105
131
|
await client.user.logout({ visitorId });
|
|
@@ -117,6 +143,9 @@ export default function UserSessions({
|
|
|
117
143
|
title: t('logoutAllSession'),
|
|
118
144
|
content: t('logoutAllSessionConfirm'),
|
|
119
145
|
confirmButtonText: t('confirm'),
|
|
146
|
+
confirmButtonProps: {
|
|
147
|
+
color: 'error',
|
|
148
|
+
},
|
|
120
149
|
cancelButtonText: t('cancel'),
|
|
121
150
|
onConfirm: async () => {
|
|
122
151
|
const list = otherUserSessions.map((x) => {
|
|
@@ -240,20 +269,7 @@ export default function UserSessions({
|
|
|
240
269
|
options: {
|
|
241
270
|
customBodyRenderLite: (rawIndex: number) => {
|
|
242
271
|
const x = safeData[rawIndex];
|
|
243
|
-
return
|
|
244
|
-
<Box>
|
|
245
|
-
{ipRegionMap[x.lastLoginIp] ? (
|
|
246
|
-
<>
|
|
247
|
-
<Typography variant="body2">{ipRegionMap[x.lastLoginIp]}</Typography>
|
|
248
|
-
<Typography variant="body2" color="grey">
|
|
249
|
-
{x.lastLoginIp || t('unknown')}
|
|
250
|
-
</Typography>
|
|
251
|
-
</>
|
|
252
|
-
) : (
|
|
253
|
-
<Typography>{x.lastLoginIp || t('unknown')}</Typography>
|
|
254
|
-
)}
|
|
255
|
-
</Box>
|
|
256
|
-
);
|
|
272
|
+
return <UserSessionIp userSession={x} />;
|
|
257
273
|
},
|
|
258
274
|
},
|
|
259
275
|
},
|