@taskon/widget-react 0.0.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +1065 -0
  2. package/dist/CommunityTaskList.css +4893 -0
  3. package/dist/EligibilityInfo.css +2337 -0
  4. package/dist/LeaderboardWidget.css +815 -0
  5. package/dist/PageBuilder.css +54 -0
  6. package/dist/Quest.css +4214 -0
  7. package/dist/TaskOnProvider.css +163 -0
  8. package/dist/TipPopover.css +210 -0
  9. package/dist/UserCenterWidget.css +297 -0
  10. package/dist/UserCenterWidget2.css +3519 -0
  11. package/dist/WidgetShell.css +182 -0
  12. package/dist/chunks/CommunityTaskList-DoPGZsw1.js +6813 -0
  13. package/dist/chunks/EligibilityInfo-C7GZ2G5u.js +22228 -0
  14. package/dist/chunks/LeaderboardWidget-CmYfDeHV.js +1068 -0
  15. package/dist/chunks/PageBuilder-Tmhf2GTS.js +150 -0
  16. package/dist/chunks/Quest-DKFZ-pPU.js +8839 -0
  17. package/dist/chunks/TaskOnProvider-BD6Vp2x8.js +1435 -0
  18. package/dist/chunks/ThemeProvider-wnSXrNQb.js +1118 -0
  19. package/dist/chunks/TipPopover-BrW8jo71.js +2926 -0
  20. package/dist/chunks/UserCenterWidget-BE329iS7.js +3546 -0
  21. package/dist/chunks/UserCenterWidget-BVw_IEEd.js +3989 -0
  22. package/dist/chunks/WidgetShell-D_5OjvNZ.js +1517 -0
  23. package/dist/chunks/common-ja-DWhTaFHb.js +23 -0
  24. package/dist/chunks/common-ko-80ezXsMG.js +23 -0
  25. package/dist/chunks/dynamic-import-helper-DxEFwm31.js +537 -0
  26. package/dist/chunks/index-CwMvO_wZ.js +777 -0
  27. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +119 -0
  28. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +119 -0
  29. package/dist/chunks/useToast-B-wyO5zL.js +93 -0
  30. package/dist/chunks/useWidgetLocale-JDelxtt8.js +74 -0
  31. package/dist/chunks/usercenter-ja-uu-XfVF9.js +332 -0
  32. package/dist/chunks/usercenter-ko-DYgUOVzd.js +332 -0
  33. package/dist/community-task.d.ts +451 -0
  34. package/dist/community-task.js +9 -0
  35. package/dist/core.d.ts +803 -0
  36. package/dist/core.js +22 -0
  37. package/dist/dynamic-import-helper.css +389 -0
  38. package/dist/index.d.ts +1660 -0
  39. package/dist/index.js +41 -0
  40. package/dist/leaderboard.d.ts +547 -0
  41. package/dist/leaderboard.js +18 -0
  42. package/dist/page-builder.d.ts +20 -0
  43. package/dist/page-builder.js +4 -0
  44. package/dist/quest.d.ts +400 -0
  45. package/dist/quest.js +8 -0
  46. package/dist/user-center.d.ts +1780 -0
  47. package/dist/user-center.js +713 -0
  48. package/package.json +105 -0
