@taskon/widget-react 0.0.1-beta.5 → 0.0.1-beta.7
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/README.md +61 -47
- package/dist/CommunityTaskList.css +9 -1
- package/dist/EligibilityInfo.css +48 -75
- package/dist/LeaderboardWidget.css +73 -71
- package/dist/PageBuilder.css +5 -0
- package/dist/Quest.css +18 -14
- package/dist/TaskOnProvider.css +289 -0
- package/dist/ThemeProvider.css +227 -0
- package/dist/UserCenterWidget.css +6 -6
- package/dist/UserCenterWidget2.css +1388 -1621
- package/dist/{dynamic-import-helper.css → WidgetShell.css} +0 -227
- package/dist/chunks/{CommunityTaskList-CrMvOB8w.js → CommunityTaskList-D0uVD8wD.js} +393 -208
- package/dist/chunks/{EligibilityInfo-Beww12QX.js → EligibilityInfo-Cf6hx9-a.js} +459 -679
- package/dist/chunks/{LeaderboardWidget-DwuSpVl0.js → LeaderboardWidget-DyoiiNS6.js} +274 -252
- package/dist/chunks/{PageBuilder-DsX6Tv0N.js → PageBuilder-DoAFPm6-.js} +5 -5
- package/dist/chunks/{Quest-CuD2LElS.js → Quest-ySZlYd4u.js} +74 -57
- package/dist/chunks/TaskOnProvider-CxtFIs3n.js +2072 -0
- package/dist/chunks/{dynamic-import-helper-WmIF58Sb.js → ThemeProvider-CulHkqqY.js} +1282 -555
- package/dist/chunks/UserCenterWidget-BJsc_GSZ.js +3246 -0
- package/dist/chunks/{UserCenterWidget-CvU6K4AC.js → UserCenterWidget-STq8kpV4.js} +1174 -1386
- package/dist/chunks/WidgetShell-8xn-Jivw.js +659 -0
- package/dist/chunks/communitytask-es-CBNnS4o2.js +521 -0
- package/dist/chunks/communitytask-ja-GRf9cbdx.js +521 -0
- package/dist/chunks/communitytask-ko-Bf24PQKI.js +521 -0
- package/dist/chunks/{communitytask-ru-DhySaZL8.js → communitytask-ru-CZm2CPoV.js} +211 -1
- package/dist/chunks/leaderboardwidget-es-vKjrjQaz.js +146 -0
- package/dist/chunks/leaderboardwidget-ja-Q6u0HxKG.js +146 -0
- package/dist/chunks/leaderboardwidget-ko-CG6SWgxf.js +146 -0
- package/dist/chunks/leaderboardwidget-ru-DCcHcJGz.js +146 -0
- package/dist/chunks/{quest-es-D-b5xcme.js → quest-es-Dyyy0zaw.js} +8 -93
- package/dist/chunks/{quest-ja-Dxd2vqBF.js → quest-ja-Depog33y.js} +8 -93
- package/dist/chunks/{quest-ko-CSmRWgK_.js → quest-ko-BMu3uRQJ.js} +8 -93
- package/dist/chunks/{quest-ru-CkEKv1_F.js → quest-ru-xne814Rw.js} +8 -93
- package/dist/chunks/useIsMobile-D6Ybur-6.js +30 -0
- package/dist/chunks/useToast-BGJhd3BX.js +93 -0
- package/dist/chunks/usercenter-es-Dz3Wp2vV.js +512 -0
- package/dist/chunks/usercenter-ja-CKE4DJC6.js +512 -0
- package/dist/chunks/usercenter-ko-Dtpkn2qb.js +512 -0
- package/dist/chunks/usercenter-ru-DnBGee45.js +512 -0
- package/dist/community-task.d.ts +0 -390
- package/dist/community-task.js +2 -7
- package/dist/core.d.ts +38 -20
- package/dist/core.js +9 -10
- package/dist/index.d.ts +86 -709
- package/dist/index.js +22 -28
- package/dist/leaderboard.d.ts +0 -498
- package/dist/leaderboard.js +2 -16
- package/dist/page-builder.js +1 -1
- package/dist/quest.d.ts +0 -971
- package/dist/quest.js +2 -7
- package/dist/user-center.d.ts +0 -1610
- package/dist/user-center.js +2 -494
- package/package.json +2 -2
- package/dist/chunks/TaskOnProvider-xUeP2Nro.js +0 -1243
- package/dist/chunks/ThemeProvider-Bt4UZ33y.js +0 -1334
- package/dist/chunks/UserCenterWidget-CB0hnj-L.js +0 -3230
- package/dist/chunks/communitytask-es-1zawvXEX.js +0 -311
- package/dist/chunks/communitytask-ja-CmW6nP-L.js +0 -311
- package/dist/chunks/communitytask-ko-BD0hzQSi.js +0 -311
- package/dist/chunks/createLocaleLoader-BameiEhU.js +0 -65
- package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +0 -119
- package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +0 -119
- package/dist/chunks/useToast-CaRkylKe.js +0 -304
- package/dist/chunks/usercenter-ja-B2465c1O.js +0 -326
- package/dist/chunks/usercenter-ko-xAEYxqLg.js +0 -326
|
@@ -1,3230 +0,0 @@
|
|
|
1
|
-
import { T as Table, u as usePagination, D as Dialog, B as Button, a as useResolvedWidgetConfig, W as WidgetShell, _ as __variableDynamicImportRuntimeHelper } from "./dynamic-import-helper-WmIF58Sb.js";
|
|
2
|
-
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useRef, useCallback, useLayoutEffect, useMemo, useEffect } from "react";
|
|
4
|
-
import { UserCenterRewardCardType, USER_CENTER_PAGE_SIZE, createUserCenterApi, SnsType, createUserApi, VerifyCodeType, getChainName, truncateAddress, filterEnabledAccounts, filterEnabledWallets, USER_CENTER_REWARD_CARD_TYPES, RewardType, toWei, LockedType, filterEnabledTabs, UserCenterTabType } from "@taskon/core";
|
|
5
|
-
import { d as useTaskOnContext, b as useWidgetLocale } from "./ThemeProvider-Bt4UZ33y.js";
|
|
6
|
-
import { L as LoadingState, E as EmptyState, P as Pagination, e as formatDateTime, A as AssetImage, d as buildRewardCards, g as useBindSocialAccount, I as Input, a as useTokenAssets, u as useRewardDetails, c as usePointsHistory, W as WithdrawForm, h as PointsList, N as NftRewardContent, i as TokenRewardContent, j as enMessages } from "./UserCenterWidget-CvU6K4AC.js";
|
|
7
|
-
import { u as useWallet, d as useToast } from "./useToast-CaRkylKe.js";
|
|
8
|
-
import '../UserCenterWidget.css';function Tabs({
|
|
9
|
-
items,
|
|
10
|
-
activeKey,
|
|
11
|
-
defaultActiveKey,
|
|
12
|
-
onChange,
|
|
13
|
-
className = "",
|
|
14
|
-
style,
|
|
15
|
-
gap = 40
|
|
16
|
-
}) {
|
|
17
|
-
var _a;
|
|
18
|
-
const [internalActiveKey, setInternalActiveKey] = useState(
|
|
19
|
-
defaultActiveKey ?? ((_a = items[0]) == null ? void 0 : _a.key) ?? ""
|
|
20
|
-
);
|
|
21
|
-
const currentActiveKey = activeKey ?? internalActiveKey;
|
|
22
|
-
const tabsRef = useRef(null);
|
|
23
|
-
const [indicatorStyle, setIndicatorStyle] = useState({});
|
|
24
|
-
const updateIndicator = useCallback(() => {
|
|
25
|
-
if (!tabsRef.current) return;
|
|
26
|
-
const activeTab = tabsRef.current.querySelector(
|
|
27
|
-
`.taskon-tabs__tab--active`
|
|
28
|
-
);
|
|
29
|
-
if (activeTab) {
|
|
30
|
-
setIndicatorStyle({
|
|
31
|
-
width: activeTab.offsetWidth,
|
|
32
|
-
transform: `translateX(${activeTab.offsetLeft}px)`
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}, []);
|
|
36
|
-
useLayoutEffect(() => {
|
|
37
|
-
updateIndicator();
|
|
38
|
-
}, [currentActiveKey, updateIndicator]);
|
|
39
|
-
useLayoutEffect(() => {
|
|
40
|
-
window.addEventListener("resize", updateIndicator);
|
|
41
|
-
return () => window.removeEventListener("resize", updateIndicator);
|
|
42
|
-
}, [updateIndicator]);
|
|
43
|
-
const handleTabClick = (item) => {
|
|
44
|
-
if (item.disabled) return;
|
|
45
|
-
if (activeKey === void 0) {
|
|
46
|
-
setInternalActiveKey(item.key);
|
|
47
|
-
}
|
|
48
|
-
onChange == null ? void 0 : onChange(item.key);
|
|
49
|
-
};
|
|
50
|
-
return /* @__PURE__ */ jsxs(
|
|
51
|
-
"div",
|
|
52
|
-
{
|
|
53
|
-
ref: tabsRef,
|
|
54
|
-
className: `taskon-tabs ${className}`,
|
|
55
|
-
style: { ...style, "--taskon-tabs-gap": `${gap}px` },
|
|
56
|
-
children: [
|
|
57
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-tabs__list", children: items.map((item) => /* @__PURE__ */ jsx(
|
|
58
|
-
"button",
|
|
59
|
-
{
|
|
60
|
-
type: "button",
|
|
61
|
-
className: `taskon-tabs__tab ${currentActiveKey === item.key ? "taskon-tabs__tab--active" : ""} ${item.disabled ? "taskon-tabs__tab--disabled" : ""}`,
|
|
62
|
-
onClick: () => handleTabClick(item),
|
|
63
|
-
disabled: item.disabled,
|
|
64
|
-
"aria-selected": currentActiveKey === item.key,
|
|
65
|
-
role: "tab",
|
|
66
|
-
children: item.label
|
|
67
|
-
},
|
|
68
|
-
item.key
|
|
69
|
-
)) }),
|
|
70
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-tabs__indicator", style: indicatorStyle })
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
function formatTimeRange(startTime, endTime) {
|
|
76
|
-
const formatDate = (timestamp) => {
|
|
77
|
-
const date = new Date(timestamp);
|
|
78
|
-
const year = date.getFullYear();
|
|
79
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
80
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
81
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
82
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
83
|
-
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
84
|
-
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
85
|
-
};
|
|
86
|
-
return `${formatDate(startTime)} - ${formatDate(endTime)}`;
|
|
87
|
-
}
|
|
88
|
-
function ActivityHistoryList({
|
|
89
|
-
data,
|
|
90
|
-
loading,
|
|
91
|
-
error,
|
|
92
|
-
pagination,
|
|
93
|
-
messages,
|
|
94
|
-
mode = "pagination",
|
|
95
|
-
onItemClick,
|
|
96
|
-
onRetry
|
|
97
|
-
}) {
|
|
98
|
-
const columns = useMemo(
|
|
99
|
-
() => [
|
|
100
|
-
{
|
|
101
|
-
key: "campaign_name",
|
|
102
|
-
title: messages.activityName,
|
|
103
|
-
cellClassName: "taskon-activity-history__cell--name",
|
|
104
|
-
render: (_value, row) => /* @__PURE__ */ jsxs("div", { className: "taskon-activity-history__name-cell", children: [
|
|
105
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-activity-history__campaign-name", children: row.campaign_name }),
|
|
106
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-activity-history__campaign-type", children: row.campaign_type })
|
|
107
|
-
] })
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
key: "time",
|
|
111
|
-
title: messages.activityTime,
|
|
112
|
-
width: "380px",
|
|
113
|
-
align: "right",
|
|
114
|
-
cellClassName: "taskon-activity-history__cell--time",
|
|
115
|
-
render: (_value, row) => formatTimeRange(row.start_time, row.end_time)
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
[messages.activityName, messages.activityTime]
|
|
119
|
-
);
|
|
120
|
-
const rowConfig = useMemo(
|
|
121
|
-
() => ({
|
|
122
|
-
getRowKey: (row) => `${row.campaign_type}-${row.campaign_id}`,
|
|
123
|
-
onRowClick: onItemClick
|
|
124
|
-
}),
|
|
125
|
-
[onItemClick]
|
|
126
|
-
);
|
|
127
|
-
if (loading && data.length === 0) {
|
|
128
|
-
return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
|
|
129
|
-
}
|
|
130
|
-
if (error && data.length === 0) {
|
|
131
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-user-center-error", children: [
|
|
132
|
-
/* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: error.message }),
|
|
133
|
-
onRetry && /* @__PURE__ */ jsx(
|
|
134
|
-
"button",
|
|
135
|
-
{
|
|
136
|
-
type: "button",
|
|
137
|
-
className: "taskon-user-center-error__retry",
|
|
138
|
-
onClick: onRetry,
|
|
139
|
-
children: messages.retry
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
] });
|
|
143
|
-
}
|
|
144
|
-
if (!loading && data.length === 0) {
|
|
145
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.emptyActivityHistory });
|
|
146
|
-
}
|
|
147
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-activity-history", children: [
|
|
148
|
-
/* @__PURE__ */ jsx(
|
|
149
|
-
Table,
|
|
150
|
-
{
|
|
151
|
-
columns,
|
|
152
|
-
data,
|
|
153
|
-
rowConfig,
|
|
154
|
-
className: "taskon-activity-history__table",
|
|
155
|
-
compact: true,
|
|
156
|
-
loading,
|
|
157
|
-
loadingText: messages.loading
|
|
158
|
-
}
|
|
159
|
-
),
|
|
160
|
-
mode === "pagination" ? /* @__PURE__ */ jsx(
|
|
161
|
-
Pagination,
|
|
162
|
-
{
|
|
163
|
-
page: pagination.page,
|
|
164
|
-
totalPages: pagination.totalPages,
|
|
165
|
-
onPrevious: pagination.goToPrevious,
|
|
166
|
-
onNext: pagination.goToNext,
|
|
167
|
-
hasPrevious: pagination.hasPrevious,
|
|
168
|
-
hasNext: pagination.hasNext,
|
|
169
|
-
messages
|
|
170
|
-
}
|
|
171
|
-
) : pagination.hasMore && /* @__PURE__ */ jsx("div", { className: "taskon-activity-history__load-more", children: /* @__PURE__ */ jsx(
|
|
172
|
-
"button",
|
|
173
|
-
{
|
|
174
|
-
type: "button",
|
|
175
|
-
className: "taskon-activity-history__load-more-btn",
|
|
176
|
-
onClick: pagination.loadMore,
|
|
177
|
-
disabled: loading,
|
|
178
|
-
children: loading ? messages.loading : messages.loadMore
|
|
179
|
-
}
|
|
180
|
-
) })
|
|
181
|
-
] });
|
|
182
|
-
}
|
|
183
|
-
function getCardTitle(type, messages, pointsData, xpLevelData) {
|
|
184
|
-
var _a;
|
|
185
|
-
switch (type) {
|
|
186
|
-
case UserCenterRewardCardType.Token:
|
|
187
|
-
return messages.rewardToken;
|
|
188
|
-
case UserCenterRewardCardType.Nft:
|
|
189
|
-
return messages.rewardNft;
|
|
190
|
-
case UserCenterRewardCardType.Whitelist:
|
|
191
|
-
return messages.rewardWhitelist;
|
|
192
|
-
case UserCenterRewardCardType.DiscordRole:
|
|
193
|
-
return messages.rewardDiscordRole;
|
|
194
|
-
case UserCenterRewardCardType.Points:
|
|
195
|
-
return (pointsData == null ? void 0 : pointsData.points_name) ?? messages.rewardPoints;
|
|
196
|
-
case UserCenterRewardCardType.XpLevel: {
|
|
197
|
-
const xpPointsName = (_a = xpLevelData == null ? void 0 : xpLevelData.xpPointsName) == null ? void 0 : _a.trim();
|
|
198
|
-
if (xpPointsName) {
|
|
199
|
-
return `${xpPointsName} & ${messages.level}`;
|
|
200
|
-
}
|
|
201
|
-
return messages.rewardXpLevel;
|
|
202
|
-
}
|
|
203
|
-
default:
|
|
204
|
-
return type;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
function getCardIconUrl(type, pointsData) {
|
|
208
|
-
if (type === UserCenterRewardCardType.Points && (pointsData == null ? void 0 : pointsData.points_icon)) {
|
|
209
|
-
return pointsData.points_icon;
|
|
210
|
-
}
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
function TokenIcon() {
|
|
214
|
-
return /* @__PURE__ */ jsxs("svg", { width: "25", height: "28", viewBox: "0 0 25 28", fill: "none", children: [
|
|
215
|
-
/* @__PURE__ */ jsx("path", { d: "M12.5 2L3 10H22L12.5 2Z", fill: "url(#token-gem-top)" }),
|
|
216
|
-
/* @__PURE__ */ jsx("path", { d: "M3 10L12.5 26L12.5 10H3Z", fill: "url(#token-gem-left)" }),
|
|
217
|
-
/* @__PURE__ */ jsx("path", { d: "M22 10L12.5 26L12.5 10H22Z", fill: "url(#token-gem-right)" }),
|
|
218
|
-
/* @__PURE__ */ jsx("path", { d: "M12.5 2L8 10H17L12.5 2Z", fill: "url(#token-gem-highlight)", fillOpacity: "0.6" }),
|
|
219
|
-
/* @__PURE__ */ jsxs("defs", { children: [
|
|
220
|
-
/* @__PURE__ */ jsxs("linearGradient", { id: "token-gem-top", x1: "12.5", y1: "2", x2: "12.5", y2: "10", gradientUnits: "userSpaceOnUse", children: [
|
|
221
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#81D4FA" }),
|
|
222
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#4FC3F7" })
|
|
223
|
-
] }),
|
|
224
|
-
/* @__PURE__ */ jsxs("linearGradient", { id: "token-gem-left", x1: "3", y1: "10", x2: "12.5", y2: "26", gradientUnits: "userSpaceOnUse", children: [
|
|
225
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#4FC3F7" }),
|
|
226
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#0288D1" })
|
|
227
|
-
] }),
|
|
228
|
-
/* @__PURE__ */ jsxs("linearGradient", { id: "token-gem-right", x1: "22", y1: "10", x2: "12.5", y2: "26", gradientUnits: "userSpaceOnUse", children: [
|
|
229
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#29B6F6" }),
|
|
230
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#0277BD" })
|
|
231
|
-
] }),
|
|
232
|
-
/* @__PURE__ */ jsxs("linearGradient", { id: "token-gem-highlight", x1: "12.5", y1: "2", x2: "12.5", y2: "10", gradientUnits: "userSpaceOnUse", children: [
|
|
233
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#E1F5FE" }),
|
|
234
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#81D4FA" })
|
|
235
|
-
] })
|
|
236
|
-
] })
|
|
237
|
-
] });
|
|
238
|
-
}
|
|
239
|
-
function NftIcon() {
|
|
240
|
-
return /* @__PURE__ */ jsx("span", { className: "taskon-asset-card__icon-nft", children: "NFT" });
|
|
241
|
-
}
|
|
242
|
-
function WhitelistIcon() {
|
|
243
|
-
return /* @__PURE__ */ jsx("span", { className: "taskon-asset-card__icon-wl", children: "WL" });
|
|
244
|
-
}
|
|
245
|
-
function DiscordRoleIcon() {
|
|
246
|
-
return /* @__PURE__ */ jsx("svg", { width: "28", height: "22", viewBox: "0 0 28 22", fill: "none", children: /* @__PURE__ */ jsx(
|
|
247
|
-
"path",
|
|
248
|
-
{
|
|
249
|
-
d: "M23.7 1.84A23.15 23.15 0 0018 0a.09.09 0 00-.09.04c-.25.44-.52 1.01-.71 1.46a21.37 21.37 0 00-6.4 0 14.77 14.77 0 00-.72-1.46.09.09 0 00-.1-.04 23.08 23.08 0 00-5.7 1.84.08.08 0 00-.04.03C.62 7.86-.37 13.68.12 19.41a.1.1 0 00.04.07 23.26 23.26 0 007 3.54.1.1 0 00.1-.04c.54-.74.97-1.52 1.33-2.33a.09.09 0 00-.05-.13 15.32 15.32 0 01-2.19-1.04.1.1 0 01-.01-.15c.15-.11.3-.22.43-.34a.09.09 0 01.09-.01c4.6 2.1 9.57 2.1 14.12 0a.09.09 0 01.1.01c.14.12.28.23.43.34a.1.1 0 01-.01.15c-.7.41-1.42.75-2.19 1.04a.09.09 0 00-.05.13c.38.81.8 1.59 1.32 2.33a.1.1 0 00.1.04 23.17 23.17 0 007.01-3.54.1.1 0 00.04-.07c.58-6.07-.97-11.84-4.13-16.84a.08.08 0 00-.04-.03zM9.36 15.91c-1.39 0-2.52-1.27-2.52-2.83s1.11-2.83 2.52-2.83c1.42 0 2.55 1.29 2.52 2.83 0 1.56-1.11 2.83-2.52 2.83zm9.32 0c-1.39 0-2.52-1.27-2.52-2.83s1.11-2.83 2.52-2.83c1.42 0 2.55 1.29 2.52 2.83 0 1.56-1.1 2.83-2.52 2.83z",
|
|
250
|
-
fill: "#ffffff"
|
|
251
|
-
}
|
|
252
|
-
) });
|
|
253
|
-
}
|
|
254
|
-
function XpLevelIcon() {
|
|
255
|
-
return /* @__PURE__ */ jsxs("svg", { width: "26", height: "26", viewBox: "0 0 26 26", fill: "none", children: [
|
|
256
|
-
/* @__PURE__ */ jsx(
|
|
257
|
-
"path",
|
|
258
|
-
{
|
|
259
|
-
d: "M13 2L15.9 8.9L23 9.5L17.5 14.4L19.1 21.5L13 17.8L6.9 21.5L8.5 14.4L3 9.5L10.1 8.9L13 2Z",
|
|
260
|
-
fill: "url(#xp-gradient)",
|
|
261
|
-
stroke: "#F59E0B",
|
|
262
|
-
strokeWidth: "1.5",
|
|
263
|
-
strokeLinejoin: "round"
|
|
264
|
-
}
|
|
265
|
-
),
|
|
266
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "xp-gradient", x1: "13", y1: "2", x2: "13", y2: "21.5", gradientUnits: "userSpaceOnUse", children: [
|
|
267
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#FDE68A" }),
|
|
268
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#F59E0B" })
|
|
269
|
-
] }) })
|
|
270
|
-
] });
|
|
271
|
-
}
|
|
272
|
-
function PointsIcon() {
|
|
273
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
|
|
274
|
-
/* @__PURE__ */ jsx(
|
|
275
|
-
"path",
|
|
276
|
-
{
|
|
277
|
-
d: "M12 2L14.4 8.6L21.5 9.2L16.2 13.8L17.8 20.8L12 17.1L6.2 20.8L7.8 13.8L2.5 9.2L9.6 8.6L12 2Z",
|
|
278
|
-
fill: "url(#points-gradient)"
|
|
279
|
-
}
|
|
280
|
-
),
|
|
281
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "points-gradient", x1: "12", y1: "2", x2: "12", y2: "20.8", gradientUnits: "userSpaceOnUse", children: [
|
|
282
|
-
/* @__PURE__ */ jsx("stop", { stopColor: "#A78BFA" }),
|
|
283
|
-
/* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#7C3AED" })
|
|
284
|
-
] }) })
|
|
285
|
-
] });
|
|
286
|
-
}
|
|
287
|
-
function DefaultIcon({
|
|
288
|
-
type
|
|
289
|
-
}) {
|
|
290
|
-
switch (type) {
|
|
291
|
-
case UserCenterRewardCardType.Token:
|
|
292
|
-
return /* @__PURE__ */ jsx(TokenIcon, {});
|
|
293
|
-
case UserCenterRewardCardType.Nft:
|
|
294
|
-
return /* @__PURE__ */ jsx(NftIcon, {});
|
|
295
|
-
case UserCenterRewardCardType.Whitelist:
|
|
296
|
-
return /* @__PURE__ */ jsx(WhitelistIcon, {});
|
|
297
|
-
case UserCenterRewardCardType.DiscordRole:
|
|
298
|
-
return /* @__PURE__ */ jsx(DiscordRoleIcon, {});
|
|
299
|
-
case UserCenterRewardCardType.Points:
|
|
300
|
-
return /* @__PURE__ */ jsx(PointsIcon, {});
|
|
301
|
-
case UserCenterRewardCardType.XpLevel:
|
|
302
|
-
return /* @__PURE__ */ jsx(XpLevelIcon, {});
|
|
303
|
-
default:
|
|
304
|
-
return /* @__PURE__ */ jsx(PointsIcon, {});
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
function needsLightBackground(type) {
|
|
308
|
-
return type === UserCenterRewardCardType.Whitelist;
|
|
309
|
-
}
|
|
310
|
-
function AssetCard({
|
|
311
|
-
type,
|
|
312
|
-
value,
|
|
313
|
-
selected = false,
|
|
314
|
-
onClick,
|
|
315
|
-
messages,
|
|
316
|
-
pointsData,
|
|
317
|
-
xpLevelData
|
|
318
|
-
}) {
|
|
319
|
-
const title = getCardTitle(type, messages, pointsData, xpLevelData);
|
|
320
|
-
const iconUrl = getCardIconUrl(type, pointsData);
|
|
321
|
-
const iconClassName = `taskon-asset-card__icon${needsLightBackground(type) ? " taskon-asset-card__icon--light" : ""}`;
|
|
322
|
-
return /* @__PURE__ */ jsxs(
|
|
323
|
-
"button",
|
|
324
|
-
{
|
|
325
|
-
type: "button",
|
|
326
|
-
className: `taskon-asset-card ${selected ? "taskon-asset-card--selected" : ""}`,
|
|
327
|
-
onClick,
|
|
328
|
-
"aria-pressed": selected,
|
|
329
|
-
children: [
|
|
330
|
-
/* @__PURE__ */ jsx("div", { className: iconClassName, children: iconUrl ? /* @__PURE__ */ jsx("img", { src: iconUrl, alt: title, className: "taskon-asset-card__icon-img" }) : /* @__PURE__ */ jsx(DefaultIcon, { type }) }),
|
|
331
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-asset-card__content", children: [
|
|
332
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-asset-card__title", children: title }),
|
|
333
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-asset-card__value", children: value })
|
|
334
|
-
] })
|
|
335
|
-
]
|
|
336
|
-
}
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
function AssetCarousel({
|
|
340
|
-
cards,
|
|
341
|
-
selectedCard,
|
|
342
|
-
selectedPointsId,
|
|
343
|
-
onSelectCard,
|
|
344
|
-
messages
|
|
345
|
-
}) {
|
|
346
|
-
const containerRef = useRef(null);
|
|
347
|
-
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
|
348
|
-
const [showRightArrow, setShowRightArrow] = useState(false);
|
|
349
|
-
const visibleCards = cards.filter((card) => card.visible);
|
|
350
|
-
const checkScrollArrows = useCallback(() => {
|
|
351
|
-
const container = containerRef.current;
|
|
352
|
-
if (!container) return;
|
|
353
|
-
const { scrollLeft, scrollWidth, clientWidth } = container;
|
|
354
|
-
setShowLeftArrow(scrollLeft > 0);
|
|
355
|
-
setShowRightArrow(scrollLeft + clientWidth < scrollWidth - 1);
|
|
356
|
-
}, []);
|
|
357
|
-
useCallback(
|
|
358
|
-
(direction) => {
|
|
359
|
-
const container = containerRef.current;
|
|
360
|
-
if (!container) return;
|
|
361
|
-
const scrollAmount = 200;
|
|
362
|
-
const newScrollLeft = direction === "left" ? container.scrollLeft - scrollAmount : container.scrollLeft + scrollAmount;
|
|
363
|
-
container.scrollTo({
|
|
364
|
-
left: newScrollLeft,
|
|
365
|
-
behavior: "smooth"
|
|
366
|
-
});
|
|
367
|
-
},
|
|
368
|
-
[]
|
|
369
|
-
);
|
|
370
|
-
const isCardSelected = useCallback(
|
|
371
|
-
(card) => {
|
|
372
|
-
if (selectedCard !== card.type) return false;
|
|
373
|
-
if (card.type === "Points" && card.pointsData) {
|
|
374
|
-
return selectedPointsId === card.pointsData.points_id;
|
|
375
|
-
}
|
|
376
|
-
return true;
|
|
377
|
-
},
|
|
378
|
-
[selectedCard, selectedPointsId]
|
|
379
|
-
);
|
|
380
|
-
useEffect(() => {
|
|
381
|
-
const container = containerRef.current;
|
|
382
|
-
if (!container) return;
|
|
383
|
-
checkScrollArrows();
|
|
384
|
-
container.addEventListener("scroll", checkScrollArrows);
|
|
385
|
-
window.addEventListener("resize", checkScrollArrows);
|
|
386
|
-
return () => {
|
|
387
|
-
container.removeEventListener("scroll", checkScrollArrows);
|
|
388
|
-
window.removeEventListener("resize", checkScrollArrows);
|
|
389
|
-
};
|
|
390
|
-
}, [checkScrollArrows, visibleCards]);
|
|
391
|
-
if (visibleCards.length === 0) {
|
|
392
|
-
return /* @__PURE__ */ jsx("div", { className: "taskon-asset-carousel--empty" });
|
|
393
|
-
}
|
|
394
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-asset-carousel", children: [
|
|
395
|
-
/* @__PURE__ */ jsx("h3", { className: "taskon-asset-carousel__title", children: messages.sectionYouHaveEarned ?? "You have earned" }),
|
|
396
|
-
/* @__PURE__ */ jsx("div", { ref: containerRef, className: "taskon-asset-carousel__container", children: visibleCards.map((card, index) => {
|
|
397
|
-
var _a;
|
|
398
|
-
return /* @__PURE__ */ jsx(
|
|
399
|
-
AssetCard,
|
|
400
|
-
{
|
|
401
|
-
type: card.type,
|
|
402
|
-
value: card.value,
|
|
403
|
-
selected: isCardSelected(card),
|
|
404
|
-
onClick: () => {
|
|
405
|
-
var _a2;
|
|
406
|
-
return onSelectCard(card.type, (_a2 = card.pointsData) == null ? void 0 : _a2.points_id);
|
|
407
|
-
},
|
|
408
|
-
messages,
|
|
409
|
-
pointsData: card.pointsData,
|
|
410
|
-
xpLevelData: card.xpLevelData
|
|
411
|
-
},
|
|
412
|
-
`${card.type}-${((_a = card.pointsData) == null ? void 0 : _a.points_id) ?? index}`
|
|
413
|
-
);
|
|
414
|
-
}) })
|
|
415
|
-
] });
|
|
416
|
-
}
|
|
417
|
-
function ProgressBar({
|
|
418
|
-
value,
|
|
419
|
-
max,
|
|
420
|
-
showPercent = false,
|
|
421
|
-
showValues = false,
|
|
422
|
-
height = 8,
|
|
423
|
-
className = "",
|
|
424
|
-
color,
|
|
425
|
-
backgroundColor
|
|
426
|
-
}) {
|
|
427
|
-
const percent = max > 0 ? Math.min(100, Math.max(0, value / max * 100)) : 0;
|
|
428
|
-
const formatValue = (val) => {
|
|
429
|
-
if (val >= 1e6) {
|
|
430
|
-
return `${(val / 1e6).toFixed(1)}M`;
|
|
431
|
-
}
|
|
432
|
-
if (val >= 1e3) {
|
|
433
|
-
return `${(val / 1e3).toFixed(1)}K`;
|
|
434
|
-
}
|
|
435
|
-
return val.toLocaleString();
|
|
436
|
-
};
|
|
437
|
-
const containerStyle = {
|
|
438
|
-
height: `${height}px`,
|
|
439
|
-
...backgroundColor && { backgroundColor }
|
|
440
|
-
};
|
|
441
|
-
const fillStyle = {
|
|
442
|
-
width: `${percent}%`,
|
|
443
|
-
...color && { backgroundColor: color }
|
|
444
|
-
};
|
|
445
|
-
return /* @__PURE__ */ jsxs("div", { className: `taskon-progress-bar ${className}`, children: [
|
|
446
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-progress-bar__container", style: containerStyle, children: /* @__PURE__ */ jsx("div", { className: "taskon-progress-bar__fill", style: fillStyle }) }),
|
|
447
|
-
(showPercent || showValues) && /* @__PURE__ */ jsxs("div", { className: "taskon-progress-bar__info", children: [
|
|
448
|
-
showValues && /* @__PURE__ */ jsxs("span", { className: "taskon-progress-bar__values", children: [
|
|
449
|
-
formatValue(value),
|
|
450
|
-
" / ",
|
|
451
|
-
formatValue(max)
|
|
452
|
-
] }),
|
|
453
|
-
showPercent && /* @__PURE__ */ jsxs("span", { className: "taskon-progress-bar__percent", children: [
|
|
454
|
-
percent.toFixed(0),
|
|
455
|
-
"%"
|
|
456
|
-
] })
|
|
457
|
-
] })
|
|
458
|
-
] });
|
|
459
|
-
}
|
|
460
|
-
function formatNumber(val) {
|
|
461
|
-
if (Math.abs(val) >= 1e6) {
|
|
462
|
-
return `${(val / 1e6).toFixed(1)}M`;
|
|
463
|
-
}
|
|
464
|
-
if (Math.abs(val) >= 1e3) {
|
|
465
|
-
return `${(val / 1e3).toFixed(1)}K`;
|
|
466
|
-
}
|
|
467
|
-
return val.toLocaleString();
|
|
468
|
-
}
|
|
469
|
-
function XpLevelCard({
|
|
470
|
-
xpData,
|
|
471
|
-
historyData,
|
|
472
|
-
historyLoading,
|
|
473
|
-
historyError,
|
|
474
|
-
pagination,
|
|
475
|
-
messages,
|
|
476
|
-
className = ""
|
|
477
|
-
}) {
|
|
478
|
-
var _a;
|
|
479
|
-
const { level, currentXp, nextLevelXp, totalXp } = xpData;
|
|
480
|
-
const pointsName = ((_a = xpData.pointsName) == null ? void 0 : _a.trim()) || "XP";
|
|
481
|
-
const xpToNext = Math.max(0, nextLevelXp - currentXp);
|
|
482
|
-
const columns = [
|
|
483
|
-
{
|
|
484
|
-
key: "detail",
|
|
485
|
-
title: messages.columnDetail,
|
|
486
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-points-list__name", children: row.name })
|
|
487
|
-
},
|
|
488
|
-
{
|
|
489
|
-
key: "time",
|
|
490
|
-
title: messages.columnTime,
|
|
491
|
-
width: 160,
|
|
492
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-points-list__time", children: formatDateTime(row.receive_time) })
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
key: "amount",
|
|
496
|
-
title: `${messages.columnAmount} (${pointsName})`,
|
|
497
|
-
width: 160,
|
|
498
|
-
align: "right",
|
|
499
|
-
render: (_, row) => {
|
|
500
|
-
const isPositive = row.points.amount >= 0;
|
|
501
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-points-list__amount-cell", children: [
|
|
502
|
-
row.points.points_icon && /* @__PURE__ */ jsx(
|
|
503
|
-
"img",
|
|
504
|
-
{
|
|
505
|
-
src: row.points.points_icon,
|
|
506
|
-
alt: "",
|
|
507
|
-
className: "taskon-points-list__amount-icon"
|
|
508
|
-
}
|
|
509
|
-
),
|
|
510
|
-
/* @__PURE__ */ jsxs(
|
|
511
|
-
"span",
|
|
512
|
-
{
|
|
513
|
-
className: `taskon-points-list__amount-value ${isPositive ? "taskon-points-list__amount-value--positive" : "taskon-points-list__amount-value--negative"}`,
|
|
514
|
-
children: [
|
|
515
|
-
isPositive ? "+" : "",
|
|
516
|
-
formatNumber(row.points.amount)
|
|
517
|
-
]
|
|
518
|
-
}
|
|
519
|
-
)
|
|
520
|
-
] });
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
];
|
|
524
|
-
return /* @__PURE__ */ jsxs("div", { className: `taskon-xp-level-card ${className}`, children: [
|
|
525
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__header", children: [
|
|
526
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__level", children: [
|
|
527
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-xp-level-card__level-badge", children: level }),
|
|
528
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__level-info", children: [
|
|
529
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-xp-level-card__level-label", children: messages.level }),
|
|
530
|
-
/* @__PURE__ */ jsxs("span", { className: "taskon-xp-level-card__level-value", children: [
|
|
531
|
-
messages.level,
|
|
532
|
-
" ",
|
|
533
|
-
level
|
|
534
|
-
] })
|
|
535
|
-
] })
|
|
536
|
-
] }),
|
|
537
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__xp", children: [
|
|
538
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-xp-level-card__xp-label", children: messages.totalXp }),
|
|
539
|
-
/* @__PURE__ */ jsxs("span", { className: "taskon-xp-level-card__xp-value", children: [
|
|
540
|
-
formatNumber(totalXp),
|
|
541
|
-
" ",
|
|
542
|
-
pointsName
|
|
543
|
-
] })
|
|
544
|
-
] })
|
|
545
|
-
] }),
|
|
546
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__progress", children: [
|
|
547
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__progress-label", children: [
|
|
548
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
549
|
-
formatNumber(currentXp),
|
|
550
|
-
" / ",
|
|
551
|
-
formatNumber(nextLevelXp),
|
|
552
|
-
" ",
|
|
553
|
-
pointsName
|
|
554
|
-
] }),
|
|
555
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
556
|
-
messages.xpToNextLevel,
|
|
557
|
-
": ",
|
|
558
|
-
formatNumber(xpToNext),
|
|
559
|
-
" ",
|
|
560
|
-
pointsName
|
|
561
|
-
] })
|
|
562
|
-
] }),
|
|
563
|
-
/* @__PURE__ */ jsx(ProgressBar, { value: currentXp, max: nextLevelXp, height: 10 })
|
|
564
|
-
] }),
|
|
565
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-xp-level-card__history", children: [
|
|
566
|
-
/* @__PURE__ */ jsx("h4", { className: "taskon-xp-level-card__history-title", children: messages.xpHistory }),
|
|
567
|
-
historyLoading && historyData.length === 0 && /* @__PURE__ */ jsx(LoadingState, { message: messages.loading }),
|
|
568
|
-
historyError && historyData.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: historyError.message }) }),
|
|
569
|
-
!historyLoading && !historyError && historyData.length === 0 && /* @__PURE__ */ jsx(EmptyState, { message: messages.noData }),
|
|
570
|
-
historyData.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
571
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-xp-level-card__table-wrap", children: /* @__PURE__ */ jsx(
|
|
572
|
-
Table,
|
|
573
|
-
{
|
|
574
|
-
columns,
|
|
575
|
-
data: historyData,
|
|
576
|
-
rowConfig: {
|
|
577
|
-
getRowKey: (row, index) => `${row.campaign_id ?? row.task_id ?? "item"}-${row.receive_time}-${index}`
|
|
578
|
-
},
|
|
579
|
-
loading: historyLoading && historyData.length > 0,
|
|
580
|
-
loadingText: messages.loading,
|
|
581
|
-
empty: {
|
|
582
|
-
title: messages.noData
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
) }),
|
|
586
|
-
pagination.totalPages > 1 && /* @__PURE__ */ jsx(
|
|
587
|
-
Pagination,
|
|
588
|
-
{
|
|
589
|
-
page: pagination.page,
|
|
590
|
-
totalPages: pagination.totalPages,
|
|
591
|
-
onPrevious: pagination.goToPrevious,
|
|
592
|
-
onNext: pagination.goToNext,
|
|
593
|
-
hasPrevious: pagination.hasPrevious,
|
|
594
|
-
hasNext: pagination.hasNext,
|
|
595
|
-
messages
|
|
596
|
-
}
|
|
597
|
-
)
|
|
598
|
-
] })
|
|
599
|
-
] })
|
|
600
|
-
] });
|
|
601
|
-
}
|
|
602
|
-
function WhitelistTable({
|
|
603
|
-
data,
|
|
604
|
-
loading,
|
|
605
|
-
error,
|
|
606
|
-
pagination,
|
|
607
|
-
messages
|
|
608
|
-
}) {
|
|
609
|
-
if (loading && data.length === 0) {
|
|
610
|
-
return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
|
|
611
|
-
}
|
|
612
|
-
if (error && data.length === 0) {
|
|
613
|
-
return /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: error.message }) });
|
|
614
|
-
}
|
|
615
|
-
if (!loading && data.length === 0) {
|
|
616
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.noData });
|
|
617
|
-
}
|
|
618
|
-
const columns = [
|
|
619
|
-
{
|
|
620
|
-
key: "whitelist",
|
|
621
|
-
title: messages.columnWhitelist,
|
|
622
|
-
width: 100,
|
|
623
|
-
render: (_, row) => {
|
|
624
|
-
const wlValue = row.reward_value;
|
|
625
|
-
return /* @__PURE__ */ jsx(
|
|
626
|
-
AssetImage,
|
|
627
|
-
{
|
|
628
|
-
src: wlValue.nft_image,
|
|
629
|
-
chain: wlValue.chain,
|
|
630
|
-
alt: "Whitelist",
|
|
631
|
-
size: 60,
|
|
632
|
-
useWhitelistDefault: !wlValue.nft_image
|
|
633
|
-
}
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
},
|
|
637
|
-
{
|
|
638
|
-
key: "detail",
|
|
639
|
-
title: messages.columnDetail,
|
|
640
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__campaign-name", children: row.campaign_name })
|
|
641
|
-
},
|
|
642
|
-
{
|
|
643
|
-
key: "time",
|
|
644
|
-
title: messages.columnTime,
|
|
645
|
-
width: 160,
|
|
646
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__time", children: formatDateTime(row.reward_time) })
|
|
647
|
-
},
|
|
648
|
-
{
|
|
649
|
-
key: "status",
|
|
650
|
-
title: messages.columnStatus,
|
|
651
|
-
width: 120,
|
|
652
|
-
align: "right",
|
|
653
|
-
render: () => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__manual-drop", children: messages.manualDrop })
|
|
654
|
-
}
|
|
655
|
-
];
|
|
656
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-reward-table", children: [
|
|
657
|
-
/* @__PURE__ */ jsx(
|
|
658
|
-
Table,
|
|
659
|
-
{
|
|
660
|
-
columns,
|
|
661
|
-
data,
|
|
662
|
-
rowConfig: {
|
|
663
|
-
getRowKey: (row, index) => `${row.campaign_id}-${row.reward_time}-${index}`
|
|
664
|
-
},
|
|
665
|
-
loading: loading && data.length > 0,
|
|
666
|
-
loadingText: messages.loading,
|
|
667
|
-
empty: {
|
|
668
|
-
title: messages.noData
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
),
|
|
672
|
-
pagination.totalPages > 1 && /* @__PURE__ */ jsx(
|
|
673
|
-
Pagination,
|
|
674
|
-
{
|
|
675
|
-
page: pagination.page,
|
|
676
|
-
totalPages: pagination.totalPages,
|
|
677
|
-
onPrevious: pagination.goToPrevious,
|
|
678
|
-
onNext: pagination.goToNext,
|
|
679
|
-
hasPrevious: pagination.hasPrevious,
|
|
680
|
-
hasNext: pagination.hasNext,
|
|
681
|
-
messages
|
|
682
|
-
}
|
|
683
|
-
)
|
|
684
|
-
] });
|
|
685
|
-
}
|
|
686
|
-
function DiscordRoleTable({
|
|
687
|
-
data,
|
|
688
|
-
loading,
|
|
689
|
-
error,
|
|
690
|
-
pagination,
|
|
691
|
-
messages
|
|
692
|
-
}) {
|
|
693
|
-
if (loading && data.length === 0) {
|
|
694
|
-
return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
|
|
695
|
-
}
|
|
696
|
-
if (error && data.length === 0) {
|
|
697
|
-
return /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: error.message }) });
|
|
698
|
-
}
|
|
699
|
-
if (!loading && data.length === 0) {
|
|
700
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.noData });
|
|
701
|
-
}
|
|
702
|
-
const columns = [
|
|
703
|
-
{
|
|
704
|
-
key: "discordRole",
|
|
705
|
-
title: messages.columnDiscordRole,
|
|
706
|
-
width: 160,
|
|
707
|
-
render: (_, row) => {
|
|
708
|
-
const dcValue = row.reward_value;
|
|
709
|
-
return /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__role-name", children: dcValue.role_name });
|
|
710
|
-
}
|
|
711
|
-
},
|
|
712
|
-
{
|
|
713
|
-
key: "detail",
|
|
714
|
-
title: messages.columnDetail,
|
|
715
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__campaign-name", children: row.milestone_name || row.campaign_name })
|
|
716
|
-
},
|
|
717
|
-
{
|
|
718
|
-
key: "time",
|
|
719
|
-
title: messages.columnTime,
|
|
720
|
-
width: 160,
|
|
721
|
-
render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__time", children: formatDateTime(row.reward_time) })
|
|
722
|
-
},
|
|
723
|
-
{
|
|
724
|
-
key: "status",
|
|
725
|
-
title: messages.columnStatus,
|
|
726
|
-
width: 120,
|
|
727
|
-
align: "right",
|
|
728
|
-
render: () => /* @__PURE__ */ jsx("span", { className: "taskon-reward-table__manual-drop", children: messages.manualDrop })
|
|
729
|
-
}
|
|
730
|
-
];
|
|
731
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-reward-table", children: [
|
|
732
|
-
/* @__PURE__ */ jsx(
|
|
733
|
-
Table,
|
|
734
|
-
{
|
|
735
|
-
columns,
|
|
736
|
-
data,
|
|
737
|
-
rowConfig: {
|
|
738
|
-
getRowKey: (row, index) => `${row.campaign_id}-${row.reward_time}-${index}`
|
|
739
|
-
},
|
|
740
|
-
loading: loading && data.length > 0,
|
|
741
|
-
loadingText: messages.loading,
|
|
742
|
-
empty: {
|
|
743
|
-
title: messages.noData
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
),
|
|
747
|
-
pagination.totalPages > 1 && /* @__PURE__ */ jsx(
|
|
748
|
-
Pagination,
|
|
749
|
-
{
|
|
750
|
-
page: pagination.page,
|
|
751
|
-
totalPages: pagination.totalPages,
|
|
752
|
-
onPrevious: pagination.goToPrevious,
|
|
753
|
-
onNext: pagination.goToNext,
|
|
754
|
-
hasPrevious: pagination.hasPrevious,
|
|
755
|
-
hasNext: pagination.hasNext,
|
|
756
|
-
messages
|
|
757
|
-
}
|
|
758
|
-
)
|
|
759
|
-
] });
|
|
760
|
-
}
|
|
761
|
-
function useActivityHistory(options = {}) {
|
|
762
|
-
const {
|
|
763
|
-
pageSize = USER_CENTER_PAGE_SIZE,
|
|
764
|
-
mode = "pagination",
|
|
765
|
-
autoLoad = true
|
|
766
|
-
} = options;
|
|
767
|
-
const { client } = useTaskOnContext();
|
|
768
|
-
const [data, setData] = useState([]);
|
|
769
|
-
const [total, setTotal] = useState(0);
|
|
770
|
-
const [loading, setLoading] = useState(false);
|
|
771
|
-
const [error, setError] = useState(null);
|
|
772
|
-
const isInitialLoad = useRef(true);
|
|
773
|
-
const lastFetchedPage = useRef(null);
|
|
774
|
-
const api = useMemo(() => {
|
|
775
|
-
if (!client) return null;
|
|
776
|
-
return createUserCenterApi(client);
|
|
777
|
-
}, [client]);
|
|
778
|
-
const pagination = usePagination({
|
|
779
|
-
total,
|
|
780
|
-
pageSize,
|
|
781
|
-
initialPage: 0,
|
|
782
|
-
// 使用 0-based 索引
|
|
783
|
-
mode
|
|
784
|
-
});
|
|
785
|
-
const fetchData = useCallback(
|
|
786
|
-
async (pageNo, append = false) => {
|
|
787
|
-
if (!api) {
|
|
788
|
-
setError(new Error("TaskOn client not initialized"));
|
|
789
|
-
return;
|
|
790
|
-
}
|
|
791
|
-
if (lastFetchedPage.current === pageNo && !append) {
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
setLoading(true);
|
|
795
|
-
setError(null);
|
|
796
|
-
lastFetchedPage.current = pageNo;
|
|
797
|
-
try {
|
|
798
|
-
const response = await api.getMyCampaignHistory({
|
|
799
|
-
page: {
|
|
800
|
-
page_no: pageNo,
|
|
801
|
-
// API 使用 0-based 索引
|
|
802
|
-
size: pageSize
|
|
803
|
-
}
|
|
804
|
-
});
|
|
805
|
-
if (append) {
|
|
806
|
-
setData((prev) => [...prev, ...response.data]);
|
|
807
|
-
} else {
|
|
808
|
-
setData(response.data);
|
|
809
|
-
}
|
|
810
|
-
setTotal(response.total);
|
|
811
|
-
} catch (err) {
|
|
812
|
-
setError(
|
|
813
|
-
err instanceof Error ? err : new Error("Failed to fetch activity history")
|
|
814
|
-
);
|
|
815
|
-
} finally {
|
|
816
|
-
setLoading(false);
|
|
817
|
-
}
|
|
818
|
-
},
|
|
819
|
-
[api, pageSize]
|
|
820
|
-
);
|
|
821
|
-
const refresh = useCallback(async () => {
|
|
822
|
-
pagination.goToPage(0);
|
|
823
|
-
setData([]);
|
|
824
|
-
lastFetchedPage.current = null;
|
|
825
|
-
await fetchData(0, false);
|
|
826
|
-
}, [fetchData, pagination]);
|
|
827
|
-
useEffect(() => {
|
|
828
|
-
if (autoLoad && isInitialLoad.current) {
|
|
829
|
-
isInitialLoad.current = false;
|
|
830
|
-
fetchData(0, false);
|
|
831
|
-
}
|
|
832
|
-
}, [autoLoad, fetchData]);
|
|
833
|
-
useEffect(() => {
|
|
834
|
-
if (isInitialLoad.current) {
|
|
835
|
-
return;
|
|
836
|
-
}
|
|
837
|
-
if (mode === "pagination") {
|
|
838
|
-
fetchData(pagination.page, false);
|
|
839
|
-
}
|
|
840
|
-
}, [mode, pagination.page, fetchData]);
|
|
841
|
-
useEffect(() => {
|
|
842
|
-
if (mode === "infinite" && pagination.loadedCount > pageSize) {
|
|
843
|
-
const nextPage = Math.ceil(pagination.loadedCount / pageSize) - 1;
|
|
844
|
-
fetchData(nextPage, true);
|
|
845
|
-
}
|
|
846
|
-
}, [mode, pagination.loadedCount, pageSize, fetchData]);
|
|
847
|
-
return {
|
|
848
|
-
data,
|
|
849
|
-
loading,
|
|
850
|
-
error,
|
|
851
|
-
total,
|
|
852
|
-
pagination,
|
|
853
|
-
refresh
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
function useUserRewards(options = {}) {
|
|
857
|
-
const { autoLoad = true } = options;
|
|
858
|
-
const { client } = useTaskOnContext();
|
|
859
|
-
const [rewards, setRewards] = useState(null);
|
|
860
|
-
const [userInfo, setUserInfo] = useState(null);
|
|
861
|
-
const [selectedCard, setSelectedCard] = useState(null);
|
|
862
|
-
const [loading, setLoading] = useState(false);
|
|
863
|
-
const [error, setError] = useState(null);
|
|
864
|
-
const api = useMemo(() => {
|
|
865
|
-
if (!client) return null;
|
|
866
|
-
return createUserCenterApi(client);
|
|
867
|
-
}, [client]);
|
|
868
|
-
const cards = useMemo(() => {
|
|
869
|
-
if (!rewards) return [];
|
|
870
|
-
return buildRewardCards(rewards, userInfo);
|
|
871
|
-
}, [rewards, userInfo]);
|
|
872
|
-
const fetchData = useCallback(async () => {
|
|
873
|
-
if (!api) {
|
|
874
|
-
setError(new Error("TaskOn client not initialized"));
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
|
-
setLoading(true);
|
|
878
|
-
setError(null);
|
|
879
|
-
try {
|
|
880
|
-
const [rewardsResponse, userInfoResponse] = await Promise.all([
|
|
881
|
-
api.getMyCommunityRewards({}),
|
|
882
|
-
api.getCUserInfo({})
|
|
883
|
-
]);
|
|
884
|
-
setRewards(rewardsResponse);
|
|
885
|
-
setUserInfo(userInfoResponse);
|
|
886
|
-
const builtCards = buildRewardCards(rewardsResponse, userInfoResponse);
|
|
887
|
-
const firstVisibleCard = builtCards.find((c) => c.visible);
|
|
888
|
-
if (firstVisibleCard && !selectedCard) {
|
|
889
|
-
setSelectedCard(firstVisibleCard.type);
|
|
890
|
-
}
|
|
891
|
-
} catch (err) {
|
|
892
|
-
setError(
|
|
893
|
-
err instanceof Error ? err : new Error("Failed to fetch rewards")
|
|
894
|
-
);
|
|
895
|
-
} finally {
|
|
896
|
-
setLoading(false);
|
|
897
|
-
}
|
|
898
|
-
}, [api, selectedCard]);
|
|
899
|
-
const selectCard = useCallback((type) => {
|
|
900
|
-
setSelectedCard(type);
|
|
901
|
-
}, []);
|
|
902
|
-
const refresh = useCallback(async () => {
|
|
903
|
-
await fetchData();
|
|
904
|
-
}, [fetchData]);
|
|
905
|
-
useEffect(() => {
|
|
906
|
-
if (autoLoad) {
|
|
907
|
-
fetchData();
|
|
908
|
-
}
|
|
909
|
-
}, [autoLoad, fetchData]);
|
|
910
|
-
return {
|
|
911
|
-
rewards,
|
|
912
|
-
userInfo,
|
|
913
|
-
cards,
|
|
914
|
-
selectedCard,
|
|
915
|
-
selectCard,
|
|
916
|
-
loading,
|
|
917
|
-
error,
|
|
918
|
-
refresh
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
function useFrozenAssets(options) {
|
|
922
|
-
const { tokenId, pageSize = USER_CENTER_PAGE_SIZE, autoLoad = true } = options;
|
|
923
|
-
const { client } = useTaskOnContext();
|
|
924
|
-
const [data, setData] = useState([]);
|
|
925
|
-
const [total, setTotal] = useState(0);
|
|
926
|
-
const [loading, setLoading] = useState(false);
|
|
927
|
-
const [error, setError] = useState(null);
|
|
928
|
-
const api = useMemo(() => {
|
|
929
|
-
if (!client) return null;
|
|
930
|
-
return createUserCenterApi(client);
|
|
931
|
-
}, [client]);
|
|
932
|
-
const pagination = usePagination({
|
|
933
|
-
total,
|
|
934
|
-
pageSize,
|
|
935
|
-
initialPage: 0,
|
|
936
|
-
mode: "pagination"
|
|
937
|
-
});
|
|
938
|
-
const skipNextPageEffectRef = useRef(false);
|
|
939
|
-
const fetchData = useCallback(
|
|
940
|
-
async (pageNo) => {
|
|
941
|
-
if (!api) {
|
|
942
|
-
setError(new Error("TaskOn client not initialized"));
|
|
943
|
-
return;
|
|
944
|
-
}
|
|
945
|
-
if (!tokenId) {
|
|
946
|
-
setError(new Error("Token ID is required"));
|
|
947
|
-
return;
|
|
948
|
-
}
|
|
949
|
-
setLoading(true);
|
|
950
|
-
setError(null);
|
|
951
|
-
try {
|
|
952
|
-
const response = await api.getLockedTokenList({
|
|
953
|
-
token_id: tokenId,
|
|
954
|
-
page: {
|
|
955
|
-
page_no: pageNo,
|
|
956
|
-
// API 使用 0-based 索引
|
|
957
|
-
size: pageSize
|
|
958
|
-
}
|
|
959
|
-
});
|
|
960
|
-
setData(response.data);
|
|
961
|
-
setTotal(response.total);
|
|
962
|
-
} catch (err) {
|
|
963
|
-
setError(
|
|
964
|
-
err instanceof Error ? err : new Error("Failed to fetch frozen assets")
|
|
965
|
-
);
|
|
966
|
-
} finally {
|
|
967
|
-
setLoading(false);
|
|
968
|
-
}
|
|
969
|
-
},
|
|
970
|
-
[api, tokenId, pageSize]
|
|
971
|
-
);
|
|
972
|
-
const refresh = useCallback(async () => {
|
|
973
|
-
if (autoLoad && pagination.page !== 0) {
|
|
974
|
-
skipNextPageEffectRef.current = true;
|
|
975
|
-
}
|
|
976
|
-
pagination.goToPage(0);
|
|
977
|
-
await fetchData(0);
|
|
978
|
-
}, [autoLoad, fetchData, pagination]);
|
|
979
|
-
const canResend = useCallback((item) => {
|
|
980
|
-
return item.type === "Withdraw" && Boolean(item.nonce) && Boolean(item.receiver_address);
|
|
981
|
-
}, []);
|
|
982
|
-
useEffect(() => {
|
|
983
|
-
if (!autoLoad || !tokenId) {
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
986
|
-
if (skipNextPageEffectRef.current) {
|
|
987
|
-
skipNextPageEffectRef.current = false;
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
|
-
fetchData(pagination.page);
|
|
991
|
-
}, [autoLoad, tokenId, pagination.page, fetchData]);
|
|
992
|
-
return {
|
|
993
|
-
data,
|
|
994
|
-
loading,
|
|
995
|
-
error,
|
|
996
|
-
total,
|
|
997
|
-
pagination,
|
|
998
|
-
refresh,
|
|
999
|
-
canResend
|
|
1000
|
-
};
|
|
1001
|
-
}
|
|
1002
|
-
const SNS_TYPE_MAP = {
|
|
1003
|
-
Twitter: "Twitter",
|
|
1004
|
-
Discord: "Discord",
|
|
1005
|
-
Telegram: "Telegram",
|
|
1006
|
-
Email: "Email",
|
|
1007
|
-
Reddit: "Reddit"
|
|
1008
|
-
};
|
|
1009
|
-
const CHAIN_TYPE_MAP = {
|
|
1010
|
-
evm: "evm",
|
|
1011
|
-
solana: "solana",
|
|
1012
|
-
sui: "sui",
|
|
1013
|
-
aptos: "aptos",
|
|
1014
|
-
btc: "btc",
|
|
1015
|
-
starknet: "starknet",
|
|
1016
|
-
tron: "tron",
|
|
1017
|
-
ton: "ton",
|
|
1018
|
-
nibiru: "nibiru",
|
|
1019
|
-
kaspa: "kaspa"
|
|
1020
|
-
};
|
|
1021
|
-
const ALL_SOCIAL_TYPES = [
|
|
1022
|
-
SnsType.Twitter,
|
|
1023
|
-
SnsType.Discord,
|
|
1024
|
-
SnsType.Telegram,
|
|
1025
|
-
SnsType.Email,
|
|
1026
|
-
SnsType.Reddit
|
|
1027
|
-
];
|
|
1028
|
-
const ALL_CHAIN_TYPES = [
|
|
1029
|
-
"evm",
|
|
1030
|
-
"solana",
|
|
1031
|
-
"sui",
|
|
1032
|
-
"aptos",
|
|
1033
|
-
"btc",
|
|
1034
|
-
"starknet",
|
|
1035
|
-
"tron",
|
|
1036
|
-
"ton",
|
|
1037
|
-
"nibiru",
|
|
1038
|
-
"kaspa"
|
|
1039
|
-
];
|
|
1040
|
-
function getSocialProfileUrl(snsType, username) {
|
|
1041
|
-
switch (snsType) {
|
|
1042
|
-
case SnsType.Twitter:
|
|
1043
|
-
return `https://twitter.com/${username}`;
|
|
1044
|
-
case SnsType.Discord:
|
|
1045
|
-
return null;
|
|
1046
|
-
case SnsType.Telegram:
|
|
1047
|
-
return `https://t.me/${username}`;
|
|
1048
|
-
case SnsType.Reddit:
|
|
1049
|
-
return `https://reddit.com/user/${username}`;
|
|
1050
|
-
case SnsType.Email:
|
|
1051
|
-
return null;
|
|
1052
|
-
default:
|
|
1053
|
-
return null;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
function useIdentityData() {
|
|
1057
|
-
const { userInfo } = useTaskOnContext();
|
|
1058
|
-
const rawSns = (userInfo == null ? void 0 : userInfo.sns) ?? [];
|
|
1059
|
-
const rawAddresses = (userInfo == null ? void 0 : userInfo.address) ?? [];
|
|
1060
|
-
const isLoaded = userInfo !== null;
|
|
1061
|
-
const socialAccounts = useMemo(() => {
|
|
1062
|
-
return ALL_SOCIAL_TYPES.map((snsType) => {
|
|
1063
|
-
const boundAccount = rawSns.find((s) => s.sns_type === snsType);
|
|
1064
|
-
const accountType = SNS_TYPE_MAP[snsType];
|
|
1065
|
-
return {
|
|
1066
|
-
accountType: accountType ?? snsType,
|
|
1067
|
-
snsType,
|
|
1068
|
-
isBound: !!boundAccount,
|
|
1069
|
-
account: boundAccount ?? null,
|
|
1070
|
-
profileUrl: boundAccount ? getSocialProfileUrl(snsType, boundAccount.sns_user_name) : null
|
|
1071
|
-
};
|
|
1072
|
-
});
|
|
1073
|
-
}, [rawSns]);
|
|
1074
|
-
const walletAddresses = useMemo(() => {
|
|
1075
|
-
return ALL_CHAIN_TYPES.map((chainType) => {
|
|
1076
|
-
const boundAddress = rawAddresses.find((a) => a.chain_type === chainType);
|
|
1077
|
-
const widgetChainType = CHAIN_TYPE_MAP[chainType];
|
|
1078
|
-
return {
|
|
1079
|
-
chainType: widgetChainType ?? chainType,
|
|
1080
|
-
coreChainType: chainType,
|
|
1081
|
-
isBound: !!boundAddress,
|
|
1082
|
-
address: boundAddress ?? null,
|
|
1083
|
-
isPrimary: (boundAddress == null ? void 0 : boundAddress.is_primary) ?? false,
|
|
1084
|
-
// 暂时没有 KYC 信息,后续可扩展
|
|
1085
|
-
isKycVerified: void 0
|
|
1086
|
-
};
|
|
1087
|
-
});
|
|
1088
|
-
}, [rawAddresses]);
|
|
1089
|
-
const totalBoundCount = useMemo(() => {
|
|
1090
|
-
const boundSocialCount = socialAccounts.filter((a) => a.isBound).length;
|
|
1091
|
-
const boundWalletCount = walletAddresses.filter((a) => a.isBound).length;
|
|
1092
|
-
return boundSocialCount + boundWalletCount;
|
|
1093
|
-
}, [socialAccounts, walletAddresses]);
|
|
1094
|
-
return {
|
|
1095
|
-
socialAccounts,
|
|
1096
|
-
walletAddresses,
|
|
1097
|
-
rawSns,
|
|
1098
|
-
rawAddresses,
|
|
1099
|
-
isLoaded,
|
|
1100
|
-
totalBoundCount
|
|
1101
|
-
};
|
|
1102
|
-
}
|
|
1103
|
-
function useUnbindSocial(options = {}) {
|
|
1104
|
-
const { onUnbindSuccess, onUnbindError } = options;
|
|
1105
|
-
const { client, refreshUserInfo } = useTaskOnContext();
|
|
1106
|
-
const [unbindStatus, setUnbindStatus] = useState("idle");
|
|
1107
|
-
const [error, setError] = useState(null);
|
|
1108
|
-
const [processingType, setProcessingType] = useState(null);
|
|
1109
|
-
const api = useMemo(() => {
|
|
1110
|
-
if (!client) return null;
|
|
1111
|
-
return createUserApi(client);
|
|
1112
|
-
}, [client]);
|
|
1113
|
-
const unbind = useCallback(
|
|
1114
|
-
async (snsId, type) => {
|
|
1115
|
-
if (!api) {
|
|
1116
|
-
const err = new Error("TaskOn client not initialized");
|
|
1117
|
-
setError(err);
|
|
1118
|
-
onUnbindError == null ? void 0 : onUnbindError(err);
|
|
1119
|
-
return false;
|
|
1120
|
-
}
|
|
1121
|
-
setProcessingType(type);
|
|
1122
|
-
setUnbindStatus("loading");
|
|
1123
|
-
setError(null);
|
|
1124
|
-
try {
|
|
1125
|
-
const result = await api.unbindSNS({
|
|
1126
|
-
sns_id: snsId,
|
|
1127
|
-
sns_type: type
|
|
1128
|
-
});
|
|
1129
|
-
if (result) {
|
|
1130
|
-
await refreshUserInfo();
|
|
1131
|
-
setUnbindStatus("success");
|
|
1132
|
-
onUnbindSuccess == null ? void 0 : onUnbindSuccess();
|
|
1133
|
-
return true;
|
|
1134
|
-
} else {
|
|
1135
|
-
const err = new Error("Unbind failed");
|
|
1136
|
-
setUnbindStatus("error");
|
|
1137
|
-
setError(err);
|
|
1138
|
-
onUnbindError == null ? void 0 : onUnbindError(err);
|
|
1139
|
-
return false;
|
|
1140
|
-
}
|
|
1141
|
-
} catch (err) {
|
|
1142
|
-
const error2 = err instanceof Error ? err : new Error("Unbind failed");
|
|
1143
|
-
setUnbindStatus("error");
|
|
1144
|
-
setError(error2);
|
|
1145
|
-
onUnbindError == null ? void 0 : onUnbindError(error2);
|
|
1146
|
-
return false;
|
|
1147
|
-
} finally {
|
|
1148
|
-
setProcessingType(null);
|
|
1149
|
-
}
|
|
1150
|
-
},
|
|
1151
|
-
[api, refreshUserInfo, onUnbindSuccess, onUnbindError]
|
|
1152
|
-
);
|
|
1153
|
-
const reset = useCallback(() => {
|
|
1154
|
-
setUnbindStatus("idle");
|
|
1155
|
-
setError(null);
|
|
1156
|
-
setProcessingType(null);
|
|
1157
|
-
}, []);
|
|
1158
|
-
return {
|
|
1159
|
-
unbindStatus,
|
|
1160
|
-
error,
|
|
1161
|
-
processingType,
|
|
1162
|
-
unbind,
|
|
1163
|
-
reset
|
|
1164
|
-
};
|
|
1165
|
-
}
|
|
1166
|
-
const COUNTDOWN_SECONDS = 60;
|
|
1167
|
-
const EMAIL_REGEX$1 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1168
|
-
const SNS_BIND_DUPLICATE_ERROR = 10016;
|
|
1169
|
-
const INVALID_EMAIL_VERIFY_CODE = 10017;
|
|
1170
|
-
function useBindEmail(options = {}) {
|
|
1171
|
-
const { onSendCodeSuccess, onSendCodeError, onBindSuccess, onBindError } = options;
|
|
1172
|
-
const { client, refreshUserInfo } = useTaskOnContext();
|
|
1173
|
-
const [status, setStatus] = useState("idle");
|
|
1174
|
-
const [countdown, setCountdown] = useState(0);
|
|
1175
|
-
const [error, setError] = useState(null);
|
|
1176
|
-
const [isEmailDuplicate, setIsEmailDuplicate] = useState(false);
|
|
1177
|
-
const [isCodeInvalid, setIsCodeInvalid] = useState(false);
|
|
1178
|
-
const [email, setEmail] = useState("");
|
|
1179
|
-
const countdownTimerRef = useRef(null);
|
|
1180
|
-
const api = useMemo(() => {
|
|
1181
|
-
if (!client) return null;
|
|
1182
|
-
return createUserApi(client);
|
|
1183
|
-
}, [client]);
|
|
1184
|
-
const startCountdown = useCallback(() => {
|
|
1185
|
-
setCountdown(COUNTDOWN_SECONDS);
|
|
1186
|
-
countdownTimerRef.current = setInterval(() => {
|
|
1187
|
-
setCountdown((prev) => {
|
|
1188
|
-
if (prev <= 1) {
|
|
1189
|
-
if (countdownTimerRef.current) {
|
|
1190
|
-
clearInterval(countdownTimerRef.current);
|
|
1191
|
-
countdownTimerRef.current = null;
|
|
1192
|
-
}
|
|
1193
|
-
return 0;
|
|
1194
|
-
}
|
|
1195
|
-
return prev - 1;
|
|
1196
|
-
});
|
|
1197
|
-
}, 1e3);
|
|
1198
|
-
}, []);
|
|
1199
|
-
const stopCountdown = useCallback(() => {
|
|
1200
|
-
if (countdownTimerRef.current) {
|
|
1201
|
-
clearInterval(countdownTimerRef.current);
|
|
1202
|
-
countdownTimerRef.current = null;
|
|
1203
|
-
}
|
|
1204
|
-
setCountdown(0);
|
|
1205
|
-
}, []);
|
|
1206
|
-
useEffect(() => {
|
|
1207
|
-
return () => {
|
|
1208
|
-
if (countdownTimerRef.current) {
|
|
1209
|
-
clearInterval(countdownTimerRef.current);
|
|
1210
|
-
}
|
|
1211
|
-
};
|
|
1212
|
-
}, []);
|
|
1213
|
-
const open = useCallback(() => {
|
|
1214
|
-
setStatus("inputEmail");
|
|
1215
|
-
setError(null);
|
|
1216
|
-
setIsEmailDuplicate(false);
|
|
1217
|
-
setIsCodeInvalid(false);
|
|
1218
|
-
}, []);
|
|
1219
|
-
const close = useCallback(() => {
|
|
1220
|
-
setStatus("idle");
|
|
1221
|
-
setError(null);
|
|
1222
|
-
setIsEmailDuplicate(false);
|
|
1223
|
-
setIsCodeInvalid(false);
|
|
1224
|
-
setEmail("");
|
|
1225
|
-
stopCountdown();
|
|
1226
|
-
}, [stopCountdown]);
|
|
1227
|
-
const clearError = useCallback(() => {
|
|
1228
|
-
setError(null);
|
|
1229
|
-
setIsEmailDuplicate(false);
|
|
1230
|
-
setIsCodeInvalid(false);
|
|
1231
|
-
}, []);
|
|
1232
|
-
const sendCode = useCallback(
|
|
1233
|
-
async (emailAddress) => {
|
|
1234
|
-
if (!api) {
|
|
1235
|
-
const err = new Error("TaskOn client not initialized");
|
|
1236
|
-
setError(err);
|
|
1237
|
-
onSendCodeError == null ? void 0 : onSendCodeError(err);
|
|
1238
|
-
return false;
|
|
1239
|
-
}
|
|
1240
|
-
if (!EMAIL_REGEX$1.test(emailAddress)) {
|
|
1241
|
-
const err = new Error("Invalid email format");
|
|
1242
|
-
setError(err);
|
|
1243
|
-
onSendCodeError == null ? void 0 : onSendCodeError(err);
|
|
1244
|
-
return false;
|
|
1245
|
-
}
|
|
1246
|
-
setStatus("sendingCode");
|
|
1247
|
-
setError(null);
|
|
1248
|
-
setIsEmailDuplicate(false);
|
|
1249
|
-
try {
|
|
1250
|
-
const result = await api.requestEmailVerifyCode({
|
|
1251
|
-
email: emailAddress,
|
|
1252
|
-
type: VerifyCodeType.Bind
|
|
1253
|
-
});
|
|
1254
|
-
if (result) {
|
|
1255
|
-
setStatus("inputCode");
|
|
1256
|
-
setEmail(emailAddress);
|
|
1257
|
-
startCountdown();
|
|
1258
|
-
onSendCodeSuccess == null ? void 0 : onSendCodeSuccess();
|
|
1259
|
-
return true;
|
|
1260
|
-
} else {
|
|
1261
|
-
const err = new Error("Failed to send verification code");
|
|
1262
|
-
setStatus("inputEmail");
|
|
1263
|
-
setError(err);
|
|
1264
|
-
onSendCodeError == null ? void 0 : onSendCodeError(err);
|
|
1265
|
-
return false;
|
|
1266
|
-
}
|
|
1267
|
-
} catch (err) {
|
|
1268
|
-
const error2 = err;
|
|
1269
|
-
if (error2.code === SNS_BIND_DUPLICATE_ERROR) {
|
|
1270
|
-
setIsEmailDuplicate(true);
|
|
1271
|
-
}
|
|
1272
|
-
setStatus("inputEmail");
|
|
1273
|
-
setError(error2);
|
|
1274
|
-
onSendCodeError == null ? void 0 : onSendCodeError(error2);
|
|
1275
|
-
return false;
|
|
1276
|
-
}
|
|
1277
|
-
},
|
|
1278
|
-
[api, onSendCodeSuccess, onSendCodeError, startCountdown]
|
|
1279
|
-
);
|
|
1280
|
-
const bind = useCallback(
|
|
1281
|
-
async (emailAddress, code) => {
|
|
1282
|
-
if (!api) {
|
|
1283
|
-
const err = new Error("TaskOn client not initialized");
|
|
1284
|
-
setError(err);
|
|
1285
|
-
onBindError == null ? void 0 : onBindError(err);
|
|
1286
|
-
return null;
|
|
1287
|
-
}
|
|
1288
|
-
setStatus("submitting");
|
|
1289
|
-
setError(null);
|
|
1290
|
-
setIsCodeInvalid(false);
|
|
1291
|
-
try {
|
|
1292
|
-
const result = await api.bindSNS({
|
|
1293
|
-
sns_type: SnsType.Email,
|
|
1294
|
-
token: code,
|
|
1295
|
-
sns_user_name: emailAddress
|
|
1296
|
-
});
|
|
1297
|
-
if (result.result) {
|
|
1298
|
-
await refreshUserInfo();
|
|
1299
|
-
setStatus("success");
|
|
1300
|
-
onBindSuccess == null ? void 0 : onBindSuccess(result);
|
|
1301
|
-
return result;
|
|
1302
|
-
} else {
|
|
1303
|
-
const err = new Error("Email is already linked to another account");
|
|
1304
|
-
setStatus("inputCode");
|
|
1305
|
-
setError(err);
|
|
1306
|
-
onBindError == null ? void 0 : onBindError(err);
|
|
1307
|
-
return null;
|
|
1308
|
-
}
|
|
1309
|
-
} catch (err) {
|
|
1310
|
-
const error2 = err;
|
|
1311
|
-
if (error2.code === INVALID_EMAIL_VERIFY_CODE) {
|
|
1312
|
-
setIsCodeInvalid(true);
|
|
1313
|
-
}
|
|
1314
|
-
setStatus("inputCode");
|
|
1315
|
-
setError(error2);
|
|
1316
|
-
onBindError == null ? void 0 : onBindError(error2);
|
|
1317
|
-
return null;
|
|
1318
|
-
}
|
|
1319
|
-
},
|
|
1320
|
-
[api, refreshUserInfo, onBindSuccess, onBindError]
|
|
1321
|
-
);
|
|
1322
|
-
const reset = useCallback(() => {
|
|
1323
|
-
setStatus("idle");
|
|
1324
|
-
setError(null);
|
|
1325
|
-
setIsEmailDuplicate(false);
|
|
1326
|
-
setIsCodeInvalid(false);
|
|
1327
|
-
setEmail("");
|
|
1328
|
-
stopCountdown();
|
|
1329
|
-
}, [stopCountdown]);
|
|
1330
|
-
return {
|
|
1331
|
-
status,
|
|
1332
|
-
countdown,
|
|
1333
|
-
error,
|
|
1334
|
-
isEmailDuplicate,
|
|
1335
|
-
isCodeInvalid,
|
|
1336
|
-
email,
|
|
1337
|
-
open,
|
|
1338
|
-
close,
|
|
1339
|
-
setEmail,
|
|
1340
|
-
sendCode,
|
|
1341
|
-
bind,
|
|
1342
|
-
reset,
|
|
1343
|
-
clearError
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
|
-
function generateSignMessage(action, address, nonce) {
|
|
1347
|
-
return `TaskOn ${action} wallet
|
|
1348
|
-
Address: ${address}
|
|
1349
|
-
Nonce: ${nonce}`;
|
|
1350
|
-
}
|
|
1351
|
-
function generateNonce() {
|
|
1352
|
-
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
1353
|
-
}
|
|
1354
|
-
function useBindWallet(options = {}) {
|
|
1355
|
-
const {
|
|
1356
|
-
onBindSuccess,
|
|
1357
|
-
onBindError,
|
|
1358
|
-
onUnbindSuccess,
|
|
1359
|
-
onUnbindError
|
|
1360
|
-
} = options;
|
|
1361
|
-
const { client, refreshUserInfo } = useTaskOnContext();
|
|
1362
|
-
const {
|
|
1363
|
-
connectEvm,
|
|
1364
|
-
signEvmMessage,
|
|
1365
|
-
evmAddress: connectedAddress,
|
|
1366
|
-
isEvmConnected: isConnected
|
|
1367
|
-
} = useWallet();
|
|
1368
|
-
const [bindStatus, setBindStatus] = useState("idle");
|
|
1369
|
-
const [unbindStatus, setUnbindStatus] = useState("idle");
|
|
1370
|
-
const [error, setError] = useState(null);
|
|
1371
|
-
const [processingChain, setProcessingChain] = useState(null);
|
|
1372
|
-
const api = useMemo(() => {
|
|
1373
|
-
if (!client) return null;
|
|
1374
|
-
return createUserApi(client);
|
|
1375
|
-
}, [client]);
|
|
1376
|
-
const bind = useCallback(
|
|
1377
|
-
async (chainType) => {
|
|
1378
|
-
if (!api) {
|
|
1379
|
-
const err = new Error("TaskOn client not initialized");
|
|
1380
|
-
setError(err);
|
|
1381
|
-
onBindError == null ? void 0 : onBindError(err);
|
|
1382
|
-
return false;
|
|
1383
|
-
}
|
|
1384
|
-
setProcessingChain(chainType);
|
|
1385
|
-
setBindStatus("connecting");
|
|
1386
|
-
setError(null);
|
|
1387
|
-
try {
|
|
1388
|
-
let walletAddress = connectedAddress;
|
|
1389
|
-
if (!isConnected || !walletAddress) {
|
|
1390
|
-
setBindStatus("connecting");
|
|
1391
|
-
const connectResult = await connectEvm();
|
|
1392
|
-
if (!connectResult) {
|
|
1393
|
-
throw new Error("Failed to connect wallet");
|
|
1394
|
-
}
|
|
1395
|
-
walletAddress = connectResult;
|
|
1396
|
-
}
|
|
1397
|
-
if (!walletAddress) {
|
|
1398
|
-
throw new Error("No wallet address available");
|
|
1399
|
-
}
|
|
1400
|
-
const nonce = generateNonce();
|
|
1401
|
-
const message = generateSignMessage("bind", walletAddress, nonce);
|
|
1402
|
-
setBindStatus("signing");
|
|
1403
|
-
const signature = await signEvmMessage(message);
|
|
1404
|
-
if (!signature) {
|
|
1405
|
-
throw new Error("Failed to sign message");
|
|
1406
|
-
}
|
|
1407
|
-
setBindStatus("submitting");
|
|
1408
|
-
const result = await api.bindAddress({
|
|
1409
|
-
chain_type: chainType,
|
|
1410
|
-
address: walletAddress,
|
|
1411
|
-
nonce,
|
|
1412
|
-
sig: signature
|
|
1413
|
-
});
|
|
1414
|
-
if (result) {
|
|
1415
|
-
await refreshUserInfo();
|
|
1416
|
-
setBindStatus("success");
|
|
1417
|
-
onBindSuccess == null ? void 0 : onBindSuccess();
|
|
1418
|
-
return true;
|
|
1419
|
-
} else {
|
|
1420
|
-
throw new Error("Bind wallet failed");
|
|
1421
|
-
}
|
|
1422
|
-
} catch (err) {
|
|
1423
|
-
const error2 = err instanceof Error ? err : new Error("Bind wallet failed");
|
|
1424
|
-
setBindStatus("error");
|
|
1425
|
-
setError(error2);
|
|
1426
|
-
onBindError == null ? void 0 : onBindError(error2);
|
|
1427
|
-
return false;
|
|
1428
|
-
} finally {
|
|
1429
|
-
setProcessingChain(null);
|
|
1430
|
-
}
|
|
1431
|
-
},
|
|
1432
|
-
[
|
|
1433
|
-
api,
|
|
1434
|
-
refreshUserInfo,
|
|
1435
|
-
connectEvm,
|
|
1436
|
-
signEvmMessage,
|
|
1437
|
-
connectedAddress,
|
|
1438
|
-
isConnected,
|
|
1439
|
-
onBindSuccess,
|
|
1440
|
-
onBindError
|
|
1441
|
-
]
|
|
1442
|
-
);
|
|
1443
|
-
const unbind = useCallback(
|
|
1444
|
-
async (chainType, address) => {
|
|
1445
|
-
if (!api) {
|
|
1446
|
-
const err = new Error("TaskOn client not initialized");
|
|
1447
|
-
setError(err);
|
|
1448
|
-
onUnbindError == null ? void 0 : onUnbindError(err);
|
|
1449
|
-
return false;
|
|
1450
|
-
}
|
|
1451
|
-
setProcessingChain(chainType);
|
|
1452
|
-
setUnbindStatus("connecting");
|
|
1453
|
-
setError(null);
|
|
1454
|
-
try {
|
|
1455
|
-
let walletAddress = connectedAddress;
|
|
1456
|
-
if (!isConnected || !walletAddress) {
|
|
1457
|
-
setUnbindStatus("connecting");
|
|
1458
|
-
const connectResult = await connectEvm();
|
|
1459
|
-
if (!connectResult) {
|
|
1460
|
-
throw new Error("Failed to connect wallet");
|
|
1461
|
-
}
|
|
1462
|
-
walletAddress = connectResult;
|
|
1463
|
-
}
|
|
1464
|
-
if ((walletAddress == null ? void 0 : walletAddress.toLowerCase()) !== address.toLowerCase()) {
|
|
1465
|
-
throw new Error(
|
|
1466
|
-
"Connected wallet address does not match the address to unbind. Please connect the correct wallet."
|
|
1467
|
-
);
|
|
1468
|
-
}
|
|
1469
|
-
const nonce = generateNonce();
|
|
1470
|
-
const message = generateSignMessage("unbind", address, nonce);
|
|
1471
|
-
setUnbindStatus("signing");
|
|
1472
|
-
const signature = await signEvmMessage(message);
|
|
1473
|
-
if (!signature) {
|
|
1474
|
-
throw new Error("Failed to sign message");
|
|
1475
|
-
}
|
|
1476
|
-
setUnbindStatus("submitting");
|
|
1477
|
-
const result = await api.unbindAddress({
|
|
1478
|
-
chain_type: chainType,
|
|
1479
|
-
address,
|
|
1480
|
-
nonce,
|
|
1481
|
-
sig: signature
|
|
1482
|
-
});
|
|
1483
|
-
if (result) {
|
|
1484
|
-
await refreshUserInfo();
|
|
1485
|
-
setUnbindStatus("success");
|
|
1486
|
-
onUnbindSuccess == null ? void 0 : onUnbindSuccess();
|
|
1487
|
-
return true;
|
|
1488
|
-
} else {
|
|
1489
|
-
throw new Error("Unbind wallet failed");
|
|
1490
|
-
}
|
|
1491
|
-
} catch (err) {
|
|
1492
|
-
const error2 = err instanceof Error ? err : new Error("Unbind wallet failed");
|
|
1493
|
-
setUnbindStatus("error");
|
|
1494
|
-
setError(error2);
|
|
1495
|
-
onUnbindError == null ? void 0 : onUnbindError(error2);
|
|
1496
|
-
return false;
|
|
1497
|
-
} finally {
|
|
1498
|
-
setProcessingChain(null);
|
|
1499
|
-
}
|
|
1500
|
-
},
|
|
1501
|
-
[
|
|
1502
|
-
api,
|
|
1503
|
-
refreshUserInfo,
|
|
1504
|
-
connectEvm,
|
|
1505
|
-
signEvmMessage,
|
|
1506
|
-
connectedAddress,
|
|
1507
|
-
isConnected,
|
|
1508
|
-
onUnbindSuccess,
|
|
1509
|
-
onUnbindError
|
|
1510
|
-
]
|
|
1511
|
-
);
|
|
1512
|
-
const reset = useCallback(() => {
|
|
1513
|
-
setBindStatus("idle");
|
|
1514
|
-
setUnbindStatus("idle");
|
|
1515
|
-
setError(null);
|
|
1516
|
-
setProcessingChain(null);
|
|
1517
|
-
}, []);
|
|
1518
|
-
return {
|
|
1519
|
-
bindStatus,
|
|
1520
|
-
unbindStatus,
|
|
1521
|
-
error,
|
|
1522
|
-
processingChain,
|
|
1523
|
-
bind,
|
|
1524
|
-
unbind,
|
|
1525
|
-
reset
|
|
1526
|
-
};
|
|
1527
|
-
}
|
|
1528
|
-
const OAUTH_SNS_TYPES = ["Twitter", "Discord", "Telegram"];
|
|
1529
|
-
function useOAuthBindings(options = {}) {
|
|
1530
|
-
const { onSuccess, onFailed } = options;
|
|
1531
|
-
const {
|
|
1532
|
-
bindIfNeed: bindTwitter,
|
|
1533
|
-
isWaitingAuth: isTwitterBinding
|
|
1534
|
-
} = useBindSocialAccount({
|
|
1535
|
-
snsType: "Twitter",
|
|
1536
|
-
onSuccess,
|
|
1537
|
-
onFailed
|
|
1538
|
-
});
|
|
1539
|
-
const {
|
|
1540
|
-
bindIfNeed: bindDiscord,
|
|
1541
|
-
isWaitingAuth: isDiscordBinding
|
|
1542
|
-
} = useBindSocialAccount({
|
|
1543
|
-
snsType: "Discord",
|
|
1544
|
-
onSuccess,
|
|
1545
|
-
onFailed
|
|
1546
|
-
});
|
|
1547
|
-
const {
|
|
1548
|
-
bindIfNeed: bindTelegram,
|
|
1549
|
-
isWaitingAuth: isTelegramBinding
|
|
1550
|
-
} = useBindSocialAccount({
|
|
1551
|
-
snsType: "Telegram",
|
|
1552
|
-
onSuccess,
|
|
1553
|
-
onFailed
|
|
1554
|
-
});
|
|
1555
|
-
const bind = useCallback(
|
|
1556
|
-
(snsType) => {
|
|
1557
|
-
switch (snsType) {
|
|
1558
|
-
case "Twitter":
|
|
1559
|
-
bindTwitter();
|
|
1560
|
-
break;
|
|
1561
|
-
case "Discord":
|
|
1562
|
-
bindDiscord();
|
|
1563
|
-
break;
|
|
1564
|
-
case "Telegram":
|
|
1565
|
-
bindTelegram();
|
|
1566
|
-
break;
|
|
1567
|
-
default:
|
|
1568
|
-
console.warn(`[useOAuthBindings] Unsupported snsType: ${snsType}`);
|
|
1569
|
-
}
|
|
1570
|
-
},
|
|
1571
|
-
[bindTwitter, bindDiscord, bindTelegram]
|
|
1572
|
-
);
|
|
1573
|
-
const isBinding = useCallback(
|
|
1574
|
-
(snsType) => {
|
|
1575
|
-
switch (snsType.toLowerCase()) {
|
|
1576
|
-
case "twitter":
|
|
1577
|
-
return isTwitterBinding;
|
|
1578
|
-
case "discord":
|
|
1579
|
-
return isDiscordBinding;
|
|
1580
|
-
case "telegram":
|
|
1581
|
-
return isTelegramBinding;
|
|
1582
|
-
default:
|
|
1583
|
-
return false;
|
|
1584
|
-
}
|
|
1585
|
-
},
|
|
1586
|
-
[isTwitterBinding, isDiscordBinding, isTelegramBinding]
|
|
1587
|
-
);
|
|
1588
|
-
const isOAuthSupported = useCallback((snsType) => {
|
|
1589
|
-
return OAUTH_SNS_TYPES.includes(snsType);
|
|
1590
|
-
}, []);
|
|
1591
|
-
return {
|
|
1592
|
-
bind,
|
|
1593
|
-
isBinding,
|
|
1594
|
-
isOAuthSupported
|
|
1595
|
-
};
|
|
1596
|
-
}
|
|
1597
|
-
const UNBIND_COOLDOWN_MS = 24 * 60 * 60 * 1e3;
|
|
1598
|
-
const MIN_LOGIN_METHODS = 1;
|
|
1599
|
-
function isInCooldown(bindTime) {
|
|
1600
|
-
const now = Date.now();
|
|
1601
|
-
return now - bindTime < UNBIND_COOLDOWN_MS;
|
|
1602
|
-
}
|
|
1603
|
-
function getCooldownRemaining(bindTime) {
|
|
1604
|
-
const now = Date.now();
|
|
1605
|
-
const elapsed = now - bindTime;
|
|
1606
|
-
const remaining = UNBIND_COOLDOWN_MS - elapsed;
|
|
1607
|
-
return Math.max(0, remaining);
|
|
1608
|
-
}
|
|
1609
|
-
function formatCooldownTime(ms) {
|
|
1610
|
-
const hours = Math.ceil(ms / (60 * 60 * 1e3));
|
|
1611
|
-
if (hours <= 1) {
|
|
1612
|
-
return "less than 1 hour";
|
|
1613
|
-
}
|
|
1614
|
-
return `${hours} hours`;
|
|
1615
|
-
}
|
|
1616
|
-
function useDisableUnlink() {
|
|
1617
|
-
const { totalBoundCount } = useIdentityData();
|
|
1618
|
-
const isLastLoginMethod = totalBoundCount <= MIN_LOGIN_METHODS;
|
|
1619
|
-
const checkSocialUnlink = useMemo(() => {
|
|
1620
|
-
return (account) => {
|
|
1621
|
-
if (isLastLoginMethod) {
|
|
1622
|
-
return {
|
|
1623
|
-
disabled: true,
|
|
1624
|
-
reason: "lastLoginMethod",
|
|
1625
|
-
message: "Cannot unbind the last login method. You must keep at least one login method.",
|
|
1626
|
-
cooldownRemaining: null,
|
|
1627
|
-
needsKycWarning: false
|
|
1628
|
-
};
|
|
1629
|
-
}
|
|
1630
|
-
const bindTimeMs = account.bind_time;
|
|
1631
|
-
if (isInCooldown(bindTimeMs)) {
|
|
1632
|
-
const remaining = getCooldownRemaining(bindTimeMs);
|
|
1633
|
-
return {
|
|
1634
|
-
disabled: true,
|
|
1635
|
-
reason: "cooldown",
|
|
1636
|
-
message: `Cannot unbind within 24 hours of binding. Please wait ${formatCooldownTime(remaining)}.`,
|
|
1637
|
-
cooldownRemaining: remaining,
|
|
1638
|
-
needsKycWarning: false
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
return {
|
|
1642
|
-
disabled: false,
|
|
1643
|
-
reason: null,
|
|
1644
|
-
message: null,
|
|
1645
|
-
cooldownRemaining: null,
|
|
1646
|
-
needsKycWarning: false
|
|
1647
|
-
};
|
|
1648
|
-
};
|
|
1649
|
-
}, [isLastLoginMethod]);
|
|
1650
|
-
const checkWalletUnlink = useMemo(() => {
|
|
1651
|
-
return (address, isKycVerified = false) => {
|
|
1652
|
-
if (isLastLoginMethod) {
|
|
1653
|
-
return {
|
|
1654
|
-
disabled: true,
|
|
1655
|
-
reason: "lastLoginMethod",
|
|
1656
|
-
message: "Cannot unbind the last login method. You must keep at least one login method.",
|
|
1657
|
-
cooldownRemaining: null,
|
|
1658
|
-
needsKycWarning: false
|
|
1659
|
-
};
|
|
1660
|
-
}
|
|
1661
|
-
const bindTimeMs = address.bind_time;
|
|
1662
|
-
if (isInCooldown(bindTimeMs)) {
|
|
1663
|
-
const remaining = getCooldownRemaining(bindTimeMs);
|
|
1664
|
-
return {
|
|
1665
|
-
disabled: true,
|
|
1666
|
-
reason: "cooldown",
|
|
1667
|
-
message: `Cannot unbind within 24 hours of binding. Please wait ${formatCooldownTime(remaining)}.`,
|
|
1668
|
-
cooldownRemaining: remaining,
|
|
1669
|
-
needsKycWarning: isKycVerified
|
|
1670
|
-
};
|
|
1671
|
-
}
|
|
1672
|
-
if (isKycVerified) {
|
|
1673
|
-
return {
|
|
1674
|
-
disabled: false,
|
|
1675
|
-
reason: "kycVerified",
|
|
1676
|
-
message: "This address has been KYC verified. Unbinding will clear your KYC verification status.",
|
|
1677
|
-
cooldownRemaining: null,
|
|
1678
|
-
needsKycWarning: true
|
|
1679
|
-
};
|
|
1680
|
-
}
|
|
1681
|
-
return {
|
|
1682
|
-
disabled: false,
|
|
1683
|
-
reason: null,
|
|
1684
|
-
message: null,
|
|
1685
|
-
cooldownRemaining: null,
|
|
1686
|
-
needsKycWarning: false
|
|
1687
|
-
};
|
|
1688
|
-
};
|
|
1689
|
-
}, [isLastLoginMethod]);
|
|
1690
|
-
return {
|
|
1691
|
-
checkSocialUnlink,
|
|
1692
|
-
checkWalletUnlink,
|
|
1693
|
-
totalBoundCount,
|
|
1694
|
-
isLastLoginMethod
|
|
1695
|
-
};
|
|
1696
|
-
}
|
|
1697
|
-
const twitterIcon = new URL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAH3SURBVHgBzZeNkYIwEIXjVYAdcB1QAtcBVqBWcFoBdgBWgB1YAtcBJUAHlrCXxxEnEzaQIMi9mR0zIT+fSd4GhDBERLGMTEZN86uSUcgIhU3yYdABvEuYK+AgKnq/KgXz0bGkMiLxfkXd3GJDf/tVi3X1hRVJzdrz+Sw2mw0b2+1WNE0jXHU8Htt+u91uqFkiiDkbj8eDoigi2YCCIKAwDNtAGXVxHDsdgMvl0rZHX4w5oFrYnlRV9ZwYZQWIQVGX5zkNCc8VRF3XNCYx9DDLst4/0gHLsmT7oV6tpgvEKAiEbcCgp9NpEFAJEyvQ+/1OrhoFsQ3MAaKt2ro0TclHoyAQAMylNgH18+ML4QwC4Z+bjtEBkyRpy/idImcQm2MUoKNNXweBdDdwlkbemCovEEg5BglPt7QJuDgI5GvpxUDUFplJjQNcDEQ/E+YK6Ja2Zd3ZQHSb7vf7nmWLopi0RV4g5m1qszQHOBuIDqFfZNwF53NLe4FwKV6XSmqw9BDgSyCut6l6kdIdwwFOAvG5TW2O4QC9QKbcplxSc7W0FWTqbaqSGveuO2RpgNRmpcdLb09orybm4nA4cN0qfNfkssG3WFc3gMSyUIp19fkhP35+ZOEq1tNVMjRtif7BR/hTHYxbPp5HeQ/CAApl3GiZFao7gNic9xdG16HkLDPmwQAAAABJRU5ErkJggg==", import.meta.url).href;
|
|
1698
|
-
const discordIcon = new URL("data:image/svg+xml,%3csvg%20width='24'%20height='25'%20viewBox='0%200%2024%2025'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20y='0.187012'%20width='24'%20height='24.2243'%20rx='8'%20fill='%237870FF'/%3e%3cpath%20d='M18.7627%206.96988C16.7288%205.45184%2014.7966%205.34341%2014.4915%205.34341L14.2881%205.56027C16.6271%206.21086%2017.9492%207.4036%2018.0508%207.51203C14.3898%205.56027%2010.322%205.45184%206.66102%206.96988C6.15254%207.18674%205.84746%207.4036%205.74576%207.4036C5.94915%207.29517%207.16949%206.10243%209.71186%205.45184L9.50847%205.23498C9.50847%205.23498%207.47458%205.12655%205.23729%206.86145C5.23729%206.86145%203%2010.8734%203%2015.9697C3%2015.9697%204.32203%2018.2467%207.67797%2018.3551C7.67797%2018.3551%208.18644%2017.7046%208.69492%2017.054C6.9661%2016.5118%206.15254%2015.3191%206.05085%2015.2106L6.66102%2015.5359C8.49153%2016.2949%2010.4237%2017.3793%2013.9831%2016.7287C14.6949%2016.6202%2015.5085%2016.4034%2016.2203%2016.0781C16.7288%2015.7528%2017.339%2015.5359%2017.9492%2015.1022C17.8475%2015.2106%2017.0339%2016.4034%2015.2034%2016.9455C15.6102%2017.5961%2016.2203%2018.2467%2016.2203%2018.2467C19.678%2018.1383%2021%2015.8612%2021%2016.0781C21%2011.0903%2018.7627%206.96988%2018.7627%206.96988ZM9.20339%2014.3432C8.38983%2014.3432%207.67797%2013.5842%207.67797%2012.6083C7.67797%2011.6324%208.38983%2010.8734%209.20339%2010.8734C10.0169%2010.8734%2010.7288%2011.7408%2010.7288%2012.6083C10.7288%2013.5842%2010.0169%2014.3432%209.20339%2014.3432ZM14.7966%2014.3432C13.9831%2014.3432%2013.2712%2013.5842%2013.2712%2012.6083C13.2712%2011.6324%2013.9831%2010.8734%2014.7966%2010.8734C15.7119%2010.8734%2016.4237%2011.7408%2016.4237%2012.6083C16.4237%2013.5842%2015.7119%2014.3432%2014.7966%2014.3432Z'%20fill='white'/%3e%3c/svg%3e", import.meta.url).href;
|
|
1699
|
-
const telegramIcon = new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%3e%3crect%20y='0.000396729'%20width='24'%20height='24'%20rx='8'%20fill='%2354AEFF'/%3e%3cpath%20d='M18.9513%206.24633L16.5438%2017.617C16.377%2018.424%2015.8902%2018.6174%2015.21%2018.2439L11.542%2015.5296L9.76804%2017.2435C9.56797%2017.4436%209.40125%2017.617%209.03445%2017.617C8.55428%2017.617%208.63431%2017.4369%208.47425%2016.9835L7.20714%2012.8553L3.57252%2011.7216C2.78558%2011.4882%202.77891%2010.948%203.74592%2010.5545L17.9243%205.08592C18.5711%204.79915%2019.1914%205.24598%2018.9446%206.23966L18.9513%206.24633Z'%20fill='white'/%3e%3c/svg%3e", import.meta.url).href;
|
|
1700
|
-
const redditIcon = new URL("data:image/svg+xml,%3csvg%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20id='Group%2048098228'%3e%3crect%20id='Rectangle%206202'%20y='0.000488281'%20width='24'%20height='24'%20rx='8'%20fill='%23FF4500'/%3e%3cpath%20id='Vector'%20d='M20.0319%2012.242C20.0319%2011.2761%2019.2031%2010.4913%2018.185%2010.4913C17.7441%2010.4913%2017.3313%2010.6436%2016.9987%2010.9114L16.9658%2010.9306C15.7642%2010.2012%2014.1714%209.73623%2012.4103%209.67371L13.4612%206.83847L16.0864%207.43325C16.0881%208.22042%2016.763%208.86009%2017.5934%208.86009C18.4255%208.86009%2019.102%208.21882%2019.102%207.43005C19.102%206.64128%2018.4255%206%2017.5951%206C16.9626%206%2016.4231%206.37034%2016.1995%206.89298L13.0893%206.18837L11.7987%209.6673C9.96066%209.69936%208.29575%2010.1707%207.05007%2010.9242C6.71195%2010.6442%206.28667%2010.4911%205.84768%2010.4913C4.82725%2010.4905%204%2011.2761%204%2012.2412C4%2012.8384%204.32465%2013.3899%204.8521%2013.7113C4.82003%2013.8853%204.79919%2014.0616%204.79919%2014.2412C4.79919%2016.7694%208.03042%2018.8255%2012.0015%2018.8255C15.9734%2018.8255%2019.2055%2016.7694%2019.2055%2014.242C19.2055%2014.0681%2019.187%2013.8965%2019.1566%2013.7274C19.6968%2013.4083%2020.0319%2012.8488%2020.0319%2012.242ZM14.4512%2014.5089C13.8243%2014.5089%2013.3169%2014.028%2013.3169%2013.4332C13.3169%2012.8392%2013.8243%2012.3575%2014.4512%2012.3575C15.078%2012.3575%2015.5863%2012.8384%2015.5863%2013.4332C15.5863%2014.028%2015.0772%2014.5089%2014.4512%2014.5089ZM14.6764%2016.3438C14.6428%2016.3758%2013.8292%2017.1614%2011.9887%2017.1614C10.1386%2017.1614%209.39954%2016.3662%209.36748%2016.3318C9.3428%2016.3048%209.32396%2016.273%209.31214%2016.2384C9.30032%2016.2039%209.29577%2016.1672%209.29878%2016.1308C9.30179%2016.0943%209.3123%2016.0589%209.32964%2016.0268C9.34697%2015.9946%209.37078%2015.9663%209.39954%2015.9438C9.45882%2015.8964%209.53372%2015.873%209.60941%2015.8782C9.68511%2015.8834%209.7561%2015.9168%209.80836%2015.9718C9.82439%2015.9895%2010.4416%2016.6131%2011.9887%2016.6131C13.5622%2016.6131%2014.2524%2015.9678%2014.2596%2015.9614C14.3147%2015.9094%2014.3873%2015.88%2014.4631%2015.8791C14.5388%2015.8782%2014.6122%2015.9059%2014.6684%2015.9566C14.6955%2015.9808%2014.7174%2016.0103%2014.7325%2016.0433C14.7477%2016.0763%2014.756%2016.1121%2014.7567%2016.1485C14.7575%2016.1848%2014.7507%2016.2209%2014.7369%2016.2545C14.7231%2016.2881%2014.7025%2016.3185%2014.6764%2016.3438ZM8.57871%2013.4332C8.57871%2012.8392%209.08612%2012.3575%209.71457%2012.3575C10.3398%2012.3575%2010.8488%2012.8384%2010.8488%2013.4332C10.8488%2014.028%2010.3398%2014.5089%209.71457%2014.5089C9.08692%2014.5089%208.57871%2014.028%208.57871%2013.4332Z'%20fill='white'/%3e%3c/g%3e%3c/svg%3e", import.meta.url).href;
|
|
1701
|
-
const emailIcon = new URL("data:image/svg+xml,%3csvg%20width='24'%20height='25'%20viewBox='0%200%2024%2025'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20width='24'%20height='24.2243'%20rx='8'%20fill='%23DD9F00'/%3e%3cpath%20d='M5.14286%2015.2063L9.41607%2012L4%207.93687V16.0612L4.89286%2015.3919L5.14286%2015.2063ZM12%2012.4631L18.8571%207.32L19.8393%206.585C19.6393%206.23437%2019.275%206%2018.8571%206H5.14286C4.75893%206%204.41964%206.19875%204.2125%206.5025L5.14286%207.32L12%2012.4631ZM13.6%2012.7369L12%2013.9369L10.4%2012.7369L5.14286%2016.68L4.89286%2016.8956L4.20536%2017.4862C4.41071%2017.7975%204.75536%2018%205.14286%2018H18.8571C19.2768%2018%2019.6429%2017.7638%2019.8411%2017.4113L18.8571%2016.68L13.6%2012.7369ZM14.5821%2012L20%2016.0631V7.93687L14.5821%2012Z'%20fill='white'/%3e%3c/svg%3e", import.meta.url).href;
|
|
1702
|
-
const SOCIAL_ICONS = {
|
|
1703
|
-
[SnsType.Twitter]: twitterIcon,
|
|
1704
|
-
[SnsType.Discord]: discordIcon,
|
|
1705
|
-
[SnsType.Telegram]: telegramIcon,
|
|
1706
|
-
[SnsType.Reddit]: redditIcon,
|
|
1707
|
-
[SnsType.Email]: emailIcon
|
|
1708
|
-
};
|
|
1709
|
-
function SocialIcon({
|
|
1710
|
-
type,
|
|
1711
|
-
size = 24,
|
|
1712
|
-
className = ""
|
|
1713
|
-
}) {
|
|
1714
|
-
const iconSrc = SOCIAL_ICONS[type];
|
|
1715
|
-
if (iconSrc) {
|
|
1716
|
-
return /* @__PURE__ */ jsx(
|
|
1717
|
-
"img",
|
|
1718
|
-
{
|
|
1719
|
-
src: iconSrc,
|
|
1720
|
-
alt: type,
|
|
1721
|
-
width: size,
|
|
1722
|
-
height: size,
|
|
1723
|
-
className: `taskon-social-icon ${className}`,
|
|
1724
|
-
style: { objectFit: "contain" }
|
|
1725
|
-
}
|
|
1726
|
-
);
|
|
1727
|
-
}
|
|
1728
|
-
return /* @__PURE__ */ jsx(
|
|
1729
|
-
"svg",
|
|
1730
|
-
{
|
|
1731
|
-
width: size,
|
|
1732
|
-
height: size,
|
|
1733
|
-
viewBox: "0 0 24 24",
|
|
1734
|
-
fill: "none",
|
|
1735
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1736
|
-
className,
|
|
1737
|
-
style: { color: "var(--taskon-color-text-secondary)" },
|
|
1738
|
-
children: /* @__PURE__ */ jsx(
|
|
1739
|
-
"path",
|
|
1740
|
-
{
|
|
1741
|
-
d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1ZM8 13h8v-2H8v2Zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5Z",
|
|
1742
|
-
fill: "currentColor"
|
|
1743
|
-
}
|
|
1744
|
-
)
|
|
1745
|
-
}
|
|
1746
|
-
);
|
|
1747
|
-
}
|
|
1748
|
-
function ChainIcon({ chain }) {
|
|
1749
|
-
if (chain === "evm") {
|
|
1750
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1751
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "white" }),
|
|
1752
|
-
/* @__PURE__ */ jsx("path", { d: "M12 4L6 12L12 9.5V4Z", fill: "#343434" }),
|
|
1753
|
-
/* @__PURE__ */ jsx("path", { d: "M12 4L18 12L12 9.5V4Z", fill: "#8C8C8C" }),
|
|
1754
|
-
/* @__PURE__ */ jsx("path", { d: "M12 16.5L6 12L12 14.5V16.5Z", fill: "#3C3C3B" }),
|
|
1755
|
-
/* @__PURE__ */ jsx("path", { d: "M12 16.5L18 12L12 14.5V16.5Z", fill: "#8C8C8C" }),
|
|
1756
|
-
/* @__PURE__ */ jsx("path", { d: "M12 17.5L6 13L12 20V17.5Z", fill: "#141414" }),
|
|
1757
|
-
/* @__PURE__ */ jsx("path", { d: "M12 17.5L18 13L12 20V17.5Z", fill: "#393939" })
|
|
1758
|
-
] });
|
|
1759
|
-
}
|
|
1760
|
-
if (chain === "sui") {
|
|
1761
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1762
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#4DA2FF" }),
|
|
1763
|
-
/* @__PURE__ */ jsx("path", { d: "M16.5 8.5C15.5 7.5 14 7 12.5 7.5C11 8 10 9 9.5 10.5C9 12 9 13.5 9.5 15C10 16.5 11 17.5 12.5 18C14 18.5 15.5 18 16.5 17", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }),
|
|
1764
|
-
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "10", r: "1.5", fill: "white" })
|
|
1765
|
-
] });
|
|
1766
|
-
}
|
|
1767
|
-
if (chain === "solana") {
|
|
1768
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1769
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "black" }),
|
|
1770
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "solana-grad", x1: "4", y1: "20", x2: "20", y2: "4", children: [
|
|
1771
|
-
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#9945FF" }),
|
|
1772
|
-
/* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: "#14F195" }),
|
|
1773
|
-
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#00D1FF" })
|
|
1774
|
-
] }) }),
|
|
1775
|
-
/* @__PURE__ */ jsx("path", { d: "M6 15.5L8.5 13H18L15.5 15.5H6Z", fill: "url(#solana-grad)" }),
|
|
1776
|
-
/* @__PURE__ */ jsx("path", { d: "M6 8.5L8.5 11H18L15.5 8.5H6Z", fill: "url(#solana-grad)" }),
|
|
1777
|
-
/* @__PURE__ */ jsx("path", { d: "M6 12L8.5 9.5H18L15.5 12H6Z", fill: "url(#solana-grad)" })
|
|
1778
|
-
] });
|
|
1779
|
-
}
|
|
1780
|
-
if (chain === "starknet") {
|
|
1781
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1782
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#EC796B" }),
|
|
1783
|
-
/* @__PURE__ */ jsx("path", { d: "M12 6L8 10L12 8L16 10L12 6Z", fill: "white" }),
|
|
1784
|
-
/* @__PURE__ */ jsx("path", { d: "M8 10L12 14L8 12V10Z", fill: "white", fillOpacity: "0.6" }),
|
|
1785
|
-
/* @__PURE__ */ jsx("path", { d: "M16 10L12 14L16 12V10Z", fill: "white", fillOpacity: "0.8" }),
|
|
1786
|
-
/* @__PURE__ */ jsx("path", { d: "M12 14L8 12L12 18L16 12L12 14Z", fill: "white" })
|
|
1787
|
-
] });
|
|
1788
|
-
}
|
|
1789
|
-
if (chain === "aptos") {
|
|
1790
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1791
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "white" }),
|
|
1792
|
-
/* @__PURE__ */ jsx("path", { d: "M16 8H14L12 12L10 8H8L11 14H9V16H15V14H13L16 8Z", fill: "black" })
|
|
1793
|
-
] });
|
|
1794
|
-
}
|
|
1795
|
-
if (chain === "btc") {
|
|
1796
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1797
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#F7931A" }),
|
|
1798
|
-
/* @__PURE__ */ jsx("path", { d: "M15.5 10.5C15.5 8.5 14 8 12 8V6H11V8H10V6H9V8H7V10H8.5V14H7V16H9V18H10V16H11V18H12V16C14.5 16 16 15 16 13C16 11.5 15 11 15.5 10.5ZM10 10H12C13 10 13.5 10.5 13.5 11C13.5 11.5 13 12 12 12H10V10ZM12.5 14H10V12H12.5C13.5 12 14 12.5 14 13C14 13.5 13.5 14 12.5 14Z", fill: "white" })
|
|
1799
|
-
] });
|
|
1800
|
-
}
|
|
1801
|
-
if (chain === "tron") {
|
|
1802
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1803
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#FF0013" }),
|
|
1804
|
-
/* @__PURE__ */ jsx("path", { d: "M7 7L12 19L17 7H7Z", fill: "white" }),
|
|
1805
|
-
/* @__PURE__ */ jsx("path", { d: "M9 9L12 16L15 9H9Z", fill: "#FF0013" })
|
|
1806
|
-
] });
|
|
1807
|
-
}
|
|
1808
|
-
if (chain === "ton") {
|
|
1809
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1810
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#0088CC" }),
|
|
1811
|
-
/* @__PURE__ */ jsx("path", { d: "M12 6L6 18H10L12 14L14 18H18L12 6Z", fill: "white" })
|
|
1812
|
-
] });
|
|
1813
|
-
}
|
|
1814
|
-
if (chain === "nibiru") {
|
|
1815
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1816
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#1E1E2F" }),
|
|
1817
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5", stroke: "#7B68EE", strokeWidth: "2" }),
|
|
1818
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2", fill: "#7B68EE" })
|
|
1819
|
-
] });
|
|
1820
|
-
}
|
|
1821
|
-
if (chain === "kaspa") {
|
|
1822
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1823
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#49EACB" }),
|
|
1824
|
-
/* @__PURE__ */ jsx("path", { d: "M8 8L12 12L8 16M12 12L16 8M12 12L16 16", stroke: "white", strokeWidth: "2", strokeLinecap: "round" })
|
|
1825
|
-
] });
|
|
1826
|
-
}
|
|
1827
|
-
return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1828
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#4B5563" }),
|
|
1829
|
-
/* @__PURE__ */ jsx("path", { d: "M12 6C8.69 6 6 8.69 6 12s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z", fill: "white" })
|
|
1830
|
-
] });
|
|
1831
|
-
}
|
|
1832
|
-
function EvmChainIcons() {
|
|
1833
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-chain-icons", children: [
|
|
1834
|
-
/* @__PURE__ */ jsx(ChainIcon, { chain: "evm" }),
|
|
1835
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1836
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#213147" }),
|
|
1837
|
-
/* @__PURE__ */ jsx("path", { d: "M12 6L16.5 12L12 18L7.5 12L12 6Z", fill: "#28A0F0" }),
|
|
1838
|
-
/* @__PURE__ */ jsx("path", { d: "M12 6L7.5 12L12 14.5V6Z", fill: "white" })
|
|
1839
|
-
] }),
|
|
1840
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1841
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#8247E5" }),
|
|
1842
|
-
/* @__PURE__ */ jsx("path", { d: "M15.5 9L12 7L8.5 9V13L12 15L15.5 13V9Z", stroke: "white", strokeWidth: "1.5" }),
|
|
1843
|
-
/* @__PURE__ */ jsx("path", { d: "M12 11L15.5 9M12 11L8.5 9M12 11V15", stroke: "white", strokeWidth: "1.5" })
|
|
1844
|
-
] }),
|
|
1845
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1846
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#F3BA2F" }),
|
|
1847
|
-
/* @__PURE__ */ jsx("path", { d: "M12 7L9.5 9.5L10.5 10.5L12 9L13.5 10.5L14.5 9.5L12 7Z", fill: "white" }),
|
|
1848
|
-
/* @__PURE__ */ jsx("path", { d: "M7 12L8 11L9 12L8 13L7 12Z", fill: "white" }),
|
|
1849
|
-
/* @__PURE__ */ jsx("path", { d: "M17 12L16 11L15 12L16 13L17 12Z", fill: "white" }),
|
|
1850
|
-
/* @__PURE__ */ jsx("path", { d: "M12 17L14.5 14.5L13.5 13.5L12 15L10.5 13.5L9.5 14.5L12 17Z", fill: "white" }),
|
|
1851
|
-
/* @__PURE__ */ jsx("path", { d: "M12 11L11 12L12 13L13 12L12 11Z", fill: "white" })
|
|
1852
|
-
] }),
|
|
1853
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1854
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#FF0420" }),
|
|
1855
|
-
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "12", r: "3", fill: "white" }),
|
|
1856
|
-
/* @__PURE__ */ jsx("path", { d: "M14 9H17V10.5H15V11.5H17V13H15V15H14V9Z", fill: "white" })
|
|
1857
|
-
] }),
|
|
1858
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1859
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#E84142" }),
|
|
1860
|
-
/* @__PURE__ */ jsx("path", { d: "M8 16L12 8L16 16H13L12 14L11 16H8Z", fill: "white" })
|
|
1861
|
-
] }),
|
|
1862
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1863
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#0052FF" }),
|
|
1864
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5", stroke: "white", strokeWidth: "2" }),
|
|
1865
|
-
/* @__PURE__ */ jsx("path", { d: "M12 9V12H15", stroke: "white", strokeWidth: "2", strokeLinecap: "round" })
|
|
1866
|
-
] }),
|
|
1867
|
-
/* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1868
|
-
/* @__PURE__ */ jsx("rect", { width: "24", height: "24", rx: "8", fill: "#121212" }),
|
|
1869
|
-
/* @__PURE__ */ jsx("path", { d: "M7 17V7H9V15H17V17H7Z", fill: "white" })
|
|
1870
|
-
] }),
|
|
1871
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-chain-icons__more", children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "3", viewBox: "0 0 12 3", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1872
|
-
/* @__PURE__ */ jsx("circle", { cx: "1.5", cy: "1.5", r: "1.5", fill: "#666" }),
|
|
1873
|
-
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "1.5", r: "1.5", fill: "#666" }),
|
|
1874
|
-
/* @__PURE__ */ jsx("circle", { cx: "10.5", cy: "1.5", r: "1.5", fill: "#666" })
|
|
1875
|
-
] }) })
|
|
1876
|
-
] });
|
|
1877
|
-
}
|
|
1878
|
-
function ArrowButton({
|
|
1879
|
-
onClick,
|
|
1880
|
-
disabled,
|
|
1881
|
-
isLoading,
|
|
1882
|
-
title
|
|
1883
|
-
}) {
|
|
1884
|
-
return /* @__PURE__ */ jsx(
|
|
1885
|
-
"button",
|
|
1886
|
-
{
|
|
1887
|
-
className: "taskon-identity-social-btn",
|
|
1888
|
-
onClick,
|
|
1889
|
-
disabled: disabled || isLoading,
|
|
1890
|
-
title,
|
|
1891
|
-
children: isLoading ? /* @__PURE__ */ jsx("span", { className: "taskon-identity-social-btn__spinner" }) : /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1892
|
-
/* @__PURE__ */ jsx("path", { d: "M10.8225 4.44751L15.375 9.00001L10.8225 13.5525", stroke: "currentColor", strokeWidth: "1.5", strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
1893
|
-
/* @__PURE__ */ jsx("path", { d: "M2.625 9H15.2475", stroke: "currentColor", strokeWidth: "1.5", strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1894
|
-
] })
|
|
1895
|
-
}
|
|
1896
|
-
);
|
|
1897
|
-
}
|
|
1898
|
-
function CopyButton({ text }) {
|
|
1899
|
-
const [copied, setCopied] = useState(false);
|
|
1900
|
-
const handleCopy = useCallback(() => {
|
|
1901
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
1902
|
-
setCopied(true);
|
|
1903
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1904
|
-
});
|
|
1905
|
-
}, [text]);
|
|
1906
|
-
return /* @__PURE__ */ jsx(
|
|
1907
|
-
"button",
|
|
1908
|
-
{
|
|
1909
|
-
className: "taskon-network-copy-btn",
|
|
1910
|
-
onClick: handleCopy,
|
|
1911
|
-
title: copied ? "Copied!" : "Copy",
|
|
1912
|
-
children: copied ? (
|
|
1913
|
-
// 复制成功图标(勾选)
|
|
1914
|
-
/* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M3 7L6 10L11 4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1915
|
-
) : (
|
|
1916
|
-
// 复制图标
|
|
1917
|
-
/* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
1918
|
-
/* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1919
|
-
/* @__PURE__ */ jsx("path", { d: "M2 10V3C2 2.44772 2.44772 2 3 2H10", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
1920
|
-
] })
|
|
1921
|
-
)
|
|
1922
|
-
}
|
|
1923
|
-
);
|
|
1924
|
-
}
|
|
1925
|
-
function SocialAccountItem({
|
|
1926
|
-
data,
|
|
1927
|
-
onBind,
|
|
1928
|
-
onUnbind,
|
|
1929
|
-
isLoading,
|
|
1930
|
-
disabled,
|
|
1931
|
-
disabledReason,
|
|
1932
|
-
messages
|
|
1933
|
-
}) {
|
|
1934
|
-
const displayText = data.isBound && data.account ? data.account.sns_user_name : (messages.linkPlatformAccount ?? "Link {platform} Account").replace("{platform}", data.snsType);
|
|
1935
|
-
return /* @__PURE__ */ jsxs(
|
|
1936
|
-
"div",
|
|
1937
|
-
{
|
|
1938
|
-
className: `taskon-identity-social-item ${data.isBound ? "taskon-identity-social-item--bound" : ""} ${data.isBound && disabled ? "taskon-identity-social-item--unlink-disabled" : ""}`,
|
|
1939
|
-
children: [
|
|
1940
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-identity-social-item__content", children: [
|
|
1941
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-identity-social-item__icon", children: /* @__PURE__ */ jsx(SocialIcon, { type: data.snsType }) }),
|
|
1942
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-identity-social-item__text", children: data.isBound && data.profileUrl ? /* @__PURE__ */ jsx(
|
|
1943
|
-
"a",
|
|
1944
|
-
{
|
|
1945
|
-
href: data.profileUrl,
|
|
1946
|
-
target: "_blank",
|
|
1947
|
-
rel: "noopener noreferrer",
|
|
1948
|
-
className: "taskon-identity-social-item__link",
|
|
1949
|
-
children: displayText
|
|
1950
|
-
}
|
|
1951
|
-
) : /* @__PURE__ */ jsx("span", { className: "taskon-identity-social-item__name", children: displayText }) })
|
|
1952
|
-
] }),
|
|
1953
|
-
data.isBound ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1954
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-identity-social-item__linked", children: messages.linked ?? "Linked" }),
|
|
1955
|
-
!disabled && /* @__PURE__ */ jsx(
|
|
1956
|
-
"button",
|
|
1957
|
-
{
|
|
1958
|
-
className: "taskon-identity-social-item__unlink-btn",
|
|
1959
|
-
onClick: onUnbind,
|
|
1960
|
-
disabled: isLoading,
|
|
1961
|
-
"aria-label": messages.unbind ?? "Unbind",
|
|
1962
|
-
children: isLoading ? /* @__PURE__ */ jsx("span", { className: "taskon-identity-social-btn__spinner" }) : /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M11 3L3 11M3 3L11 11", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1963
|
-
}
|
|
1964
|
-
)
|
|
1965
|
-
] }) : (
|
|
1966
|
-
/* 未绑定状态:显示箭头按钮 */
|
|
1967
|
-
/* @__PURE__ */ jsx(
|
|
1968
|
-
ArrowButton,
|
|
1969
|
-
{
|
|
1970
|
-
onClick: onBind,
|
|
1971
|
-
disabled: false,
|
|
1972
|
-
isLoading
|
|
1973
|
-
}
|
|
1974
|
-
)
|
|
1975
|
-
)
|
|
1976
|
-
]
|
|
1977
|
-
}
|
|
1978
|
-
);
|
|
1979
|
-
}
|
|
1980
|
-
function WalletItem({
|
|
1981
|
-
data,
|
|
1982
|
-
addresses,
|
|
1983
|
-
onBind,
|
|
1984
|
-
onUnbind,
|
|
1985
|
-
isLoading,
|
|
1986
|
-
disabled,
|
|
1987
|
-
disabledReason,
|
|
1988
|
-
messages
|
|
1989
|
-
}) {
|
|
1990
|
-
const name = getChainName(data.coreChainType);
|
|
1991
|
-
const isEvm = data.coreChainType === "evm";
|
|
1992
|
-
if (isEvm && addresses && addresses.length > 0) {
|
|
1993
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-card taskon-network-card--multi", children: [
|
|
1994
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__header", children: /* @__PURE__ */ jsx("span", { className: "taskon-network-card__label", children: "EVM Chain" }) }),
|
|
1995
|
-
/* @__PURE__ */ jsx(EvmChainIcons, {}),
|
|
1996
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__addresses", children: addresses.map((addr, index) => {
|
|
1997
|
-
var _a, _b, _c;
|
|
1998
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-address-row", children: [
|
|
1999
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-network-address-row__left", children: [
|
|
2000
|
-
/* @__PURE__ */ jsx("span", { className: `taskon-network-address-row__addr ${!addr.isPrimary ? "taskon-network-address-row__addr--secondary" : ""}`, children: truncateAddress(((_a = addr.address) == null ? void 0 : _a.address) ?? "") }),
|
|
2001
|
-
/* @__PURE__ */ jsx(CopyButton, { text: ((_b = addr.address) == null ? void 0 : _b.address) ?? "" })
|
|
2002
|
-
] }),
|
|
2003
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-address-row__divider" }),
|
|
2004
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-network-address-row__right", children: [
|
|
2005
|
-
/* @__PURE__ */ jsx("span", { className: `taskon-network-address-row__type ${addr.isPrimary ? "taskon-network-address-row__type--primary" : "taskon-network-address-row__type--secondary"}`, children: addr.isPrimary ? "Primary Address" : "Secondary Address" }),
|
|
2006
|
-
/* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "taskon-network-address-row__edit", children: [
|
|
2007
|
-
/* @__PURE__ */ jsx("path", { d: "M2 12H4L10.5 5.5L8.5 3.5L2 10V12Z", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
2008
|
-
/* @__PURE__ */ jsx("path", { d: "M8.5 3.5L10.5 5.5", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" })
|
|
2009
|
-
] })
|
|
2010
|
-
] }),
|
|
2011
|
-
/* @__PURE__ */ jsx(
|
|
2012
|
-
"button",
|
|
2013
|
-
{
|
|
2014
|
-
className: "taskon-network-unbind-badge",
|
|
2015
|
-
onClick: () => {
|
|
2016
|
-
var _a2;
|
|
2017
|
-
return onUnbind((_a2 = addr.address) == null ? void 0 : _a2.address);
|
|
2018
|
-
},
|
|
2019
|
-
disabled: isLoading || disabled,
|
|
2020
|
-
title: disabledReason,
|
|
2021
|
-
children: messages.unbind ?? "Unbind"
|
|
2022
|
-
}
|
|
2023
|
-
)
|
|
2024
|
-
] }, ((_c = addr.address) == null ? void 0 : _c.address) ?? index);
|
|
2025
|
-
}) })
|
|
2026
|
-
] });
|
|
2027
|
-
}
|
|
2028
|
-
if (isEvm && !data.isBound) {
|
|
2029
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-card taskon-network-card--multi", children: [
|
|
2030
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__header", children: /* @__PURE__ */ jsx("span", { className: "taskon-network-card__label", children: "EVM Chain" }) }),
|
|
2031
|
-
/* @__PURE__ */ jsx(EvmChainIcons, {}),
|
|
2032
|
-
/* @__PURE__ */ jsx(
|
|
2033
|
-
"button",
|
|
2034
|
-
{
|
|
2035
|
-
className: "taskon-network-connect-btn",
|
|
2036
|
-
onClick: onBind,
|
|
2037
|
-
disabled: isLoading,
|
|
2038
|
-
children: isLoading ? messages.loading : messages.connectWallet ?? "Connect Wallet"
|
|
2039
|
-
}
|
|
2040
|
-
)
|
|
2041
|
-
] });
|
|
2042
|
-
}
|
|
2043
|
-
if (data.isBound && data.address) {
|
|
2044
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-card taskon-network-card--single", children: [
|
|
2045
|
-
/* @__PURE__ */ jsx(
|
|
2046
|
-
"button",
|
|
2047
|
-
{
|
|
2048
|
-
className: "taskon-network-unbind-badge taskon-network-unbind-badge--corner",
|
|
2049
|
-
onClick: () => onUnbind(),
|
|
2050
|
-
disabled: isLoading || disabled,
|
|
2051
|
-
title: disabledReason,
|
|
2052
|
-
children: messages.unbind ?? "Unbind"
|
|
2053
|
-
}
|
|
2054
|
-
),
|
|
2055
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__header", children: /* @__PURE__ */ jsx("span", { className: "taskon-network-card__label", children: name }) }),
|
|
2056
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__chain-icon", children: /* @__PURE__ */ jsx(ChainIcon, { chain: data.coreChainType }) }),
|
|
2057
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-network-address-input", children: [
|
|
2058
|
-
/* @__PURE__ */ jsx("span", { className: "taskon-network-address-input__text", children: truncateAddress(data.address.address) }),
|
|
2059
|
-
/* @__PURE__ */ jsx(CopyButton, { text: data.address.address })
|
|
2060
|
-
] })
|
|
2061
|
-
] });
|
|
2062
|
-
}
|
|
2063
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-network-card taskon-network-card--single", children: [
|
|
2064
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__header", children: /* @__PURE__ */ jsx("span", { className: "taskon-network-card__label", children: name }) }),
|
|
2065
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-card__chain-icon", children: /* @__PURE__ */ jsx(ChainIcon, { chain: data.coreChainType }) }),
|
|
2066
|
-
/* @__PURE__ */ jsx(
|
|
2067
|
-
"button",
|
|
2068
|
-
{
|
|
2069
|
-
className: "taskon-network-connect-btn",
|
|
2070
|
-
onClick: onBind,
|
|
2071
|
-
disabled: isLoading,
|
|
2072
|
-
children: isLoading ? messages.loading : messages.connectWallet ?? "Connect Wallet"
|
|
2073
|
-
}
|
|
2074
|
-
)
|
|
2075
|
-
] });
|
|
2076
|
-
}
|
|
2077
|
-
function WarningIcon() {
|
|
2078
|
-
return /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
|
|
2079
|
-
"path",
|
|
2080
|
-
{
|
|
2081
|
-
d: "M12 9V13M12 17H12.01M10.29 3.86L1.82 18C1.64 18.3 1.55 18.65 1.55 19C1.56 19.35 1.65 19.69 1.82 20C2 20.3 2.25 20.56 2.55 20.73C2.85 20.91 3.19 21 3.54 21H20.46C20.81 21 21.15 20.91 21.45 20.73C21.75 20.56 22 20.3 22.18 20C22.35 19.69 22.44 19.35 22.45 19C22.45 18.65 22.36 18.3 22.18 18L13.71 3.86C13.53 3.56 13.28 3.32 12.98 3.15C12.68 2.98 12.34 2.89 12 2.89C11.66 2.89 11.32 2.98 11.02 3.15C10.72 3.32 10.47 3.56 10.29 3.86Z",
|
|
2082
|
-
stroke: "currentColor",
|
|
2083
|
-
strokeWidth: "2",
|
|
2084
|
-
strokeLinecap: "round",
|
|
2085
|
-
strokeLinejoin: "round"
|
|
2086
|
-
}
|
|
2087
|
-
) });
|
|
2088
|
-
}
|
|
2089
|
-
function ConfirmUnlinkDialog({
|
|
2090
|
-
open,
|
|
2091
|
-
onOpenChange,
|
|
2092
|
-
onConfirm,
|
|
2093
|
-
onCancel,
|
|
2094
|
-
loading = false,
|
|
2095
|
-
messages
|
|
2096
|
-
}) {
|
|
2097
|
-
return /* @__PURE__ */ jsx(
|
|
2098
|
-
Dialog,
|
|
2099
|
-
{
|
|
2100
|
-
open,
|
|
2101
|
-
onOpenChange,
|
|
2102
|
-
title: messages.confirmUnbind,
|
|
2103
|
-
showCloseButton: false,
|
|
2104
|
-
maxWidth: 400,
|
|
2105
|
-
children: /* @__PURE__ */ jsxs("div", { className: "taskon-confirm-unlink", children: [
|
|
2106
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-confirm-unlink__icon", children: /* @__PURE__ */ jsx(WarningIcon, {}) }),
|
|
2107
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-confirm-unlink__text", children: [
|
|
2108
|
-
/* @__PURE__ */ jsx("h4", { className: "taskon-confirm-unlink__title", children: messages.confirmUnbind }),
|
|
2109
|
-
/* @__PURE__ */ jsx("p", { className: "taskon-confirm-unlink__description", children: messages.unbindWarning })
|
|
2110
|
-
] }),
|
|
2111
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-confirm-unlink__actions", children: [
|
|
2112
|
-
/* @__PURE__ */ jsx(
|
|
2113
|
-
"button",
|
|
2114
|
-
{
|
|
2115
|
-
className: "taskon-confirm-unlink__btn taskon-confirm-unlink__btn--cancel",
|
|
2116
|
-
onClick: onCancel,
|
|
2117
|
-
disabled: loading,
|
|
2118
|
-
children: messages.cancel
|
|
2119
|
-
}
|
|
2120
|
-
),
|
|
2121
|
-
/* @__PURE__ */ jsx(
|
|
2122
|
-
"button",
|
|
2123
|
-
{
|
|
2124
|
-
className: "taskon-confirm-unlink__btn taskon-confirm-unlink__btn--confirm",
|
|
2125
|
-
onClick: onConfirm,
|
|
2126
|
-
disabled: loading,
|
|
2127
|
-
children: loading ? messages.unbinding : messages.confirm
|
|
2128
|
-
}
|
|
2129
|
-
)
|
|
2130
|
-
] })
|
|
2131
|
-
] })
|
|
2132
|
-
}
|
|
2133
|
-
);
|
|
2134
|
-
}
|
|
2135
|
-
function SocialAccountsSection({
|
|
2136
|
-
accounts,
|
|
2137
|
-
messages,
|
|
2138
|
-
onBind,
|
|
2139
|
-
onUnbind,
|
|
2140
|
-
isProcessing,
|
|
2141
|
-
checkUnlink,
|
|
2142
|
-
onShowWarning
|
|
2143
|
-
}) {
|
|
2144
|
-
if (accounts.length === 0) {
|
|
2145
|
-
return null;
|
|
2146
|
-
}
|
|
2147
|
-
const [confirmTarget, setConfirmTarget] = useState(null);
|
|
2148
|
-
const showConfirm = confirmTarget !== null;
|
|
2149
|
-
const handleBind = useCallback(
|
|
2150
|
-
(account) => {
|
|
2151
|
-
onBind(account.snsType);
|
|
2152
|
-
},
|
|
2153
|
-
[onBind]
|
|
2154
|
-
);
|
|
2155
|
-
const handleUnbind = useCallback(
|
|
2156
|
-
(account) => {
|
|
2157
|
-
if (!account.account) return;
|
|
2158
|
-
const check = checkUnlink(account.account);
|
|
2159
|
-
if (check.disabled) {
|
|
2160
|
-
onShowWarning(check.message ?? messages.unbindFailed);
|
|
2161
|
-
return;
|
|
2162
|
-
}
|
|
2163
|
-
setConfirmTarget(account);
|
|
2164
|
-
},
|
|
2165
|
-
[checkUnlink, onShowWarning, messages]
|
|
2166
|
-
);
|
|
2167
|
-
const handleConfirmUnbind = useCallback(() => {
|
|
2168
|
-
if (!(confirmTarget == null ? void 0 : confirmTarget.account)) return;
|
|
2169
|
-
onUnbind(confirmTarget.account.sns_id, confirmTarget.snsType);
|
|
2170
|
-
setConfirmTarget(null);
|
|
2171
|
-
}, [confirmTarget, onUnbind]);
|
|
2172
|
-
return /* @__PURE__ */ jsxs("section", { className: "taskon-identity-social-section", children: [
|
|
2173
|
-
/* @__PURE__ */ jsx("h3", { className: "taskon-identity-social-section__title", children: messages.socialAccounts ?? "Social Media Accounts" }),
|
|
2174
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-identity-social-grid", children: accounts.map((account) => {
|
|
2175
|
-
const check = account.account ? checkUnlink(account.account) : { disabled: false, message: null };
|
|
2176
|
-
return /* @__PURE__ */ jsx(
|
|
2177
|
-
SocialAccountItem,
|
|
2178
|
-
{
|
|
2179
|
-
data: account,
|
|
2180
|
-
onBind: () => handleBind(account),
|
|
2181
|
-
onUnbind: () => handleUnbind(account),
|
|
2182
|
-
isLoading: isProcessing(account.snsType),
|
|
2183
|
-
disabled: check.disabled,
|
|
2184
|
-
disabledReason: check.message ?? void 0,
|
|
2185
|
-
messages
|
|
2186
|
-
},
|
|
2187
|
-
account.snsType
|
|
2188
|
-
);
|
|
2189
|
-
}) }),
|
|
2190
|
-
/* @__PURE__ */ jsx(
|
|
2191
|
-
ConfirmUnlinkDialog,
|
|
2192
|
-
{
|
|
2193
|
-
open: showConfirm,
|
|
2194
|
-
onOpenChange: (open) => {
|
|
2195
|
-
if (!open) setConfirmTarget(null);
|
|
2196
|
-
},
|
|
2197
|
-
onConfirm: handleConfirmUnbind,
|
|
2198
|
-
onCancel: () => setConfirmTarget(null),
|
|
2199
|
-
loading: confirmTarget ? isProcessing(confirmTarget.snsType) : false,
|
|
2200
|
-
messages
|
|
2201
|
-
}
|
|
2202
|
-
)
|
|
2203
|
-
] });
|
|
2204
|
-
}
|
|
2205
|
-
function WalletsSection({
|
|
2206
|
-
wallets,
|
|
2207
|
-
rawAddresses,
|
|
2208
|
-
messages,
|
|
2209
|
-
onBind,
|
|
2210
|
-
onUnbind,
|
|
2211
|
-
isProcessing,
|
|
2212
|
-
checkUnlink,
|
|
2213
|
-
onShowWarning,
|
|
2214
|
-
onShowInfo
|
|
2215
|
-
}) {
|
|
2216
|
-
if (wallets.length === 0) {
|
|
2217
|
-
return null;
|
|
2218
|
-
}
|
|
2219
|
-
const evmAddresses = useMemo(() => {
|
|
2220
|
-
return rawAddresses.filter((addr) => addr.chain_type === "evm").map((addr) => ({
|
|
2221
|
-
chainType: "EVM",
|
|
2222
|
-
// UserCenterChainType.EVM
|
|
2223
|
-
coreChainType: "evm",
|
|
2224
|
-
isBound: true,
|
|
2225
|
-
address: addr,
|
|
2226
|
-
isPrimary: addr.is_primary ?? false,
|
|
2227
|
-
isKycVerified: void 0
|
|
2228
|
-
}));
|
|
2229
|
-
}, [rawAddresses]);
|
|
2230
|
-
const [confirmTarget, setConfirmTarget] = useState(null);
|
|
2231
|
-
const showConfirm = confirmTarget !== null;
|
|
2232
|
-
const handleBind = useCallback(
|
|
2233
|
-
(wallet) => {
|
|
2234
|
-
onBind(wallet.coreChainType);
|
|
2235
|
-
},
|
|
2236
|
-
[onBind]
|
|
2237
|
-
);
|
|
2238
|
-
const handleUnbind = useCallback(
|
|
2239
|
-
(wallet, specificAddress) => {
|
|
2240
|
-
var _a;
|
|
2241
|
-
const addressToUnbind = specificAddress ?? ((_a = wallet.address) == null ? void 0 : _a.address);
|
|
2242
|
-
if (!addressToUnbind || !wallet.address) return;
|
|
2243
|
-
const check = checkUnlink(wallet.address, wallet.isKycVerified);
|
|
2244
|
-
if (check.disabled) {
|
|
2245
|
-
onShowWarning(check.message ?? messages.unbindFailed);
|
|
2246
|
-
return;
|
|
2247
|
-
}
|
|
2248
|
-
if (check.needsKycWarning) {
|
|
2249
|
-
onShowInfo(messages.kycWarning);
|
|
2250
|
-
}
|
|
2251
|
-
setConfirmTarget({ wallet, address: addressToUnbind });
|
|
2252
|
-
},
|
|
2253
|
-
[checkUnlink, onShowWarning, onShowInfo, messages]
|
|
2254
|
-
);
|
|
2255
|
-
const handleConfirmUnbind = useCallback(() => {
|
|
2256
|
-
if (!confirmTarget) return;
|
|
2257
|
-
onUnbind(confirmTarget.wallet.coreChainType, confirmTarget.address);
|
|
2258
|
-
setConfirmTarget(null);
|
|
2259
|
-
}, [confirmTarget, onUnbind]);
|
|
2260
|
-
return /* @__PURE__ */ jsxs("section", { className: "taskon-network-section", children: [
|
|
2261
|
-
/* @__PURE__ */ jsx("h3", { className: "taskon-network-section__title", children: messages.walletAddresses ?? "Network List" }),
|
|
2262
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-network-grid", children: wallets.map((wallet) => {
|
|
2263
|
-
const check = wallet.address ? checkUnlink(wallet.address, wallet.isKycVerified) : { disabled: false, message: null };
|
|
2264
|
-
const isEvm = wallet.coreChainType === "evm";
|
|
2265
|
-
return /* @__PURE__ */ jsx(
|
|
2266
|
-
WalletItem,
|
|
2267
|
-
{
|
|
2268
|
-
data: wallet,
|
|
2269
|
-
addresses: isEvm && evmAddresses.length > 0 ? evmAddresses : void 0,
|
|
2270
|
-
onBind: () => handleBind(wallet),
|
|
2271
|
-
onUnbind: (addr) => handleUnbind(wallet, addr),
|
|
2272
|
-
isLoading: isProcessing(wallet.chainType),
|
|
2273
|
-
disabled: check.disabled,
|
|
2274
|
-
disabledReason: check.message ?? void 0,
|
|
2275
|
-
messages
|
|
2276
|
-
},
|
|
2277
|
-
wallet.coreChainType
|
|
2278
|
-
);
|
|
2279
|
-
}) }),
|
|
2280
|
-
/* @__PURE__ */ jsx(
|
|
2281
|
-
ConfirmUnlinkDialog,
|
|
2282
|
-
{
|
|
2283
|
-
open: showConfirm,
|
|
2284
|
-
onOpenChange: (open) => {
|
|
2285
|
-
if (!open) setConfirmTarget(null);
|
|
2286
|
-
},
|
|
2287
|
-
onConfirm: handleConfirmUnbind,
|
|
2288
|
-
onCancel: () => setConfirmTarget(null),
|
|
2289
|
-
loading: confirmTarget ? isProcessing(confirmTarget.wallet.chainType) : false,
|
|
2290
|
-
messages
|
|
2291
|
-
}
|
|
2292
|
-
)
|
|
2293
|
-
] });
|
|
2294
|
-
}
|
|
2295
|
-
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2296
|
-
function EmailBindDialog({
|
|
2297
|
-
visible,
|
|
2298
|
-
status,
|
|
2299
|
-
countdown,
|
|
2300
|
-
isEmailDuplicate,
|
|
2301
|
-
isCodeInvalid,
|
|
2302
|
-
messages,
|
|
2303
|
-
onClose,
|
|
2304
|
-
onSendCode,
|
|
2305
|
-
onBind,
|
|
2306
|
-
onClearError
|
|
2307
|
-
}) {
|
|
2308
|
-
const [email, setEmail] = useState("");
|
|
2309
|
-
const [code, setCode] = useState("");
|
|
2310
|
-
const isEmailValid = useMemo(() => EMAIL_REGEX.test(email), [email]);
|
|
2311
|
-
const isCodeValid = useMemo(() => code.length >= 4, [code]);
|
|
2312
|
-
const isSending = status === "sendingCode";
|
|
2313
|
-
const isSubmitting = status === "submitting";
|
|
2314
|
-
const showCodeInput = status === "inputCode" || status === "submitting" || status === "success";
|
|
2315
|
-
const emailError = useMemo(() => {
|
|
2316
|
-
if (isEmailDuplicate) {
|
|
2317
|
-
return messages.emailAlreadyLinked ?? "This email is already linked to another account";
|
|
2318
|
-
}
|
|
2319
|
-
if (email && !isEmailValid) {
|
|
2320
|
-
return messages.pleaseEnterValidEmail ?? "Please enter a valid email address";
|
|
2321
|
-
}
|
|
2322
|
-
return void 0;
|
|
2323
|
-
}, [isEmailDuplicate, email, isEmailValid, messages]);
|
|
2324
|
-
const codeError = useMemo(() => {
|
|
2325
|
-
if (isCodeInvalid) {
|
|
2326
|
-
return messages.pleaseEnterValidCode ?? "Please enter a valid verification code";
|
|
2327
|
-
}
|
|
2328
|
-
return void 0;
|
|
2329
|
-
}, [isCodeInvalid, messages]);
|
|
2330
|
-
const handleEmailChange = useCallback(
|
|
2331
|
-
(value) => {
|
|
2332
|
-
setEmail(value);
|
|
2333
|
-
onClearError();
|
|
2334
|
-
},
|
|
2335
|
-
[onClearError]
|
|
2336
|
-
);
|
|
2337
|
-
const handleCodeChange = useCallback(
|
|
2338
|
-
(value) => {
|
|
2339
|
-
const numericValue = value.replace(/[^0-9]/g, "").slice(0, 6);
|
|
2340
|
-
setCode(numericValue);
|
|
2341
|
-
onClearError();
|
|
2342
|
-
},
|
|
2343
|
-
[onClearError]
|
|
2344
|
-
);
|
|
2345
|
-
const handleSendCode = useCallback(async () => {
|
|
2346
|
-
if (!isEmailValid || isSending) return;
|
|
2347
|
-
await onSendCode(email);
|
|
2348
|
-
}, [email, isEmailValid, isSending, onSendCode]);
|
|
2349
|
-
const handleBind = useCallback(async () => {
|
|
2350
|
-
if (!isEmailValid || !isCodeValid || isSubmitting) return;
|
|
2351
|
-
const result = await onBind(email, code);
|
|
2352
|
-
if (result == null ? void 0 : result.result) {
|
|
2353
|
-
setEmail("");
|
|
2354
|
-
setCode("");
|
|
2355
|
-
onClose();
|
|
2356
|
-
}
|
|
2357
|
-
}, [email, code, isEmailValid, isCodeValid, isSubmitting, onBind, onClose]);
|
|
2358
|
-
const handleClose = useCallback(() => {
|
|
2359
|
-
setEmail("");
|
|
2360
|
-
setCode("");
|
|
2361
|
-
onClose();
|
|
2362
|
-
}, [onClose]);
|
|
2363
|
-
return /* @__PURE__ */ jsx(
|
|
2364
|
-
Dialog,
|
|
2365
|
-
{
|
|
2366
|
-
open: visible,
|
|
2367
|
-
onOpenChange: (open) => {
|
|
2368
|
-
if (!open) handleClose();
|
|
2369
|
-
},
|
|
2370
|
-
title: messages.linkEmailAccount ?? "Link Email Account",
|
|
2371
|
-
showCloseButton: true,
|
|
2372
|
-
maxWidth: 400,
|
|
2373
|
-
children: /* @__PURE__ */ jsxs("div", { className: "taskon-email-bind-dialog", children: [
|
|
2374
|
-
/* @__PURE__ */ jsx("h2", { className: "taskon-email-bind-dialog__title", children: messages.linkEmailAccount ?? "Link Email Account" }),
|
|
2375
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-email-bind-dialog__field", children: [
|
|
2376
|
-
/* @__PURE__ */ jsx("label", { className: "taskon-email-bind-dialog__label", children: messages.emailAddress ?? "Email Address" }),
|
|
2377
|
-
/* @__PURE__ */ jsx(
|
|
2378
|
-
Input,
|
|
2379
|
-
{
|
|
2380
|
-
type: "email",
|
|
2381
|
-
value: email,
|
|
2382
|
-
onChange: handleEmailChange,
|
|
2383
|
-
placeholder: messages.pleaseEnterEmail ?? "Please enter email address",
|
|
2384
|
-
maxLength: 64,
|
|
2385
|
-
disabled: showCodeInput,
|
|
2386
|
-
error: emailError,
|
|
2387
|
-
onBlur: () => setEmail(email.trim())
|
|
2388
|
-
}
|
|
2389
|
-
)
|
|
2390
|
-
] }),
|
|
2391
|
-
showCodeInput && /* @__PURE__ */ jsxs("div", { className: "taskon-email-bind-dialog__field", children: [
|
|
2392
|
-
/* @__PURE__ */ jsx("label", { className: "taskon-email-bind-dialog__label", children: messages.verificationCode ?? "Verification Code" }),
|
|
2393
|
-
/* @__PURE__ */ jsx(
|
|
2394
|
-
Input,
|
|
2395
|
-
{
|
|
2396
|
-
type: "text",
|
|
2397
|
-
inputMode: "numeric",
|
|
2398
|
-
value: code,
|
|
2399
|
-
onChange: handleCodeChange,
|
|
2400
|
-
placeholder: messages.pleaseEnterCode ?? "Please enter verification code",
|
|
2401
|
-
maxLength: 6,
|
|
2402
|
-
disabled: isSubmitting,
|
|
2403
|
-
error: codeError,
|
|
2404
|
-
rightSlot: /* @__PURE__ */ jsx(
|
|
2405
|
-
Button,
|
|
2406
|
-
{
|
|
2407
|
-
variant: "ghost",
|
|
2408
|
-
size: "small",
|
|
2409
|
-
disabled: countdown > 0 || isSending,
|
|
2410
|
-
loading: isSending,
|
|
2411
|
-
onClick: handleSendCode,
|
|
2412
|
-
children: countdown > 0 ? `${messages.resendCode ?? "Resend"} (${countdown}s)` : messages.resendCode ?? "Resend"
|
|
2413
|
-
}
|
|
2414
|
-
)
|
|
2415
|
-
}
|
|
2416
|
-
)
|
|
2417
|
-
] }),
|
|
2418
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-email-bind-dialog__actions", children: !showCodeInput ? (
|
|
2419
|
-
/* 发送验证码按钮 */
|
|
2420
|
-
/* @__PURE__ */ jsx(
|
|
2421
|
-
Button,
|
|
2422
|
-
{
|
|
2423
|
-
variant: "primary",
|
|
2424
|
-
size: "large",
|
|
2425
|
-
disabled: !isEmailValid || isSending,
|
|
2426
|
-
loading: isSending,
|
|
2427
|
-
onClick: handleSendCode,
|
|
2428
|
-
style: { width: "100%" },
|
|
2429
|
-
children: messages.sendVerificationCode ?? "Send Verification Code"
|
|
2430
|
-
}
|
|
2431
|
-
)
|
|
2432
|
-
) : (
|
|
2433
|
-
/* 确认绑定按钮 */
|
|
2434
|
-
/* @__PURE__ */ jsx(
|
|
2435
|
-
Button,
|
|
2436
|
-
{
|
|
2437
|
-
variant: "primary",
|
|
2438
|
-
size: "large",
|
|
2439
|
-
disabled: !isEmailValid || !isCodeValid || isSubmitting,
|
|
2440
|
-
loading: isSubmitting,
|
|
2441
|
-
onClick: handleBind,
|
|
2442
|
-
style: { width: "100%" },
|
|
2443
|
-
children: messages.confirm ?? "Confirm"
|
|
2444
|
-
}
|
|
2445
|
-
)
|
|
2446
|
-
) })
|
|
2447
|
-
] })
|
|
2448
|
-
}
|
|
2449
|
-
);
|
|
2450
|
-
}
|
|
2451
|
-
function EmailSection({
|
|
2452
|
-
emailAccount,
|
|
2453
|
-
messages,
|
|
2454
|
-
onUnbind,
|
|
2455
|
-
isUnbinding,
|
|
2456
|
-
checkUnlink,
|
|
2457
|
-
onShowSuccess,
|
|
2458
|
-
onShowError,
|
|
2459
|
-
onShowWarning
|
|
2460
|
-
}) {
|
|
2461
|
-
const [dialogVisible, setDialogVisible] = useState(false);
|
|
2462
|
-
const {
|
|
2463
|
-
status: emailBindStatus,
|
|
2464
|
-
countdown: emailCountdown,
|
|
2465
|
-
isEmailDuplicate,
|
|
2466
|
-
isCodeInvalid,
|
|
2467
|
-
sendCode: sendEmailCode,
|
|
2468
|
-
bind: bindEmail,
|
|
2469
|
-
reset: resetEmailBind,
|
|
2470
|
-
clearError: clearEmailError
|
|
2471
|
-
} = useBindEmail({
|
|
2472
|
-
onSendCodeSuccess: () => {
|
|
2473
|
-
onShowSuccess(messages.sendCodeSuccess ?? "Verification code sent");
|
|
2474
|
-
},
|
|
2475
|
-
onSendCodeError: (error) => {
|
|
2476
|
-
if (!error.message.includes("duplicate")) {
|
|
2477
|
-
onShowError(messages.sendCodeFailed ?? "Failed to send verification code");
|
|
2478
|
-
}
|
|
2479
|
-
},
|
|
2480
|
-
onBindSuccess: () => {
|
|
2481
|
-
onShowSuccess(messages.bindSuccess);
|
|
2482
|
-
setDialogVisible(false);
|
|
2483
|
-
},
|
|
2484
|
-
onBindError: () => {
|
|
2485
|
-
onShowError(messages.bindFailed);
|
|
2486
|
-
}
|
|
2487
|
-
});
|
|
2488
|
-
const handleBind = useCallback(() => {
|
|
2489
|
-
setDialogVisible(true);
|
|
2490
|
-
}, []);
|
|
2491
|
-
const handleUnbind = useCallback(() => {
|
|
2492
|
-
if (!emailAccount.account) return;
|
|
2493
|
-
const check2 = checkUnlink(emailAccount.account);
|
|
2494
|
-
if (check2.disabled) {
|
|
2495
|
-
onShowWarning(check2.message ?? messages.unbindFailed);
|
|
2496
|
-
return;
|
|
2497
|
-
}
|
|
2498
|
-
onUnbind(emailAccount.account.sns_id, "Email");
|
|
2499
|
-
}, [emailAccount, checkUnlink, onUnbind, onShowWarning, messages]);
|
|
2500
|
-
const handleDialogClose = useCallback(() => {
|
|
2501
|
-
setDialogVisible(false);
|
|
2502
|
-
resetEmailBind();
|
|
2503
|
-
}, [resetEmailBind]);
|
|
2504
|
-
const check = emailAccount.account ? checkUnlink(emailAccount.account) : { disabled: false, message: null };
|
|
2505
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2506
|
-
/* @__PURE__ */ jsxs("section", { className: "taskon-identity-email-section", children: [
|
|
2507
|
-
/* @__PURE__ */ jsx("h3", { className: "taskon-identity-email-section__title", children: messages.emailAddress ?? "Email Address" }),
|
|
2508
|
-
/* @__PURE__ */ jsx("div", { className: "taskon-identity-email-card", children: /* @__PURE__ */ jsx(
|
|
2509
|
-
SocialAccountItem,
|
|
2510
|
-
{
|
|
2511
|
-
data: emailAccount,
|
|
2512
|
-
onBind: handleBind,
|
|
2513
|
-
onUnbind: handleUnbind,
|
|
2514
|
-
isLoading: isUnbinding,
|
|
2515
|
-
disabled: check.disabled,
|
|
2516
|
-
disabledReason: check.message ?? void 0,
|
|
2517
|
-
messages
|
|
2518
|
-
}
|
|
2519
|
-
) })
|
|
2520
|
-
] }),
|
|
2521
|
-
/* @__PURE__ */ jsx(
|
|
2522
|
-
EmailBindDialog,
|
|
2523
|
-
{
|
|
2524
|
-
visible: dialogVisible,
|
|
2525
|
-
status: emailBindStatus,
|
|
2526
|
-
countdown: emailCountdown,
|
|
2527
|
-
isEmailDuplicate,
|
|
2528
|
-
isCodeInvalid,
|
|
2529
|
-
messages,
|
|
2530
|
-
onClose: handleDialogClose,
|
|
2531
|
-
onSendCode: sendEmailCode,
|
|
2532
|
-
onBind: bindEmail,
|
|
2533
|
-
onClearError: clearEmailError
|
|
2534
|
-
}
|
|
2535
|
-
)
|
|
2536
|
-
] });
|
|
2537
|
-
}
|
|
2538
|
-
const USER_CENTER_WALLET_ACCOUNT_TYPE = String(SnsType.All).toLowerCase();
|
|
2539
|
-
const isWalletAccountType = (accountType) => accountType.toLowerCase() === USER_CENTER_WALLET_ACCOUNT_TYPE;
|
|
2540
|
-
function IdentityContent({
|
|
2541
|
-
config,
|
|
2542
|
-
messages
|
|
2543
|
-
}) {
|
|
2544
|
-
var _a, _b, _c, _d;
|
|
2545
|
-
const identityTab = config.find((t) => t.tab === "Identity");
|
|
2546
|
-
const enabledAccounts = identityTab ? filterEnabledAccounts(identityTab) : [];
|
|
2547
|
-
const enabledWallets = identityTab ? filterEnabledWallets(identityTab) : [];
|
|
2548
|
-
const identityParams = identityTab && !Array.isArray(identityTab.params) ? identityTab.params : void 0;
|
|
2549
|
-
const walletAccountOption = (_a = identityParams == null ? void 0 : identityParams.accountOptions) == null ? void 0 : _a.find(
|
|
2550
|
-
(account) => isWalletAccountType(String(account.account))
|
|
2551
|
-
);
|
|
2552
|
-
const isWalletAccountEnabled = walletAccountOption ? walletAccountOption.enabled !== false : true;
|
|
2553
|
-
const hasExplicitAccountConfig = (((_b = identityParams == null ? void 0 : identityParams.accountOptions) == null ? void 0 : _b.length) ?? 0) > 0;
|
|
2554
|
-
const hasExplicitWalletConfig = (((_c = walletAccountOption == null ? void 0 : walletAccountOption.walletOptions) == null ? void 0 : _c.length) ?? 0) > 0 || (((_d = identityParams == null ? void 0 : identityParams.walletOptions) == null ? void 0 : _d.length) ?? 0) > 0;
|
|
2555
|
-
const { socialAccounts, walletAddresses, rawAddresses, isLoaded } = useIdentityData();
|
|
2556
|
-
const { checkSocialUnlink, checkWalletUnlink } = useDisableUnlink();
|
|
2557
|
-
const { toast } = useToast();
|
|
2558
|
-
const {
|
|
2559
|
-
unbind: unbindSocial,
|
|
2560
|
-
unbindStatus: socialUnbindStatus,
|
|
2561
|
-
processingType: socialProcessingType
|
|
2562
|
-
} = useUnbindSocial({
|
|
2563
|
-
onUnbindSuccess: () => {
|
|
2564
|
-
toast.success(messages.unbindSuccess);
|
|
2565
|
-
},
|
|
2566
|
-
onUnbindError: () => {
|
|
2567
|
-
toast.error(messages.unbindFailed);
|
|
2568
|
-
}
|
|
2569
|
-
});
|
|
2570
|
-
const { bind: bindOAuth, isBinding: isOAuthBinding, isOAuthSupported } = useOAuthBindings({
|
|
2571
|
-
onSuccess: () => {
|
|
2572
|
-
toast.success(messages.bindSuccess);
|
|
2573
|
-
},
|
|
2574
|
-
onFailed: (error) => {
|
|
2575
|
-
toast.error(error || messages.bindFailed);
|
|
2576
|
-
}
|
|
2577
|
-
});
|
|
2578
|
-
const {
|
|
2579
|
-
bind: bindWallet,
|
|
2580
|
-
unbind: unbindWallet,
|
|
2581
|
-
bindStatus: walletBindStatus,
|
|
2582
|
-
unbindStatus: walletUnbindStatus,
|
|
2583
|
-
processingChain: walletProcessingChain
|
|
2584
|
-
} = useBindWallet({
|
|
2585
|
-
onBindSuccess: () => {
|
|
2586
|
-
toast.success(messages.bindSuccess);
|
|
2587
|
-
},
|
|
2588
|
-
onUnbindSuccess: () => {
|
|
2589
|
-
toast.success(messages.unbindSuccess);
|
|
2590
|
-
},
|
|
2591
|
-
onBindError: () => {
|
|
2592
|
-
toast.error(messages.bindFailed);
|
|
2593
|
-
},
|
|
2594
|
-
onUnbindError: () => {
|
|
2595
|
-
toast.error(messages.unbindFailed);
|
|
2596
|
-
}
|
|
2597
|
-
});
|
|
2598
|
-
const enabledSocialAccountTypes = useMemo(() => {
|
|
2599
|
-
return new Set(
|
|
2600
|
-
enabledAccounts.filter((account) => !isWalletAccountType(String(account.account))).map((account) => String(account.account).toLowerCase())
|
|
2601
|
-
);
|
|
2602
|
-
}, [enabledAccounts]);
|
|
2603
|
-
const enabledWalletChainTypes = useMemo(() => {
|
|
2604
|
-
return new Set(
|
|
2605
|
-
enabledWallets.map((wallet) => String(wallet.chain).toLowerCase())
|
|
2606
|
-
);
|
|
2607
|
-
}, [enabledWallets]);
|
|
2608
|
-
const filteredSocialAccounts = useMemo(() => {
|
|
2609
|
-
return socialAccounts.filter((account) => {
|
|
2610
|
-
if (isWalletAccountType(String(account.snsType))) {
|
|
2611
|
-
return false;
|
|
2612
|
-
}
|
|
2613
|
-
if (!hasExplicitAccountConfig) {
|
|
2614
|
-
return true;
|
|
2615
|
-
}
|
|
2616
|
-
return enabledSocialAccountTypes.has(account.snsType.toLowerCase());
|
|
2617
|
-
});
|
|
2618
|
-
}, [socialAccounts, hasExplicitAccountConfig, enabledSocialAccountTypes]);
|
|
2619
|
-
const filteredWalletAddresses = useMemo(() => {
|
|
2620
|
-
if (!isWalletAccountEnabled) {
|
|
2621
|
-
return [];
|
|
2622
|
-
}
|
|
2623
|
-
if (!hasExplicitWalletConfig) {
|
|
2624
|
-
return walletAddresses;
|
|
2625
|
-
}
|
|
2626
|
-
return walletAddresses.filter((wallet) => {
|
|
2627
|
-
return enabledWalletChainTypes.has(wallet.coreChainType.toLowerCase());
|
|
2628
|
-
});
|
|
2629
|
-
}, [walletAddresses, hasExplicitWalletConfig, enabledWalletChainTypes, isWalletAccountEnabled]);
|
|
2630
|
-
const emailAccount = useMemo(() => {
|
|
2631
|
-
return filteredSocialAccounts.find((a) => a.snsType === SnsType.Email);
|
|
2632
|
-
}, [filteredSocialAccounts]);
|
|
2633
|
-
const socialAccountsWithoutEmail = useMemo(() => {
|
|
2634
|
-
return filteredSocialAccounts.filter((a) => a.snsType !== SnsType.Email);
|
|
2635
|
-
}, [filteredSocialAccounts]);
|
|
2636
|
-
const handleSocialBind = useCallback(
|
|
2637
|
-
(snsType) => {
|
|
2638
|
-
if (isOAuthSupported(snsType)) {
|
|
2639
|
-
bindOAuth(snsType);
|
|
2640
|
-
return;
|
|
2641
|
-
}
|
|
2642
|
-
toast.info(messages.bindSocialTodo ?? "This binding method is not yet supported");
|
|
2643
|
-
},
|
|
2644
|
-
[bindOAuth, isOAuthSupported, toast, messages]
|
|
2645
|
-
);
|
|
2646
|
-
const isSocialProcessing = useCallback(
|
|
2647
|
-
(snsType) => {
|
|
2648
|
-
if (isOAuthBinding(snsType)) return true;
|
|
2649
|
-
return String(socialProcessingType).toLowerCase() === snsType.toLowerCase() && socialUnbindStatus === "loading";
|
|
2650
|
-
},
|
|
2651
|
-
[isOAuthBinding, socialProcessingType, socialUnbindStatus]
|
|
2652
|
-
);
|
|
2653
|
-
const handleWalletBind = useCallback(
|
|
2654
|
-
(chainType) => {
|
|
2655
|
-
bindWallet(chainType);
|
|
2656
|
-
},
|
|
2657
|
-
[bindWallet]
|
|
2658
|
-
);
|
|
2659
|
-
const handleWalletUnbind = useCallback(
|
|
2660
|
-
(chainType, address) => {
|
|
2661
|
-
unbindWallet(chainType, address);
|
|
2662
|
-
},
|
|
2663
|
-
[unbindWallet]
|
|
2664
|
-
);
|
|
2665
|
-
const isWalletProcessing = useCallback(
|
|
2666
|
-
(chainType) => {
|
|
2667
|
-
return String(walletProcessingChain) === String(chainType) && (walletBindStatus !== "idle" || walletUnbindStatus !== "idle");
|
|
2668
|
-
},
|
|
2669
|
-
[walletProcessingChain, walletBindStatus, walletUnbindStatus]
|
|
2670
|
-
);
|
|
2671
|
-
const isEmailUnbinding = useMemo(() => {
|
|
2672
|
-
return socialProcessingType === SnsType.Email && socialUnbindStatus === "loading";
|
|
2673
|
-
}, [socialProcessingType, socialUnbindStatus]);
|
|
2674
|
-
if (!isLoaded) {
|
|
2675
|
-
return /* @__PURE__ */ jsx("div", { className: "taskon-identity", children: /* @__PURE__ */ jsx("div", { className: "taskon-identity-loading", children: messages.loading }) });
|
|
2676
|
-
}
|
|
2677
|
-
const isEmpty = socialAccountsWithoutEmail.length === 0 && !emailAccount && filteredWalletAddresses.length === 0;
|
|
2678
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-identity", children: [
|
|
2679
|
-
/* @__PURE__ */ jsx(
|
|
2680
|
-
SocialAccountsSection,
|
|
2681
|
-
{
|
|
2682
|
-
accounts: socialAccountsWithoutEmail,
|
|
2683
|
-
messages,
|
|
2684
|
-
onBind: handleSocialBind,
|
|
2685
|
-
onUnbind: unbindSocial,
|
|
2686
|
-
isProcessing: isSocialProcessing,
|
|
2687
|
-
checkUnlink: checkSocialUnlink,
|
|
2688
|
-
onShowWarning: toast.warning
|
|
2689
|
-
}
|
|
2690
|
-
),
|
|
2691
|
-
/* @__PURE__ */ jsx(
|
|
2692
|
-
WalletsSection,
|
|
2693
|
-
{
|
|
2694
|
-
wallets: filteredWalletAddresses,
|
|
2695
|
-
rawAddresses,
|
|
2696
|
-
messages,
|
|
2697
|
-
onBind: handleWalletBind,
|
|
2698
|
-
onUnbind: handleWalletUnbind,
|
|
2699
|
-
isProcessing: isWalletProcessing,
|
|
2700
|
-
checkUnlink: checkWalletUnlink,
|
|
2701
|
-
onShowWarning: toast.warning,
|
|
2702
|
-
onShowInfo: toast.info
|
|
2703
|
-
}
|
|
2704
|
-
),
|
|
2705
|
-
emailAccount && /* @__PURE__ */ jsx(
|
|
2706
|
-
EmailSection,
|
|
2707
|
-
{
|
|
2708
|
-
emailAccount,
|
|
2709
|
-
messages,
|
|
2710
|
-
onUnbind: unbindSocial,
|
|
2711
|
-
isUnbinding: isEmailUnbinding,
|
|
2712
|
-
checkUnlink: checkSocialUnlink,
|
|
2713
|
-
onShowSuccess: toast.success,
|
|
2714
|
-
onShowError: toast.error,
|
|
2715
|
-
onShowWarning: toast.warning
|
|
2716
|
-
}
|
|
2717
|
-
),
|
|
2718
|
-
isEmpty && /* @__PURE__ */ jsx("div", { className: "taskon-identity-empty", children: messages.noData ?? "No identity options configured" })
|
|
2719
|
-
] });
|
|
2720
|
-
}
|
|
2721
|
-
function MyRewardsContent({
|
|
2722
|
-
messages,
|
|
2723
|
-
defaultRewardCard,
|
|
2724
|
-
defaultPointId
|
|
2725
|
-
}) {
|
|
2726
|
-
const { toast } = useToast();
|
|
2727
|
-
const { client } = useTaskOnContext();
|
|
2728
|
-
const [selectedPointsId, setSelectedPointsId] = useState(null);
|
|
2729
|
-
const hasUserSelectedRef = useRef(false);
|
|
2730
|
-
const appliedDefaultKeyRef = useRef(null);
|
|
2731
|
-
const [showWithdrawForm, setShowWithdrawForm] = useState(false);
|
|
2732
|
-
const [selectedTokenForWithdraw, setSelectedTokenForWithdraw] = useState(null);
|
|
2733
|
-
const [viewingFrozenToken, setViewingFrozenToken] = useState(null);
|
|
2734
|
-
const [resendParams, setResendParams] = useState(void 0);
|
|
2735
|
-
const {
|
|
2736
|
-
cards,
|
|
2737
|
-
selectedCard,
|
|
2738
|
-
selectCard,
|
|
2739
|
-
loading: rewardsLoading,
|
|
2740
|
-
error: rewardsError
|
|
2741
|
-
} = useUserRewards({});
|
|
2742
|
-
const selectedPointsData = useMemo(() => {
|
|
2743
|
-
if (selectedCard !== USER_CENTER_REWARD_CARD_TYPES.Points) return null;
|
|
2744
|
-
const selectedCardData = cards.find(
|
|
2745
|
-
(c) => {
|
|
2746
|
-
var _a;
|
|
2747
|
-
return c.type === selectedCard && ((_a = c.pointsData) == null ? void 0 : _a.points_id) === selectedPointsId;
|
|
2748
|
-
}
|
|
2749
|
-
);
|
|
2750
|
-
return (selectedCardData == null ? void 0 : selectedCardData.pointsData) ?? null;
|
|
2751
|
-
}, [selectedCard, cards, selectedPointsId]);
|
|
2752
|
-
const selectedXpLevelData = useMemo(() => {
|
|
2753
|
-
if (selectedCard !== USER_CENTER_REWARD_CARD_TYPES.XpLevel) return null;
|
|
2754
|
-
const xpLevelCard = cards.find(
|
|
2755
|
-
(c) => c.type === USER_CENTER_REWARD_CARD_TYPES.XpLevel
|
|
2756
|
-
);
|
|
2757
|
-
return (xpLevelCard == null ? void 0 : xpLevelCard.xpLevelData) ?? null;
|
|
2758
|
-
}, [selectedCard, cards]);
|
|
2759
|
-
const {
|
|
2760
|
-
data: tokenAssets,
|
|
2761
|
-
loading: tokenAssetsLoading,
|
|
2762
|
-
error: tokenAssetsError,
|
|
2763
|
-
pendingWithdrawals,
|
|
2764
|
-
refresh: refreshTokenAssets
|
|
2765
|
-
} = useTokenAssets({
|
|
2766
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Token
|
|
2767
|
-
});
|
|
2768
|
-
const {
|
|
2769
|
-
data: tokenHistory,
|
|
2770
|
-
loading: tokenHistoryLoading,
|
|
2771
|
-
error: tokenHistoryError,
|
|
2772
|
-
pagination: tokenHistoryPagination
|
|
2773
|
-
} = useRewardDetails({
|
|
2774
|
-
rewardType: RewardType.Token,
|
|
2775
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Token
|
|
2776
|
-
});
|
|
2777
|
-
const {
|
|
2778
|
-
data: frozenAssets,
|
|
2779
|
-
loading: frozenAssetsLoading,
|
|
2780
|
-
error: frozenAssetsError,
|
|
2781
|
-
pagination: frozenAssetsPagination,
|
|
2782
|
-
canResend
|
|
2783
|
-
} = useFrozenAssets({
|
|
2784
|
-
tokenId: (viewingFrozenToken == null ? void 0 : viewingFrozenToken.token_id) ?? 0,
|
|
2785
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Token && !!(viewingFrozenToken == null ? void 0 : viewingFrozenToken.token_id)
|
|
2786
|
-
});
|
|
2787
|
-
const userCenterApi = useMemo(() => {
|
|
2788
|
-
if (!client) return null;
|
|
2789
|
-
return createUserCenterApi(client);
|
|
2790
|
-
}, [client]);
|
|
2791
|
-
const {
|
|
2792
|
-
data: nftList,
|
|
2793
|
-
loading: nftLoading,
|
|
2794
|
-
error: nftError,
|
|
2795
|
-
pagination: nftPagination,
|
|
2796
|
-
refresh: refreshNftList
|
|
2797
|
-
} = useRewardDetails({
|
|
2798
|
-
rewardType: RewardType.Nft,
|
|
2799
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Nft
|
|
2800
|
-
});
|
|
2801
|
-
const {
|
|
2802
|
-
data: whitelistList,
|
|
2803
|
-
loading: whitelistLoading,
|
|
2804
|
-
error: whitelistError,
|
|
2805
|
-
pagination: whitelistPagination
|
|
2806
|
-
} = useRewardDetails({
|
|
2807
|
-
rewardType: RewardType.Whitelist,
|
|
2808
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Whitelist
|
|
2809
|
-
});
|
|
2810
|
-
const {
|
|
2811
|
-
data: discordRoleList,
|
|
2812
|
-
loading: discordRoleLoading,
|
|
2813
|
-
error: discordRoleError,
|
|
2814
|
-
pagination: discordRolePagination
|
|
2815
|
-
} = useRewardDetails({
|
|
2816
|
-
rewardType: RewardType.DiscordRole,
|
|
2817
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.DiscordRole
|
|
2818
|
-
});
|
|
2819
|
-
const {
|
|
2820
|
-
data: pointsHistory,
|
|
2821
|
-
loading: pointsLoading,
|
|
2822
|
-
error: pointsError,
|
|
2823
|
-
pagination: pointsPagination
|
|
2824
|
-
} = usePointsHistory({
|
|
2825
|
-
pointsId: (selectedPointsData == null ? void 0 : selectedPointsData.points_id) ?? 0,
|
|
2826
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.Points && !!selectedPointsData
|
|
2827
|
-
});
|
|
2828
|
-
const {
|
|
2829
|
-
data: xpLevelHistory,
|
|
2830
|
-
loading: xpLevelHistoryLoading,
|
|
2831
|
-
error: xpLevelHistoryError,
|
|
2832
|
-
pagination: xpLevelHistoryPagination
|
|
2833
|
-
} = usePointsHistory({
|
|
2834
|
-
pointsId: (selectedXpLevelData == null ? void 0 : selectedXpLevelData.xpPointsId) ?? 0,
|
|
2835
|
-
autoLoad: selectedCard === USER_CENTER_REWARD_CARD_TYPES.XpLevel && !!selectedXpLevelData
|
|
2836
|
-
});
|
|
2837
|
-
const handleWithdraw = (token) => {
|
|
2838
|
-
setResendParams(void 0);
|
|
2839
|
-
setSelectedTokenForWithdraw(token);
|
|
2840
|
-
setShowWithdrawForm(true);
|
|
2841
|
-
};
|
|
2842
|
-
const handleBatchWithdraw = () => {
|
|
2843
|
-
setResendParams(void 0);
|
|
2844
|
-
setSelectedTokenForWithdraw(null);
|
|
2845
|
-
setShowWithdrawForm(true);
|
|
2846
|
-
};
|
|
2847
|
-
const handleViewFrozen = (token) => {
|
|
2848
|
-
setViewingFrozenToken(token);
|
|
2849
|
-
};
|
|
2850
|
-
const handleCloseFrozenAssets = () => {
|
|
2851
|
-
setViewingFrozenToken(null);
|
|
2852
|
-
};
|
|
2853
|
-
const handleResendFrozenAsset = async (item) => {
|
|
2854
|
-
if (!viewingFrozenToken || !userCenterApi) {
|
|
2855
|
-
return;
|
|
2856
|
-
}
|
|
2857
|
-
if (item.type !== LockedType.Withdraw) {
|
|
2858
|
-
return;
|
|
2859
|
-
}
|
|
2860
|
-
if (!item.nonce || !item.receiver_address) {
|
|
2861
|
-
toast.error(messages.error ?? "Missing resend payload");
|
|
2862
|
-
return;
|
|
2863
|
-
}
|
|
2864
|
-
try {
|
|
2865
|
-
const requests = await userCenterApi.getTokenWithdrawByNonce({
|
|
2866
|
-
chain: viewingFrozenToken.chain,
|
|
2867
|
-
nonce: item.nonce
|
|
2868
|
-
});
|
|
2869
|
-
const withdrawableRequests = requests.filter((request) => request.can_withdraw);
|
|
2870
|
-
if (withdrawableRequests.length === 0) {
|
|
2871
|
-
toast.error(messages.emptyToken ?? "No tokens available for resend");
|
|
2872
|
-
return;
|
|
2873
|
-
}
|
|
2874
|
-
setResendParams({
|
|
2875
|
-
nonce: item.nonce,
|
|
2876
|
-
receiverAddress: item.receiver_address,
|
|
2877
|
-
tokens: withdrawableRequests
|
|
2878
|
-
});
|
|
2879
|
-
setSelectedTokenForWithdraw(viewingFrozenToken);
|
|
2880
|
-
setShowWithdrawForm(true);
|
|
2881
|
-
} catch (error) {
|
|
2882
|
-
toast.error(error instanceof Error ? error.message : "Failed to load resend details");
|
|
2883
|
-
}
|
|
2884
|
-
};
|
|
2885
|
-
const handleSelectCard = (type, pointsId) => {
|
|
2886
|
-
hasUserSelectedRef.current = true;
|
|
2887
|
-
selectCard(type);
|
|
2888
|
-
setSelectedPointsId(pointsId ?? null);
|
|
2889
|
-
};
|
|
2890
|
-
useEffect(() => {
|
|
2891
|
-
var _a, _b;
|
|
2892
|
-
if (!defaultRewardCard) return;
|
|
2893
|
-
if (hasUserSelectedRef.current) return;
|
|
2894
|
-
if (cards.length === 0) return;
|
|
2895
|
-
const applyKey = `${defaultRewardCard}:${defaultPointId ?? ""}`;
|
|
2896
|
-
if (appliedDefaultKeyRef.current === applyKey) return;
|
|
2897
|
-
const visibleDefaultCard = cards.find(
|
|
2898
|
-
(card) => card.visible && card.type === defaultRewardCard
|
|
2899
|
-
);
|
|
2900
|
-
if (!visibleDefaultCard) {
|
|
2901
|
-
appliedDefaultKeyRef.current = applyKey;
|
|
2902
|
-
return;
|
|
2903
|
-
}
|
|
2904
|
-
selectCard(defaultRewardCard);
|
|
2905
|
-
if (defaultRewardCard === USER_CENTER_REWARD_CARD_TYPES.Points) {
|
|
2906
|
-
const matchedPointsCard = cards.find(
|
|
2907
|
-
(card) => {
|
|
2908
|
-
var _a2;
|
|
2909
|
-
return card.type === USER_CENTER_REWARD_CARD_TYPES.Points && ((_a2 = card.pointsData) == null ? void 0 : _a2.points_id) === defaultPointId;
|
|
2910
|
-
}
|
|
2911
|
-
);
|
|
2912
|
-
if (((_a = matchedPointsCard == null ? void 0 : matchedPointsCard.pointsData) == null ? void 0 : _a.points_id) != null) {
|
|
2913
|
-
setSelectedPointsId(matchedPointsCard.pointsData.points_id);
|
|
2914
|
-
} else if (((_b = visibleDefaultCard.pointsData) == null ? void 0 : _b.points_id) != null) {
|
|
2915
|
-
setSelectedPointsId(visibleDefaultCard.pointsData.points_id);
|
|
2916
|
-
}
|
|
2917
|
-
} else {
|
|
2918
|
-
setSelectedPointsId(null);
|
|
2919
|
-
}
|
|
2920
|
-
appliedDefaultKeyRef.current = applyKey;
|
|
2921
|
-
}, [cards, defaultPointId, defaultRewardCard, selectCard]);
|
|
2922
|
-
useEffect(() => {
|
|
2923
|
-
if (selectedCard !== USER_CENTER_REWARD_CARD_TYPES.Token) {
|
|
2924
|
-
setViewingFrozenToken(null);
|
|
2925
|
-
}
|
|
2926
|
-
}, [selectedCard]);
|
|
2927
|
-
if (rewardsLoading && cards.length === 0) {
|
|
2928
|
-
return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
|
|
2929
|
-
}
|
|
2930
|
-
if (rewardsError && cards.length === 0) {
|
|
2931
|
-
return /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: rewardsError.message }) });
|
|
2932
|
-
}
|
|
2933
|
-
const hasVisibleCards = cards.some((c) => c.visible);
|
|
2934
|
-
if (!rewardsLoading && !hasVisibleCards) {
|
|
2935
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.emptyRewards });
|
|
2936
|
-
}
|
|
2937
|
-
const renderSelectedContent = () => {
|
|
2938
|
-
switch (selectedCard) {
|
|
2939
|
-
case USER_CENTER_REWARD_CARD_TYPES.Token:
|
|
2940
|
-
return /* @__PURE__ */ jsx(
|
|
2941
|
-
TokenRewardContent,
|
|
2942
|
-
{
|
|
2943
|
-
tokenAssets,
|
|
2944
|
-
tokenAssetsLoading,
|
|
2945
|
-
tokenAssetsError,
|
|
2946
|
-
pendingWithdrawals,
|
|
2947
|
-
tokenHistory,
|
|
2948
|
-
tokenHistoryLoading,
|
|
2949
|
-
tokenHistoryError,
|
|
2950
|
-
tokenHistoryPagination,
|
|
2951
|
-
messages,
|
|
2952
|
-
onWithdraw: handleWithdraw,
|
|
2953
|
-
onBatchWithdraw: handleBatchWithdraw,
|
|
2954
|
-
onViewFrozen: handleViewFrozen,
|
|
2955
|
-
showFrozenAssets: !!viewingFrozenToken,
|
|
2956
|
-
frozenAssets,
|
|
2957
|
-
frozenAssetsLoading,
|
|
2958
|
-
frozenAssetsError,
|
|
2959
|
-
frozenAssetsPagination,
|
|
2960
|
-
canResendFrozenAsset: canResend,
|
|
2961
|
-
onResendFrozenAsset: handleResendFrozenAsset,
|
|
2962
|
-
onCloseFrozenAssets: handleCloseFrozenAssets
|
|
2963
|
-
}
|
|
2964
|
-
);
|
|
2965
|
-
case USER_CENTER_REWARD_CARD_TYPES.XpLevel:
|
|
2966
|
-
if (!selectedXpLevelData) {
|
|
2967
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.noData });
|
|
2968
|
-
}
|
|
2969
|
-
return /* @__PURE__ */ jsx(
|
|
2970
|
-
XpLevelCard,
|
|
2971
|
-
{
|
|
2972
|
-
xpData: {
|
|
2973
|
-
level: selectedXpLevelData.level,
|
|
2974
|
-
currentXp: selectedXpLevelData.currentXp,
|
|
2975
|
-
nextLevelXp: selectedXpLevelData.nextLevelXp,
|
|
2976
|
-
totalXp: selectedXpLevelData.currentXp,
|
|
2977
|
-
pointsName: selectedXpLevelData.xpPointsName
|
|
2978
|
-
},
|
|
2979
|
-
historyData: xpLevelHistory,
|
|
2980
|
-
historyLoading: xpLevelHistoryLoading,
|
|
2981
|
-
historyError: xpLevelHistoryError,
|
|
2982
|
-
pagination: xpLevelHistoryPagination,
|
|
2983
|
-
messages
|
|
2984
|
-
}
|
|
2985
|
-
);
|
|
2986
|
-
case USER_CENTER_REWARD_CARD_TYPES.Nft:
|
|
2987
|
-
return /* @__PURE__ */ jsx(
|
|
2988
|
-
NftRewardContent,
|
|
2989
|
-
{
|
|
2990
|
-
nftList,
|
|
2991
|
-
loading: nftLoading,
|
|
2992
|
-
error: nftError,
|
|
2993
|
-
pagination: nftPagination,
|
|
2994
|
-
messages,
|
|
2995
|
-
onClaimSuccess: () => {
|
|
2996
|
-
refreshNftList();
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
|
-
);
|
|
3000
|
-
case USER_CENTER_REWARD_CARD_TYPES.Whitelist:
|
|
3001
|
-
return /* @__PURE__ */ jsx(
|
|
3002
|
-
WhitelistTable,
|
|
3003
|
-
{
|
|
3004
|
-
data: whitelistList,
|
|
3005
|
-
loading: whitelistLoading,
|
|
3006
|
-
error: whitelistError,
|
|
3007
|
-
pagination: whitelistPagination,
|
|
3008
|
-
messages
|
|
3009
|
-
}
|
|
3010
|
-
);
|
|
3011
|
-
case USER_CENTER_REWARD_CARD_TYPES.DiscordRole:
|
|
3012
|
-
return /* @__PURE__ */ jsx(
|
|
3013
|
-
DiscordRoleTable,
|
|
3014
|
-
{
|
|
3015
|
-
data: discordRoleList,
|
|
3016
|
-
loading: discordRoleLoading,
|
|
3017
|
-
error: discordRoleError,
|
|
3018
|
-
pagination: discordRolePagination,
|
|
3019
|
-
messages
|
|
3020
|
-
}
|
|
3021
|
-
);
|
|
3022
|
-
case USER_CENTER_REWARD_CARD_TYPES.Points:
|
|
3023
|
-
if (!selectedPointsData) {
|
|
3024
|
-
return /* @__PURE__ */ jsx(EmptyState, { message: messages.emptyPoints });
|
|
3025
|
-
}
|
|
3026
|
-
return /* @__PURE__ */ jsx(
|
|
3027
|
-
PointsList,
|
|
3028
|
-
{
|
|
3029
|
-
pointsInfo: selectedPointsData,
|
|
3030
|
-
data: pointsHistory,
|
|
3031
|
-
loading: pointsLoading,
|
|
3032
|
-
error: pointsError,
|
|
3033
|
-
pagination: pointsPagination,
|
|
3034
|
-
messages
|
|
3035
|
-
}
|
|
3036
|
-
);
|
|
3037
|
-
default:
|
|
3038
|
-
return null;
|
|
3039
|
-
}
|
|
3040
|
-
};
|
|
3041
|
-
return /* @__PURE__ */ jsxs("div", { className: "taskon-my-rewards", children: [
|
|
3042
|
-
/* @__PURE__ */ jsx(
|
|
3043
|
-
AssetCarousel,
|
|
3044
|
-
{
|
|
3045
|
-
cards,
|
|
3046
|
-
selectedCard,
|
|
3047
|
-
selectedPointsId,
|
|
3048
|
-
onSelectCard: handleSelectCard,
|
|
3049
|
-
messages
|
|
3050
|
-
}
|
|
3051
|
-
),
|
|
3052
|
-
renderSelectedContent(),
|
|
3053
|
-
/* @__PURE__ */ jsx(
|
|
3054
|
-
WithdrawForm,
|
|
3055
|
-
{
|
|
3056
|
-
open: showWithdrawForm,
|
|
3057
|
-
messages,
|
|
3058
|
-
tokenAssets,
|
|
3059
|
-
tokenAssetsLoading,
|
|
3060
|
-
initialTokenId: selectedTokenForWithdraw == null ? void 0 : selectedTokenForWithdraw.token_id,
|
|
3061
|
-
initialChain: selectedTokenForWithdraw == null ? void 0 : selectedTokenForWithdraw.chain,
|
|
3062
|
-
resend: resendParams ? {
|
|
3063
|
-
nonce: resendParams.nonce,
|
|
3064
|
-
receiverAddress: resendParams.receiverAddress
|
|
3065
|
-
} : void 0,
|
|
3066
|
-
resendTokenItems: resendParams ? resendParams.tokens.map((request) => {
|
|
3067
|
-
const matchedToken = tokenAssets.find(
|
|
3068
|
-
(token) => token.token_id === request.token_id && token.chain.toLowerCase() === request.chain.toLowerCase()
|
|
3069
|
-
);
|
|
3070
|
-
return {
|
|
3071
|
-
tokenId: request.token_id,
|
|
3072
|
-
tokenSymbol: request.token_symbol,
|
|
3073
|
-
tokenIcon: (matchedToken == null ? void 0 : matchedToken.token_icon) ?? "",
|
|
3074
|
-
tokenAddress: request.token_address,
|
|
3075
|
-
tokenDecimals: request.token_decimals,
|
|
3076
|
-
chain: request.chain,
|
|
3077
|
-
chainLabel: (matchedToken == null ? void 0 : matchedToken.chain_label) ?? request.chain,
|
|
3078
|
-
amount: request.token_amount,
|
|
3079
|
-
amountInWei: toWei(request.token_amount, request.token_decimals)
|
|
3080
|
-
};
|
|
3081
|
-
}) : void 0,
|
|
3082
|
-
onClose: () => {
|
|
3083
|
-
setResendParams(void 0);
|
|
3084
|
-
setShowWithdrawForm(false);
|
|
3085
|
-
},
|
|
3086
|
-
onSuccess: () => {
|
|
3087
|
-
refreshTokenAssets();
|
|
3088
|
-
setResendParams(void 0);
|
|
3089
|
-
setShowWithdrawForm(false);
|
|
3090
|
-
}
|
|
3091
|
-
}
|
|
3092
|
-
)
|
|
3093
|
-
] });
|
|
3094
|
-
}
|
|
3095
|
-
function ActivityHistoryContent({
|
|
3096
|
-
messages
|
|
3097
|
-
}) {
|
|
3098
|
-
const { data, loading, error, pagination, refresh } = useActivityHistory({
|
|
3099
|
-
mode: "pagination"
|
|
3100
|
-
});
|
|
3101
|
-
return /* @__PURE__ */ jsx(
|
|
3102
|
-
ActivityHistoryList,
|
|
3103
|
-
{
|
|
3104
|
-
data,
|
|
3105
|
-
loading,
|
|
3106
|
-
error,
|
|
3107
|
-
pagination,
|
|
3108
|
-
messages,
|
|
3109
|
-
mode: "pagination",
|
|
3110
|
-
onRetry: refresh
|
|
3111
|
-
}
|
|
3112
|
-
);
|
|
3113
|
-
}
|
|
3114
|
-
function mergeUserCenterConfig(props, cloud) {
|
|
3115
|
-
const resolved = props.config ?? cloud ?? null;
|
|
3116
|
-
const normalized = Array.isArray(resolved) && resolved.length > 0 ? resolved : null;
|
|
3117
|
-
return {
|
|
3118
|
-
config: normalized
|
|
3119
|
-
};
|
|
3120
|
-
}
|
|
3121
|
-
const TAB_LABEL_KEYS = {
|
|
3122
|
-
[UserCenterTabType.MyRewards]: "tabMyRewards",
|
|
3123
|
-
[UserCenterTabType.Identity]: "tabIdentity",
|
|
3124
|
-
[UserCenterTabType.ActivityHistory]: "tabActivityHistory"
|
|
3125
|
-
};
|
|
3126
|
-
const TAB_DEFAULT_LABELS = {
|
|
3127
|
-
[UserCenterTabType.MyRewards]: "My Rewards",
|
|
3128
|
-
[UserCenterTabType.Identity]: "Identity",
|
|
3129
|
-
[UserCenterTabType.ActivityHistory]: "Activity History"
|
|
3130
|
-
};
|
|
3131
|
-
function UserCenterWidget(props) {
|
|
3132
|
-
const { widgetId, themeMode } = props;
|
|
3133
|
-
const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
|
|
3134
|
-
const mergedConfig = useMemo(() => {
|
|
3135
|
-
return mergeUserCenterConfig(
|
|
3136
|
-
props,
|
|
3137
|
-
functionConfig ?? null
|
|
3138
|
-
);
|
|
3139
|
-
}, [props.config, functionConfig]);
|
|
3140
|
-
const resolvedConfig = mergedConfig.config;
|
|
3141
|
-
const isConfigured = Array.isArray(resolvedConfig) && resolvedConfig.length > 0;
|
|
3142
|
-
return /* @__PURE__ */ jsx(
|
|
3143
|
-
WidgetShell,
|
|
3144
|
-
{
|
|
3145
|
-
widgetId,
|
|
3146
|
-
isConfigLoading,
|
|
3147
|
-
cloudTheme,
|
|
3148
|
-
themeMode,
|
|
3149
|
-
className: "taskon-user-center",
|
|
3150
|
-
errorMessage: configError ?? (!isConfigured ? "未配置" : void 0),
|
|
3151
|
-
children: Array.isArray(resolvedConfig) && resolvedConfig.length > 0 ? /* @__PURE__ */ jsx(
|
|
3152
|
-
UserCenterWidgetInner,
|
|
3153
|
-
{
|
|
3154
|
-
...props,
|
|
3155
|
-
config: resolvedConfig
|
|
3156
|
-
}
|
|
3157
|
-
) : null
|
|
3158
|
-
}
|
|
3159
|
-
);
|
|
3160
|
-
}
|
|
3161
|
-
function UserCenterWidgetInner({
|
|
3162
|
-
config,
|
|
3163
|
-
defaultTab,
|
|
3164
|
-
defaultRewardCard,
|
|
3165
|
-
defaultPointId,
|
|
3166
|
-
onTabChange,
|
|
3167
|
-
className = "",
|
|
3168
|
-
style
|
|
3169
|
-
}) {
|
|
3170
|
-
var _a;
|
|
3171
|
-
const { isInitializing } = useTaskOnContext();
|
|
3172
|
-
const { messages, isLoading: isLocaleLoading } = useWidgetLocale({
|
|
3173
|
-
widgetId: "UserCenterWidget",
|
|
3174
|
-
defaultMessages: enMessages,
|
|
3175
|
-
loadMessages: (locale) => __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./locales/en.json": () => import("./UserCenterWidget-CvU6K4AC.js").then((n) => n.w), "./locales/ja.json": () => import("./usercenter-ja-B2465c1O.js"), "./locales/ko.json": () => import("./usercenter-ko-xAEYxqLg.js") }), `./locales/${locale}.json`, 3)
|
|
3176
|
-
});
|
|
3177
|
-
const enabledTabs = useMemo(() => filterEnabledTabs(config), [config]);
|
|
3178
|
-
const tabItems = useMemo(() => {
|
|
3179
|
-
return enabledTabs.map((tabConfig) => ({
|
|
3180
|
-
key: tabConfig.tab,
|
|
3181
|
-
label: messages[TAB_LABEL_KEYS[tabConfig.tab]] ?? TAB_DEFAULT_LABELS[tabConfig.tab]
|
|
3182
|
-
}));
|
|
3183
|
-
}, [enabledTabs, messages]);
|
|
3184
|
-
const initialTab = defaultTab && enabledTabs.some((t) => t.tab === defaultTab) ? defaultTab : ((_a = enabledTabs[0]) == null ? void 0 : _a.tab) ?? UserCenterTabType.MyRewards;
|
|
3185
|
-
const [activeTab, setActiveTab] = useState(initialTab);
|
|
3186
|
-
const handleTabChange = (tab) => {
|
|
3187
|
-
setActiveTab(tab);
|
|
3188
|
-
onTabChange == null ? void 0 : onTabChange(tab);
|
|
3189
|
-
};
|
|
3190
|
-
if (isInitializing || isLocaleLoading) {
|
|
3191
|
-
return /* @__PURE__ */ jsx("div", { className: `taskon-user-center ${className}`, style, children: /* @__PURE__ */ jsx(LoadingState, { message: messages.loading }) });
|
|
3192
|
-
}
|
|
3193
|
-
if (enabledTabs.length === 0) {
|
|
3194
|
-
return /* @__PURE__ */ jsx("div", { className: `taskon-user-center ${className}`, style, children: /* @__PURE__ */ jsx("div", { className: "taskon-user-center-empty", children: messages.noData }) });
|
|
3195
|
-
}
|
|
3196
|
-
return /* @__PURE__ */ jsxs("div", { className: `taskon-user-center ${className}`, style, children: [
|
|
3197
|
-
/* @__PURE__ */ jsx(Tabs, { items: tabItems, activeKey: activeTab, onChange: handleTabChange }),
|
|
3198
|
-
/* @__PURE__ */ jsxs("div", { className: "taskon-user-center-content", children: [
|
|
3199
|
-
activeTab === UserCenterTabType.MyRewards && /* @__PURE__ */ jsx(
|
|
3200
|
-
MyRewardsContent,
|
|
3201
|
-
{
|
|
3202
|
-
config,
|
|
3203
|
-
messages,
|
|
3204
|
-
defaultRewardCard,
|
|
3205
|
-
defaultPointId
|
|
3206
|
-
}
|
|
3207
|
-
),
|
|
3208
|
-
activeTab === UserCenterTabType.Identity && /* @__PURE__ */ jsx(IdentityContent, { config, messages }),
|
|
3209
|
-
activeTab === UserCenterTabType.ActivityHistory && /* @__PURE__ */ jsx(
|
|
3210
|
-
ActivityHistoryContent,
|
|
3211
|
-
{
|
|
3212
|
-
messages
|
|
3213
|
-
}
|
|
3214
|
-
)
|
|
3215
|
-
] })
|
|
3216
|
-
] });
|
|
3217
|
-
}
|
|
3218
|
-
export {
|
|
3219
|
-
ActivityHistoryList as A,
|
|
3220
|
-
UserCenterWidget as U,
|
|
3221
|
-
AssetCard as a,
|
|
3222
|
-
AssetCarousel as b,
|
|
3223
|
-
useUserRewards as c,
|
|
3224
|
-
useFrozenAssets as d,
|
|
3225
|
-
useIdentityData as e,
|
|
3226
|
-
useUnbindSocial as f,
|
|
3227
|
-
useBindWallet as g,
|
|
3228
|
-
useDisableUnlink as h,
|
|
3229
|
-
useActivityHistory as u
|
|
3230
|
-
};
|