@@ -0,0 +1,713 @@
1
+ import { A, a, b, U, u, g, h, d, e, f, c } from "./chunks/UserCenterWidget-BVw_IEEd.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { L as LoadingState, E as EmptyState, P as Pagination } from "./chunks/UserCenterWidget-BE329iS7.js";
4
+ import { T, e as e2, f as f2, d as d2, t, c as c2, u as u2, a as a2, b as b2 } from "./chunks/UserCenterWidget-BE329iS7.js";
5
+ import { formatLocalDate, formatTokenAmount as formatTokenAmount$1, RewardType, USER_CENTER_PAGE_SIZE, createUserCenterApi } from "@taskon/core";
6
+ import { getChainIcon, getChainName, getSocialIcon, toWei, truncateAddress } from "@taskon/core";
7
+ import { D as Dialog } from "./chunks/WidgetShell-D_5OjvNZ.js";
8
+ import { B as Button, T as Table, u as usePagination } from "./chunks/dynamic-import-helper-DxEFwm31.js";
9
+ import { useState, useMemo, useCallback, useEffect } from "react";
10
+ import { b as useTaskOnContext } from "./chunks/ThemeProvider-wnSXrNQb.js";
11
+ function getTabLabel(tab, messages) {
12
+ switch (tab) {
13
+ case "MyRewards":
14
+ return messages.tabMyRewards;
15
+ case "Identity":
16
+ return messages.tabIdentity;
17
+ case "ActivityHistory":
18
+ return messages.tabActivityHistory;
19
+ default:
20
+ return tab;
21
+ }
22
+ }
23
+ function TabBar({
24
+ activeTab,
25
+ tabs,
26
+ onTabChange,
27
+ messages,
28
+ className = ""
29
+ }) {
30
+ return /* @__PURE__ */ jsx("div", { className: `taskon-user-center-tabs ${className}`, children: tabs.map((tab) => /* @__PURE__ */ jsx(
31
+ "button",
32
+ {
33
+ type: "button",
34
+ className: `taskon-user-center-tabs__tab ${activeTab === tab ? "taskon-user-center-tabs__tab--active" : ""}`,
35
+ onClick: () => onTabChange(tab),
36
+ children: getTabLabel(tab, messages)
37
+ },
38
+ tab
39
+ )) });
40
+ }
41
+ function formatTime$1(timestamp) {
42
+ return formatLocalDate(timestamp);
43
+ }
44
+ function formatTokenAmount(amount) {
45
+ return formatTokenAmount$1(amount, {
46
+ showCurrency: false,
47
+ useAbbreviation: false,
48
+ decimals: 4,
49
+ minValue: 1e-4,
50
+ zeroText: "0"
51
+ });
52
+ }
53
+ function getEmptyMessage(rewardType, messages) {
54
+ switch (rewardType) {
55
+ case "Token":
56
+ return messages.emptyToken;
57
+ case "Nft":
58
+ return messages.emptyNft;
59
+ default:
60
+ return messages.noData;
61
+ }
62
+ }
63
+ function TokenRow({ item, onClick }) {
64
+ const tokenValue = item.reward_value;
65
+ return /* @__PURE__ */ jsxs(
66
+ "div",
67
+ {
68
+ className: "taskon-reward-detail__row",
69
+ onClick,
70
+ role: onClick ? "button" : void 0,
71
+ tabIndex: onClick ? 0 : void 0,
72
+ children: [
73
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--icon", children: tokenValue.token_logo && /* @__PURE__ */ jsx(
74
+ "img",
75
+ {
76
+ src: tokenValue.token_logo,
77
+ alt: tokenValue.token_name,
78
+ className: "taskon-reward-detail__token-icon"
79
+ }
80
+ ) }),
81
+ /* @__PURE__ */ jsxs("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--main", children: [
82
+ /* @__PURE__ */ jsxs("span", { className: "taskon-reward-detail__primary", children: [
83
+ "+",
84
+ formatTokenAmount(tokenValue.amount),
85
+ " ",
86
+ tokenValue.token_name
87
+ ] }),
88
+ /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__secondary", children: item.campaign_name })
89
+ ] }),
90
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--time", children: formatTime$1(item.reward_time) })
91
+ ]
92
+ }
93
+ );
94
+ }
95
+ function NftRow({
96
+ item,
97
+ onClick,
98
+ onClaim,
99
+ onTxClick,
100
+ messages
101
+ }) {
102
+ const nftValue = item.reward_value;
103
+ const renderNftAction = () => {
104
+ if (nftValue.tx_hash) {
105
+ return /* @__PURE__ */ jsx(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ className: "taskon-reward-detail__claimed-link",
110
+ onClick: (e3) => {
111
+ e3.stopPropagation();
112
+ onTxClick == null ? void 0 : onTxClick();
113
+ },
114
+ title: nftValue.tx_hash,
115
+ children: messages.claimedTxn
116
+ }
117
+ );
118
+ }
119
+ if (nftValue.claimable) {
120
+ return /* @__PURE__ */ jsx(
121
+ "button",
122
+ {
123
+ type: "button",
124
+ className: "taskon-reward-detail__claim-btn",
125
+ onClick: (e3) => {
126
+ e3.stopPropagation();
127
+ onClaim == null ? void 0 : onClaim();
128
+ },
129
+ children: messages.claim
130
+ }
131
+ );
132
+ }
133
+ return /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__manual-drop", children: messages.manualDrop });
134
+ };
135
+ return /* @__PURE__ */ jsxs(
136
+ "div",
137
+ {
138
+ className: "taskon-reward-detail__row taskon-reward-detail__row--nft",
139
+ onClick,
140
+ role: onClick ? "button" : void 0,
141
+ tabIndex: onClick ? 0 : void 0,
142
+ children: [
143
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--nft-image", children: nftValue.collection_image && /* @__PURE__ */ jsx(
144
+ "img",
145
+ {
146
+ src: nftValue.collection_image,
147
+ alt: nftValue.collection_name,
148
+ className: "taskon-reward-detail__nft-image"
149
+ }
150
+ ) }),
151
+ /* @__PURE__ */ jsxs("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--main", children: [
152
+ /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__primary", children: nftValue.collection_name }),
153
+ /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__secondary", children: item.campaign_name })
154
+ ] }),
155
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--time", children: formatTime$1(item.reward_time) }),
156
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--action", children: renderNftAction() })
157
+ ]
158
+ }
159
+ );
160
+ }
161
+ function SimpleRow({ item, onClick }) {
162
+ return /* @__PURE__ */ jsxs(
163
+ "div",
164
+ {
165
+ className: "taskon-reward-detail__row",
166
+ onClick,
167
+ role: onClick ? "button" : void 0,
168
+ tabIndex: onClick ? 0 : void 0,
169
+ children: [
170
+ /* @__PURE__ */ jsxs("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--main", children: [
171
+ /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__primary", children: item.campaign_name }),
172
+ /* @__PURE__ */ jsx("span", { className: "taskon-reward-detail__secondary", children: item.campaign_type })
173
+ ] }),
174
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__cell taskon-reward-detail__cell--time", children: formatTime$1(item.reward_time) })
175
+ ]
176
+ }
177
+ );
178
+ }
179
+ function RewardDetailList({
180
+ rewardType,
181
+ data,
182
+ loading,
183
+ error,
184
+ pagination,
185
+ messages,
186
+ onItemClick,
187
+ onClaim,
188
+ onTxClick
189
+ }) {
190
+ if (loading && data.length === 0) {
191
+ return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
192
+ }
193
+ if (error && data.length === 0) {
194
+ return /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: error.message }) });
195
+ }
196
+ if (!loading && data.length === 0) {
197
+ return /* @__PURE__ */ jsx(EmptyState, { message: getEmptyMessage(rewardType, messages) });
198
+ }
199
+ const renderRow = (item, index) => {
200
+ const handleClick = onItemClick ? () => onItemClick(item) : void 0;
201
+ const itemKey = `${item.campaign_id}-${item.reward_time}-${index}`;
202
+ switch (rewardType) {
203
+ case RewardType.Token:
204
+ return /* @__PURE__ */ jsx(TokenRow, { item, onClick: handleClick }, itemKey);
205
+ case RewardType.Nft:
206
+ return /* @__PURE__ */ jsx(
207
+ NftRow,
208
+ {
209
+ item,
210
+ onClick: handleClick,
211
+ onClaim: onClaim ? () => onClaim(item) : void 0,
212
+ onTxClick: onTxClick ? () => onTxClick(item) : void 0,
213
+ messages
214
+ },
215
+ itemKey
216
+ );
217
+ default:
218
+ return /* @__PURE__ */ jsx(SimpleRow, { item, onClick: handleClick }, itemKey);
219
+ }
220
+ };
221
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-reward-detail", children: [
222
+ /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__list", children: data.map((item, index) => renderRow(item, index)) }),
223
+ pagination.totalPages > 1 && /* @__PURE__ */ jsx(
224
+ Pagination,
225
+ {
226
+ page: pagination.page,
227
+ totalPages: pagination.totalPages,
228
+ onPrevious: pagination.goToPrevious,
229
+ onNext: pagination.goToNext,
230
+ hasPrevious: pagination.hasPrevious,
231
+ hasNext: pagination.hasNext,
232
+ messages
233
+ }
234
+ ),
235
+ loading && data.length > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-reward-detail__loading-more", children: /* @__PURE__ */ jsx("div", { className: "taskon-user-center-loading__spinner" }) })
236
+ ] });
237
+ }
238
+ function formatAmount$1(amount) {
239
+ const num = parseFloat(amount);
240
+ if (isNaN(num) || num === 0) return "0";
241
+ return num.toLocaleString(void 0, { maximumFractionDigits: 6 });
242
+ }
243
+ function WarningIcon() {
244
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "48", height: "48", children: /* @__PURE__ */ jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" }) });
245
+ }
246
+ function SuccessIcon() {
247
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "48", height: "48", children: /* @__PURE__ */ jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) });
248
+ }
249
+ function WithdrawModal({
250
+ open,
251
+ status,
252
+ tokens,
253
+ messages,
254
+ error,
255
+ txHash,
256
+ isGasInsufficient,
257
+ onConfirm,
258
+ onCancel,
259
+ onClose
260
+ }) {
261
+ if (!open) {
262
+ return null;
263
+ }
264
+ if (status === "noEnough" || isGasInsufficient) {
265
+ return /* @__PURE__ */ jsxs(
266
+ Dialog,
267
+ {
268
+ open,
269
+ onOpenChange: (isOpen) => {
270
+ if (!isOpen) onClose();
271
+ },
272
+ title: messages.gasNotEnough,
273
+ showCloseButton: true,
274
+ contentClassName: "taskon-withdraw-modal__content",
275
+ maxWidth: 400,
276
+ children: [
277
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__body", children: [
278
+ /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__icon taskon-withdraw-modal__icon--warning", children: /* @__PURE__ */ jsx(WarningIcon, {}) }),
279
+ /* @__PURE__ */ jsx("p", { className: "taskon-withdraw-modal__message", children: messages.gasNotEnough })
280
+ ] }),
281
+ /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__footer", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: messages.ok ?? "OK" }) })
282
+ ]
283
+ }
284
+ );
285
+ }
286
+ if (status === "success") {
287
+ return /* @__PURE__ */ jsxs(
288
+ Dialog,
289
+ {
290
+ open,
291
+ onOpenChange: (isOpen) => {
292
+ if (!isOpen) onClose();
293
+ },
294
+ title: messages.withdrawSuccess,
295
+ showCloseButton: true,
296
+ contentClassName: "taskon-withdraw-modal__content",
297
+ maxWidth: 400,
298
+ children: [
299
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__body", children: [
300
+ /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__icon taskon-withdraw-modal__icon--success", children: /* @__PURE__ */ jsx(SuccessIcon, {}) }),
301
+ /* @__PURE__ */ jsx("p", { className: "taskon-withdraw-modal__message", children: messages.withdrawSuccess }),
302
+ txHash && /* @__PURE__ */ jsxs("p", { className: "taskon-withdraw-modal__tx-hash", children: [
303
+ "TX: ",
304
+ txHash.slice(0, 10),
305
+ "...",
306
+ txHash.slice(-8)
307
+ ] })
308
+ ] }),
309
+ /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__footer", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: onClose, children: messages.ok ?? "OK" }) })
310
+ ]
311
+ }
312
+ );
313
+ }
314
+ return /* @__PURE__ */ jsxs(
315
+ Dialog,
316
+ {
317
+ open,
318
+ onOpenChange: (isOpen) => {
319
+ if (!isOpen) onCancel();
320
+ },
321
+ title: messages.withdrawConfirm,
322
+ showCloseButton: true,
323
+ contentClassName: "taskon-withdraw-modal__content",
324
+ maxWidth: 400,
325
+ children: [
326
+ /* @__PURE__ */ jsx("h3", { className: "taskon-withdraw-modal__title", children: messages.withdrawConfirm }),
327
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__body", children: [
328
+ /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__tokens", children: tokens.map((token) => /* @__PURE__ */ jsxs(
329
+ "div",
330
+ {
331
+ className: "taskon-withdraw-modal__token-item",
332
+ children: [
333
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__token-info", children: [
334
+ /* @__PURE__ */ jsx(
335
+ "img",
336
+ {
337
+ src: token.tokenIcon,
338
+ alt: token.tokenSymbol,
339
+ className: "taskon-withdraw-modal__token-icon"
340
+ }
341
+ ),
342
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__token-details", children: [
343
+ /* @__PURE__ */ jsx("span", { className: "taskon-withdraw-modal__token-symbol", children: token.tokenSymbol }),
344
+ /* @__PURE__ */ jsx("span", { className: "taskon-withdraw-modal__token-chain", children: token.chainLabel })
345
+ ] })
346
+ ] }),
347
+ /* @__PURE__ */ jsx("span", { className: "taskon-withdraw-modal__token-amount", children: formatAmount$1(token.amount) })
348
+ ]
349
+ },
350
+ token.tokenId
351
+ )) }),
352
+ error && /* @__PURE__ */ jsx("div", { className: "taskon-withdraw-modal__error", children: error.message })
353
+ ] }),
354
+ /* @__PURE__ */ jsxs("div", { className: "taskon-withdraw-modal__footer", children: [
355
+ /* @__PURE__ */ jsx(
356
+ Button,
357
+ {
358
+ variant: "secondary",
359
+ onClick: onCancel,
360
+ disabled: status === "loading",
361
+ children: messages.cancel
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx(
365
+ Button,
366
+ {
367
+ variant: "primary",
368
+ onClick: onConfirm,
369
+ disabled: status === "loading",
370
+ loading: status === "loading",
371
+ children: status === "loading" ? messages.loading : messages.withdraw
372
+ }
373
+ )
374
+ ] })
375
+ ]
376
+ }
377
+ );
378
+ }
379
+ function formatTime(timestamp) {
380
+ const date = new Date(timestamp);
381
+ return date.toLocaleDateString(void 0, {
382
+ year: "numeric",
383
+ month: "short",
384
+ day: "numeric",
385
+ hour: "2-digit",
386
+ minute: "2-digit"
387
+ });
388
+ }
389
+ function formatAmount(amount) {
390
+ const num = parseFloat(amount);
391
+ if (isNaN(num) || num === 0) return "0";
392
+ return num.toLocaleString(void 0, { maximumFractionDigits: 6 });
393
+ }
394
+ function getLockedTypeLabel(type, messages) {
395
+ switch (type) {
396
+ case "Campaign":
397
+ return messages.frozenTypeCampaign ?? "Campaign Locked";
398
+ case "Withdraw":
399
+ return messages.frozenTypeWithdraw ?? "Pending Withdrawal";
400
+ case "ReferralReward":
401
+ return messages.frozenTypeReferral ?? "Referral Locked";
402
+ case "Benefit":
403
+ return messages.frozenTypeBenefit ?? "Benefit Locked";
404
+ case "TgMiniApp":
405
+ return messages.frozenTypeTgMiniApp ?? "TG Mini App";
406
+ case "CommunityMilestone":
407
+ return messages.frozenTypeMilestone ?? "Milestone Locked";
408
+ default:
409
+ return type;
410
+ }
411
+ }
412
+ function FrozenAssetList({
413
+ data,
414
+ loading,
415
+ error,
416
+ pagination,
417
+ messages,
418
+ canResend,
419
+ onResend,
420
+ onClose
421
+ }) {
422
+ if (loading && data.length === 0) {
423
+ return /* @__PURE__ */ jsx(LoadingState, { message: messages.loading });
424
+ }
425
+ if (error && data.length === 0) {
426
+ return /* @__PURE__ */ jsx("div", { className: "taskon-user-center-error", children: /* @__PURE__ */ jsx("p", { className: "taskon-user-center-error__message", children: error.message }) });
427
+ }
428
+ if (!loading && data.length === 0) {
429
+ return /* @__PURE__ */ jsx(EmptyState, { message: messages.noData });
430
+ }
431
+ const columns = [
432
+ {
433
+ key: "locked_amount",
434
+ title: messages.columnAmount,
435
+ width: 120,
436
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-frozen-assets__amount", children: formatAmount(row.locked_amount) })
437
+ },
438
+ {
439
+ key: "type",
440
+ title: messages.columnDetail,
441
+ render: (_, row) => /* @__PURE__ */ jsxs("div", { className: "taskon-frozen-assets__detail-cell", children: [
442
+ /* @__PURE__ */ jsx("span", { className: "taskon-frozen-assets__type", children: getLockedTypeLabel(row.type, messages) }),
443
+ row.campaign_name && /* @__PURE__ */ jsx("span", { className: "taskon-frozen-assets__campaign", children: row.campaign_name })
444
+ ] })
445
+ },
446
+ {
447
+ key: "lock_time",
448
+ title: messages.columnTime,
449
+ width: 160,
450
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-frozen-assets__time", children: formatTime(row.lock_time) })
451
+ },
452
+ {
453
+ key: "action",
454
+ title: messages.columnAction ?? "Action",
455
+ width: 100,
456
+ align: "right",
457
+ render: (_, row) => {
458
+ if (!canResend(row) || !onResend) return null;
459
+ return /* @__PURE__ */ jsx(
460
+ Button,
461
+ {
462
+ variant: "outline",
463
+ size: "small",
464
+ onClick: () => onResend(row),
465
+ className: "taskon-frozen-assets__resend-btn",
466
+ children: messages.resend
467
+ }
468
+ );
469
+ }
470
+ }
471
+ ];
472
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-frozen-assets", children: [
473
+ /* @__PURE__ */ jsxs("div", { className: "taskon-frozen-assets__header", children: [
474
+ /* @__PURE__ */ jsx("h3", { className: "taskon-frozen-assets__title", children: messages.frozenAssets }),
475
+ onClose && /* @__PURE__ */ jsx(
476
+ "button",
477
+ {
478
+ type: "button",
479
+ className: "taskon-frozen-assets__close",
480
+ onClick: onClose,
481
+ "aria-label": "Close",
482
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) })
483
+ }
484
+ )
485
+ ] }),
486
+ /* @__PURE__ */ jsx(
487
+ Table,
488
+ {
489
+ columns,
490
+ data,
491
+ rowConfig: {
492
+ getRowKey: (row, index) => `${row.lock_time}-${index}`
493
+ },
494
+ striped: true,
495
+ loading: loading && data.length > 0,
496
+ loadingText: messages.loading,
497
+ empty: {
498
+ title: messages.noData
499
+ }
500
+ }
501
+ ),
502
+ pagination.totalPages > 1 && /* @__PURE__ */ jsx(
503
+ Pagination,
504
+ {
505
+ page: pagination.page,
506
+ totalPages: pagination.totalPages,
507
+ onPrevious: pagination.goToPrevious,
508
+ onNext: pagination.goToNext,
509
+ hasPrevious: pagination.hasPrevious,
510
+ hasNext: pagination.hasNext,
511
+ messages
512
+ }
513
+ )
514
+ ] });
515
+ }
516
+ function useFrozenAssets(options) {
517
+ const { tokenId, pageSize = USER_CENTER_PAGE_SIZE, autoLoad = true } = options;
518
+ const { client } = useTaskOnContext();
519
+ const [data, setData] = useState([]);
520
+ const [total, setTotal] = useState(0);
521
+ const [loading, setLoading] = useState(false);
522
+ const [error, setError] = useState(null);
523
+ const api = useMemo(() => {
524
+ if (!client) return null;
525
+ return createUserCenterApi(client);
526
+ }, [client]);
527
+ const pagination = usePagination({
528
+ total,
529
+ pageSize,
530
+ initialPage: 1,
531
+ mode: "pagination"
532
+ });
533
+ const fetchData = useCallback(
534
+ async (pageNo) => {
535
+ if (!api) {
536
+ setError(new Error("TaskOn client not initialized"));
537
+ return;
538
+ }
539
+ if (!tokenId) {
540
+ setError(new Error("Token ID is required"));
541
+ return;
542
+ }
543
+ setLoading(true);
544
+ setError(null);
545
+ try {
546
+ const response = await api.getLockedTokenList({
547
+ token_id: tokenId,
548
+ page: {
549
+ page_no: pageNo - 1,
550
+ // API 使用 0-based 索引
551
+ size: pageSize
552
+ }
553
+ });
554
+ setData(response.data);
555
+ setTotal(response.total);
556
+ } catch (err) {
557
+ setError(
558
+ err instanceof Error ? err : new Error("Failed to fetch frozen assets")
559
+ );
560
+ } finally {
561
+ setLoading(false);
562
+ }
563
+ },
564
+ [api, tokenId, pageSize]
565
+ );
566
+ const refresh = useCallback(async () => {
567
+ pagination.goToPage(1);
568
+ await fetchData(1);
569
+ }, [fetchData, pagination]);
570
+ const canResend = useCallback((item) => {
571
+ return item.type === "Withdraw";
572
+ }, []);
573
+ useEffect(() => {
574
+ if (autoLoad && tokenId) {
575
+ fetchData(1);
576
+ }
577
+ }, [autoLoad, tokenId, fetchData]);
578
+ useEffect(() => {
579
+ if (pagination.page > 1) {
580
+ fetchData(pagination.page);
581
+ }
582
+ }, [pagination.page, fetchData]);
583
+ return {
584
+ data,
585
+ loading,
586
+ error,
587
+ total,
588
+ pagination,
589
+ refresh,
590
+ canResend
591
+ };
592
+ }
593
+ function calculateXpLevelData(userInfo) {
594
+ const xpPointsInfo = userInfo.points_list[0];
595
+ if (!xpPointsInfo) return null;
596
+ const currentXp = xpPointsInfo.amount;
597
+ const nextLevelXp = userInfo.next_level_limit;
598
+ let percent = 0;
599
+ if (nextLevelXp > 0) {
600
+ if (currentXp >= nextLevelXp) {
601
+ percent = 100;
602
+ } else {
603
+ percent = Number((currentXp / nextLevelXp * 100).toFixed(2));
604
+ }
605
+ }
606
+ const xpToNextLevel = currentXp >= nextLevelXp ? 0 : nextLevelXp - currentXp;
607
+ return {
608
+ level: userInfo.level,
609
+ currentXp,
610
+ nextLevelXp,
611
+ totalXp: currentXp,
612
+ percent,
613
+ xpToNextLevel,
614
+ xpPointsId: xpPointsInfo.points_info.points_id,
615
+ xpPointsName: xpPointsInfo.points_info.points_name,
616
+ xpPointsIcon: xpPointsInfo.points_info.points_icon
617
+ };
618
+ }
619
+ function useXpLevel(options = {}) {
620
+ const { autoLoad = true } = options;
621
+ const { client } = useTaskOnContext();
622
+ const [userInfo, setUserInfo] = useState(null);
623
+ const [loading, setLoading] = useState(false);
624
+ const [error, setError] = useState(null);
625
+ const api = useMemo(() => {
626
+ if (!client) return null;
627
+ return createUserCenterApi(client);
628
+ }, [client]);
629
+ const xpData = useMemo(() => {
630
+ if (!userInfo) return null;
631
+ return calculateXpLevelData(userInfo);
632
+ }, [userInfo]);
633
+ const xpPointsInfo = useMemo(() => {
634
+ if (!userInfo || !userInfo.points_list.length) return null;
635
+ const firstPoints = userInfo.points_list[0];
636
+ return firstPoints ?? null;
637
+ }, [userInfo]);
638
+ const otherPointsList = useMemo(() => {
639
+ if (!userInfo || userInfo.points_list.length <= 1) return [];
640
+ return userInfo.points_list.slice(1);
641
+ }, [userInfo]);
642
+ const fetchData = useCallback(async () => {
643
+ if (!api) {
644
+ setError(new Error("TaskOn client not initialized"));
645
+ return;
646
+ }
647
+ setLoading(true);
648
+ setError(null);
649
+ try {
650
+ const response = await api.getCUserInfo({});
651
+ setUserInfo(response);
652
+ } catch (err) {
653
+ setError(
654
+ err instanceof Error ? err : new Error("Failed to fetch user info")
655
+ );
656
+ } finally {
657
+ setLoading(false);
658
+ }
659
+ }, [api]);
660
+ const refresh = useCallback(async () => {
661
+ await fetchData();
662
+ }, [fetchData]);
663
+ useEffect(() => {
664
+ if (autoLoad) {
665
+ fetchData();
666
+ }
667
+ }, [autoLoad, fetchData]);
668
+ return {
669
+ userInfo,
670
+ xpData,
671
+ xpPointsInfo,
672
+ otherPointsList,
673
+ loading,
674
+ error,
675
+ refresh
676
+ };
677
+ }
678
+ export {
679
+ A as ActivityHistoryList,
680
+ a as AssetCard,
681
+ b as AssetCarousel,
682
+ EmptyState,
683
+ FrozenAssetList,
684
+ LoadingState,
685
+ Pagination,
686
+ RewardDetailList,
687
+ TabBar,
688
+ T as TokenAssetList,
689
+ U as UserCenterWidget,
690
+ WithdrawModal,
691
+ e2 as buildRewardCards,
692
+ f2 as formatTokenAmount,
693
+ getChainIcon,
694
+ getChainName,
695
+ getSocialIcon,
696
+ d2 as toGasFreeWithdrawItem,
697
+ toWei,
698
+ t as toWithdrawItem,
699
+ truncateAddress,
700
+ u as useActivityHistory,
701
+ g as useBindWallet,
702
+ h as useDisableUnlink,
703
+ useFrozenAssets,
704
+ d as useGasFreeWithdraw,
705
+ e as useIdentityData,
706
+ c2 as usePointsHistory,
707
+ u2 as useRewardDetails,
708
+ a2 as useTokenAssets,
709
+ b2 as useTokenWithdraw,
710
+ f as useUnbindSocial,
711
+ c as useUserRewards,
712
+ useXpLevel
713
+ };