@taskon/widget-react 0.0.1-beta.2 → 0.0.1-beta.3

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 (43) hide show
  1. package/README.md +55 -16
  2. package/dist/CommunityTaskList.css +432 -628
  3. package/dist/EligibilityInfo.css +944 -431
  4. package/dist/PageBuilder.css +0 -2
  5. package/dist/Quest.css +460 -505
  6. package/dist/TaskOnProvider.css +15 -15
  7. package/dist/UserCenterWidget.css +0 -174
  8. package/dist/UserCenterWidget2.css +870 -102
  9. package/dist/chunks/{CommunityTaskList-BlH1Wdd5.js → CommunityTaskList-C9mPl_31.js} +913 -826
  10. package/dist/chunks/{EligibilityInfo-C7GZ2G5u.js → EligibilityInfo-DGBffKN8.js} +1137 -449
  11. package/dist/chunks/{LeaderboardWidget-CmYfDeHV.js → LeaderboardWidget-DPOQVXkT.js} +15 -10
  12. package/dist/chunks/{PageBuilder-Bw0zSkFh.js → PageBuilder-WCZvxL2j.js} +5 -5
  13. package/dist/chunks/{Quest-DKFZ-pPU.js → Quest-DjGH_8bx.js} +464 -314
  14. package/dist/chunks/{TaskOnProvider-BD6Vp2x8.js → TaskOnProvider-iannERG1.js} +2 -207
  15. package/dist/chunks/{ThemeProvider-wnSXrNQb.js → ThemeProvider-DNJqI2lD.js} +246 -54
  16. package/dist/chunks/UserCenterWidget-B0O-f_xl.js +8344 -0
  17. package/dist/chunks/{UserCenterWidget-Cw6h_5hT.js → UserCenterWidget-CAhgp46j.js} +204 -1001
  18. package/dist/chunks/{WidgetShell-D_5OjvNZ.js → dynamic-import-helper-B2j_dZ4V.js} +607 -40
  19. package/dist/chunks/useToast-CaRkylKe.js +304 -0
  20. package/dist/chunks/{usercenter-ja-uu-XfVF9.js → usercenter-ja-B2465c1O.js} +4 -10
  21. package/dist/chunks/{usercenter-ko-DYgUOVzd.js → usercenter-ko-xAEYxqLg.js} +4 -10
  22. package/dist/community-task.d.ts +34 -3
  23. package/dist/community-task.js +1 -1
  24. package/dist/core.d.ts +40 -3
  25. package/dist/core.js +9 -10
  26. package/dist/dynamic-import-helper.css +186 -0
  27. package/dist/index.d.ts +207 -10
  28. package/dist/index.js +21 -19
  29. package/dist/leaderboard.d.ts +8 -1
  30. package/dist/leaderboard.js +2 -2
  31. package/dist/page-builder.js +1 -1
  32. package/dist/quest.d.ts +8 -2
  33. package/dist/quest.js +1 -1
  34. package/dist/user-center.d.ts +20 -136
  35. package/dist/user-center.js +19 -236
  36. package/package.json +7 -2
  37. package/dist/TipPopover.css +0 -210
  38. package/dist/WidgetShell.css +0 -182
  39. package/dist/chunks/TipPopover-BrW8jo71.js +0 -2926
  40. package/dist/chunks/UserCenterWidget-BE329iS7.js +0 -3546
  41. package/dist/chunks/dynamic-import-helper-DxEFwm31.js +0 -537
  42. package/dist/chunks/useToast-B-wyO5zL.js +0 -93
  43. package/dist/chunks/useWidgetLocale-JDelxtt8.js +0 -74
@@ -1,14 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import React__default, { useState, useMemo, useCallback, useEffect, useRef } from "react";
3
- import { RewardType, UserEligibleStatus, EligibilityTemplateId, SnsType, ChainType, QuestAutomaticallyWinnerDrawType, QuestWinnerDrawType, QuestWinnerRangeType, createQuestApi, QuestRewardsDistributeType, QuestRewardType, createLeaderboardApi, MediaType, RewardDistributedByType } from "@taskon/core";
4
- import { b as useTaskOnContext } from "./ThemeProvider-wnSXrNQb.js";
5
- import { D as Dialog, u as useResolvedWidgetConfig, W as WidgetShell } from "./WidgetShell-D_5OjvNZ.js";
6
- import { b as useToast } from "./useToast-B-wyO5zL.js";
7
- import { R as Root2, b as Trigger, P as Portal, C as Content2, c as InfoIcon, A as Arrow2, T as TipPopover, a as useBindSocialAccount } from "./TipPopover-BrW8jo71.js";
8
- import { c as TaskItem, e as EligibilityList, g as getDefaultExportFromCjs, s as sanitizeHtml, a as useBindWallet, E as EligibilityInfo, b as BlindBoxDialog, B as BlindBoxRewardDialog } from "./EligibilityInfo-C7GZ2G5u.js";
9
- import { B as Button, T as Table, P as Pagination, _ as __variableDynamicImportRuntimeHelper } from "./dynamic-import-helper-DxEFwm31.js";
10
- import { m as enMessages, a as useTokenAssets, u as useRewardDetails, c as usePointsHistory, L as LoadingState, l as TokenRewardContent, k as PointsList, E as EmptyState, W as WithdrawForm } from "./UserCenterWidget-BE329iS7.js";
11
- import { u as useWidgetLocale } from "./useWidgetLocale-JDelxtt8.js";
3
+ import { RewardType, UserEligibleStatus, EligibilityTemplateId, SnsType, ChainType, QuestAutomaticallyWinnerDrawType, QuestWinnerDrawType, QuestWinnerRangeType, createQuestApi, QuestRewardsDistributeType, QuestRewardType, createLeaderboardApi, MediaType, RewardDistributedByType, ApiError, ErrorCode, CampaignType } from "@taskon/core";
4
+ import { s as useTaskOnPortalContainer, d as useTaskOnContext } from "./ThemeProvider-DNJqI2lD.js";
5
+ import { D as Dialog, B as Button, T as Table, P as Pagination, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-B2j_dZ4V.js";
6
+ import { d as useToast } from "./useToast-CaRkylKe.js";
7
+ import { R as Root2, o as Trigger, p as Portal, q as Content2, v as InfoIcon, r as Arrow2, s as TipPopover, g as useBindSocialAccount } from "./UserCenterWidget-B0O-f_xl.js";
8
+ import { c as TaskItem, e as EligibilityList, g as getDefaultExportFromCjs, s as sanitizeHtml, R as RewardModuleDialog, C as ConfirmNoticeDialog, u as useBindWallet, b as useNftClaimFlow, E as EligibilityInfo, B as BlindBoxDialog } from "./EligibilityInfo-DGBffKN8.js";
12
9
  import '../Quest.css';function ButtonTabs({
13
10
  items,
14
11
  activeKey,
@@ -198,6 +195,7 @@ function TaskList({
198
195
  optionalTasks = [],
199
196
  userTaskStatus,
200
197
  onTaskCompleted,
198
+ onVerifyAttempted,
201
199
  onBeforeVerify,
202
200
  disabled = false,
203
201
  minOptionalTasks,
@@ -236,6 +234,7 @@ function TaskList({
236
234
  task,
237
235
  userStatus: userTaskStatus == null ? void 0 : userTaskStatus[task.id],
238
236
  onCompleted: onTaskCompleted,
237
+ onVerifyAttempted,
239
238
  onBeforeVerify,
240
239
  disabled,
241
240
  isStarted,
@@ -283,6 +282,7 @@ function TaskList({
283
282
  task,
284
283
  userStatus: userTaskStatus == null ? void 0 : userTaskStatus[task.id],
285
284
  onCompleted: onTaskCompleted,
285
+ onVerifyAttempted,
286
286
  onBeforeVerify,
287
287
  disabled,
288
288
  isStarted,
@@ -299,6 +299,93 @@ function TaskList({
299
299
  mandatoryTasks.length === 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-task-list-empty", children: /* @__PURE__ */ jsx("p", { children: "No tasks available" }) })
300
300
  ] });
301
301
  }
302
+ function formatAmount(amount) {
303
+ const num = typeof amount === "string" ? parseFloat(amount) : amount;
304
+ if (isNaN(num)) return "0";
305
+ if (num >= 1e9) {
306
+ return `${(num / 1e9).toFixed(2)}B`;
307
+ }
308
+ if (num >= 1e6) {
309
+ return `${(num / 1e6).toFixed(2)}M`;
310
+ }
311
+ if (num >= 1e3) {
312
+ return `${(num / 1e3).toFixed(2)}K`;
313
+ }
314
+ if (num < 1 && num > 0) {
315
+ return num.toFixed(6).replace(/\.?0+$/, "");
316
+ }
317
+ return num.toFixed(2).replace(/\.?0+$/, "");
318
+ }
319
+ function formatUsdValue(amount, price) {
320
+ if (!price || price <= 0) return null;
321
+ const num = typeof amount === "string" ? parseFloat(amount) : amount;
322
+ if (isNaN(num) || num <= 0) return null;
323
+ const value = num * price;
324
+ return `≈ $${formatAmount(value)}`;
325
+ }
326
+ function RewardCard$2({
327
+ reward,
328
+ tokenPrice
329
+ }) {
330
+ if (reward.reward_type !== RewardType.Token) {
331
+ return null;
332
+ }
333
+ const tokenValue = reward.reward_value;
334
+ const amount = tokenValue.amount || "0";
335
+ const tokenName = tokenValue.token_name || "Token";
336
+ const tokenLogo = tokenValue.token_logo;
337
+ const usdValue = formatUsdValue(amount, tokenPrice);
338
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-blindbox-reward-card", children: [
339
+ tokenLogo && /* @__PURE__ */ jsx(
340
+ "img",
341
+ {
342
+ className: "taskon-quest-blindbox-reward-card-icon",
343
+ src: tokenLogo,
344
+ alt: tokenName
345
+ }
346
+ ),
347
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-blindbox-reward-card-amount", children: [
348
+ "+ ",
349
+ formatAmount(amount),
350
+ " ",
351
+ tokenName
352
+ ] }),
353
+ usdValue && /* @__PURE__ */ jsx("div", { className: "taskon-quest-blindbox-reward-card-value", children: usdValue })
354
+ ] });
355
+ }
356
+ function BlindBoxRewardDialog(props) {
357
+ const { rewards, emptyReward, tokenPrice, loading, onClose } = props;
358
+ const hasRewards = rewards.length > 0;
359
+ const title = hasRewards ? "Congratulations!" : "Oops! Better Luck Next Time!";
360
+ const subtitle = hasRewards ? "You Have Won" : "Rewards Missed";
361
+ const displayRewards = useMemo(() => {
362
+ if (hasRewards) {
363
+ return rewards;
364
+ }
365
+ return emptyReward ? [emptyReward] : [];
366
+ }, [hasRewards, rewards, emptyReward]);
367
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-blindbox-reward", children: [
368
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-blindbox-reward-title", children: title }),
369
+ /* @__PURE__ */ jsx("p", { className: "taskon-quest-blindbox-reward-subtitle", children: subtitle }),
370
+ displayRewards.length > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-quest-blindbox-reward-list", children: displayRewards.map((reward, index) => /* @__PURE__ */ jsx(
371
+ RewardCard$2,
372
+ {
373
+ reward,
374
+ tokenPrice
375
+ },
376
+ `${reward.reward_id}-${index}`
377
+ )) }),
378
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-blindbox-reward-btn-wrap", children: /* @__PURE__ */ jsx(
379
+ "button",
380
+ {
381
+ className: "taskon-quest-blindbox-reward-btn",
382
+ disabled: loading,
383
+ onClick: onClose,
384
+ children: loading ? "Loading..." : "Back"
385
+ }
386
+ ) })
387
+ ] });
388
+ }
302
389
  const BLIND_BOX_DISTRIBUTE_TYPE = "BlindBox";
303
390
  function useBlindBoxLogic(params) {
304
391
  const { campaign, userStatus } = params;
@@ -536,9 +623,7 @@ function EligsBindDialog({
536
623
  chainTypes,
537
624
  snsTypes,
538
625
  campaign,
539
- skippable = false,
540
626
  onClose,
541
- onSkip,
542
627
  onAllBind,
543
628
  onBindChain,
544
629
  onBindSns
@@ -583,12 +668,8 @@ function EligsBindDialog({
583
668
  }
584
669
  }, [onBindSns]);
585
670
  const handleClose = useCallback(() => {
586
- if (skippable) {
587
- onSkip == null ? void 0 : onSkip();
588
- } else {
589
- onClose();
590
- }
591
- }, [skippable, onSkip, onClose]);
671
+ onClose();
672
+ }, [onClose]);
592
673
  return /* @__PURE__ */ jsx(
593
674
  Dialog,
594
675
  {
@@ -617,7 +698,7 @@ function EligsBindDialog({
617
698
  }
618
699
  )
619
700
  ] }),
620
- /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: skippable ? "Please bind the following accounts to verify eligibility. You can skip this step and continue with tasks." : "Please bind the following accounts to verify eligibility." }),
701
+ /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: "Please bind the following accounts to verify eligibility." }),
621
702
  chainTypes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-section", children: [
622
703
  /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: "Wallet Address" }),
623
704
  /* @__PURE__ */ jsx("div", { className: "taskon-eligs-bind-list", children: chainTypes.map((chainType) => /* @__PURE__ */ jsx(
@@ -645,15 +726,7 @@ function EligsBindDialog({
645
726
  },
646
727
  snsType
647
728
  )) })
648
- ] }),
649
- skippable && /* @__PURE__ */ jsx(
650
- "button",
651
- {
652
- className: "taskon-eligs-bind-skip-btn",
653
- onClick: onSkip,
654
- children: "Continue with Tasks"
655
- }
656
- )
729
+ ] })
657
730
  ] })
658
731
  }
659
732
  );
@@ -987,17 +1060,6 @@ function useEligibilityRefresh(options) {
987
1060
  bindPromiseResolveRef.current = null;
988
1061
  }
989
1062
  }, []);
990
- const skipEligsBind = useCallback(() => {
991
- setEligsBindInfo(null);
992
- if (continueAfterBindRef.current) {
993
- continueAfterBindRef.current();
994
- continueAfterBindRef.current = null;
995
- }
996
- if (bindPromiseResolveRef.current) {
997
- bindPromiseResolveRef.current(true);
998
- bindPromiseResolveRef.current = null;
999
- }
1000
- }, []);
1001
1063
  const onAllEligsBind = useCallback(() => {
1002
1064
  setEligsBindInfo(null);
1003
1065
  if (continueAfterBindRef.current) {
@@ -1010,7 +1072,9 @@ function useEligibilityRefresh(options) {
1010
1072
  }
1011
1073
  }, []);
1012
1074
  const checkEligibilityAndNotify = useCallback(async () => {
1013
- if (!api || !campaign) return true;
1075
+ if (!api || !campaign) {
1076
+ return false;
1077
+ }
1014
1078
  if (!campaign.eligs || campaign.eligs.length === 0) {
1015
1079
  return true;
1016
1080
  }
@@ -1033,7 +1097,7 @@ function useEligibilityRefresh(options) {
1033
1097
  return false;
1034
1098
  } catch (error) {
1035
1099
  console.error("[useEligibilityRefresh] checkEligibility failed:", error);
1036
- return true;
1100
+ return false;
1037
1101
  }
1038
1102
  }, [api, campaign, campaignId, onEligibilityFailed]);
1039
1103
  const refreshInDialog = useCallback(async () => {
@@ -1064,7 +1128,10 @@ function useEligibilityRefresh(options) {
1064
1128
  }
1065
1129
  setIsRefreshing(true);
1066
1130
  try {
1067
- await checkEligibilityAndNotify();
1131
+ const passed = await checkEligibilityAndNotify();
1132
+ if (!passed) {
1133
+ return;
1134
+ }
1068
1135
  await onRefresh();
1069
1136
  } finally {
1070
1137
  setIsRefreshing(false);
@@ -1084,8 +1151,7 @@ function useEligibilityRefresh(options) {
1084
1151
  continueAfterBindRef.current = runEligibilityCheck;
1085
1152
  setEligsBindInfo({
1086
1153
  chainTypes,
1087
- snsTypes,
1088
- skippable: false
1154
+ snsTypes
1089
1155
  });
1090
1156
  return;
1091
1157
  }
@@ -1113,8 +1179,7 @@ function useEligibilityRefresh(options) {
1113
1179
  bindPromiseResolveRef.current = resolve;
1114
1180
  setEligsBindInfo({
1115
1181
  chainTypes,
1116
- snsTypes,
1117
- skippable: false
1182
+ snsTypes
1118
1183
  });
1119
1184
  });
1120
1185
  if (!bindCompleted) {
@@ -1142,7 +1207,6 @@ function useEligibilityRefresh(options) {
1142
1207
  // 绑定弹窗相关
1143
1208
  eligsBindInfo,
1144
1209
  closeEligsBindDialog,
1145
- skipEligsBind,
1146
1210
  onAllEligsBind
1147
1211
  };
1148
1212
  }
@@ -1358,9 +1422,7 @@ function useCompleteValidation(options) {
1358
1422
  eligsBindResolveRef.current = resolve;
1359
1423
  setEligsBindInfo({
1360
1424
  chainTypes,
1361
- snsTypes,
1362
- skippable: false
1363
- // Eligs binding is not skippable
1425
+ snsTypes
1364
1426
  });
1365
1427
  });
1366
1428
  if (!bindCompleted) {
@@ -1374,17 +1436,16 @@ function useCompleteValidation(options) {
1374
1436
  campaign_id: campaign.id
1375
1437
  });
1376
1438
  if (!result.result) {
1377
- const handled = onEligibilityFailed == null ? void 0 : onEligibilityFailed({
1439
+ onEligibilityFailed == null ? void 0 : onEligibilityFailed({
1378
1440
  eligs: campaign.eligs,
1379
1441
  eligibilityExpress: campaign.eligibility_express || "and",
1380
1442
  details: result.details
1381
1443
  });
1382
- if (!handled) {
1383
- return false;
1384
- }
1444
+ return false;
1385
1445
  }
1386
1446
  } catch (error) {
1387
1447
  console.error("[useCompleteValidation] checkEligibility failed:", error);
1448
+ return false;
1388
1449
  }
1389
1450
  }
1390
1451
  const rewardChainTypes = getRewardChainTypes(campaign.winner_rewards);
@@ -1413,12 +1474,15 @@ function useCompleteValidation(options) {
1413
1474
  }
1414
1475
  if (hasDiscordRoleReward(campaign.winner_rewards)) {
1415
1476
  if (!isDiscordBound(userProfile)) {
1416
- await new Promise((resolve) => {
1477
+ const discordResult = await new Promise((resolve) => {
1417
1478
  discordBindResolveRef.current = resolve;
1418
1479
  setDiscordBindInfo({
1419
1480
  campaignId: campaign.id
1420
1481
  });
1421
1482
  });
1483
+ if (!discordResult) {
1484
+ return false;
1485
+ }
1422
1486
  }
1423
1487
  }
1424
1488
  return true;
@@ -3926,7 +3990,7 @@ function TwitterIcon() {
3926
3990
  "path",
3927
3991
  {
3928
3992
  d: "M23 8.66667C22.6516 9.33333 22.071 10 21.2581 10.4444V10.8889C21.2581 16.4444 16.4968 21 10.6903 21C8.71613 21 6.74194 20.4444 5 19.4444C5.34839 19.4444 5.58065 19.5556 5.92903 19.4444C7.67097 19.4444 9.29677 18.8889 10.5742 17.8889C8.94839 17.8889 7.55484 16.8889 7.09032 15.4444C7.32258 15.4444 7.55484 15.5556 7.7871 15.5556C8.13548 15.5556 8.48387 15.5556 8.71613 15.4444C6.97419 15.1111 5.69677 13.6667 5.69677 12C6.16129 12.2222 6.74194 12.4444 7.32258 12.4444C6.39355 11.7778 5.8129 10.6667 5.8129 9.44444C5.8129 8.77778 6.04516 8.22222 6.27742 7.66667C8.13548 9.88889 10.9226 11.2222 13.9419 11.3333C13.8258 11.1111 13.8258 10.7778 13.8258 10.5556C13.8258 8.55556 15.4516 7 17.5419 7C18.5871 7 19.5161 7.44444 20.2129 8.11111C21.0258 8 21.8387 7.66667 22.5355 7.22222C22.3032 8 21.7226 8.77778 20.9097 9.22222C21.6065 9.11111 22.4194 8.88889 23 8.66667Z",
3929
- fill: "#54AEFF"
3993
+ fill: "currentColor"
3930
3994
  }
3931
3995
  )
3932
3996
  }
@@ -3946,7 +4010,7 @@ function CopyLinkIcon() {
3946
4010
  "path",
3947
4011
  {
3948
4012
  d: "M11.6875 16.3149L17.3178 10.6846",
3949
- stroke: "#00FFA3",
4013
+ stroke: "currentColor",
3950
4014
  strokeWidth: "2",
3951
4015
  strokeLinecap: "round",
3952
4016
  strokeLinejoin: "round"
@@ -3956,7 +4020,7 @@ function CopyLinkIcon() {
3956
4020
  "path",
3957
4021
  {
3958
4022
  d: "M9.57364 12.7959L8.16607 14.2035C6.61131 15.7582 6.61131 18.279 8.16607 19.8338C9.72083 21.3885 12.2416 21.3885 13.7964 19.8338L15.2039 18.4262",
3959
- stroke: "#00FFA3",
4023
+ stroke: "currentColor",
3960
4024
  strokeWidth: "2",
3961
4025
  strokeLinecap: "round",
3962
4026
  strokeLinejoin: "round"
@@ -3966,7 +4030,7 @@ function CopyLinkIcon() {
3966
4030
  "path",
3967
4031
  {
3968
4032
  d: "M13.7969 8.57364L15.2044 7.16607C16.7592 5.61131 19.28 5.61131 20.8347 7.16607C22.3895 8.72083 22.3895 11.2416 20.8347 12.7964L19.4272 14.2039",
3969
- stroke: "#00FFA3",
4033
+ stroke: "currentColor",
3970
4034
  strokeWidth: "2",
3971
4035
  strokeLinecap: "round",
3972
4036
  strokeLinejoin: "round"
@@ -3989,7 +4053,7 @@ function QrCodeIcon() {
3989
4053
  "path",
3990
4054
  {
3991
4055
  d: "M22 14.4429V18.943H17.5V15.9547H16V22H14.5V14.4613H19V17.4486H20.5V14.4429H22ZM12.5 14.4613V21.9308H5V14.4613H12.5ZM22 20.4369V21.9308H17.5V20.4369H22ZM11 15.9552H6.5V20.4369H11V15.9552ZM9.5 17.4491V18.943H8V17.4491H9.5ZM12.5 5V12.4695H5V5H12.5ZM22 5V12.4695H14.5V5H22ZM11 6.49389H6.5V10.9756H11V6.49389ZM20.5 6.49389H16V10.9756H20.5V6.49389ZM9.5 7.98779V9.48168H8V7.98779H9.5ZM19 7.98779V9.48168H17.5V7.98779H19Z",
3992
- fill: "#FFD465"
4056
+ fill: "currentColor"
3993
4057
  }
3994
4058
  )
3995
4059
  }
@@ -4007,6 +4071,7 @@ function ShareDropdown({
4007
4071
  endTime,
4008
4072
  winnerRewardsSimple
4009
4073
  }) {
4074
+ const portalContainer = useTaskOnPortalContainer();
4010
4075
  const { toast } = useToast();
4011
4076
  const [qrDialogOpen, setQrDialogOpen] = useState(false);
4012
4077
  const [popoverOpen, setPopoverOpen] = useState(false);
@@ -4030,11 +4095,11 @@ function ShareDropdown({
4030
4095
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4031
4096
  /* @__PURE__ */ jsxs(Root2, { open: popoverOpen, onOpenChange: setPopoverOpen, children: [
4032
4097
  /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "taskon-quest-share-trigger", "aria-label": "Share", children: /* @__PURE__ */ jsx(ShareIcon, {}) }) }),
4033
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(Content2, { className: "taskon-quest-share-menu", sideOffset: 8, children: [
4098
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(Content2, { className: "taskon-quest-share-menu", sideOffset: 8, children: [
4034
4099
  /* @__PURE__ */ jsxs(
4035
4100
  "button",
4036
4101
  {
4037
- className: "taskon-quest-share-menu-item",
4102
+ className: "taskon-quest-share-menu-item taskon-quest-share-menu-item--twitter",
4038
4103
  onClick: handleShareTwitter,
4039
4104
  children: [
4040
4105
  /* @__PURE__ */ jsx(TwitterIcon, {}),
@@ -4045,7 +4110,7 @@ function ShareDropdown({
4045
4110
  /* @__PURE__ */ jsxs(
4046
4111
  "button",
4047
4112
  {
4048
- className: "taskon-quest-share-menu-item",
4113
+ className: "taskon-quest-share-menu-item taskon-quest-share-menu-item--copy",
4049
4114
  onClick: handleCopyLink,
4050
4115
  children: [
4051
4116
  /* @__PURE__ */ jsx(CopyLinkIcon, {}),
@@ -4056,7 +4121,7 @@ function ShareDropdown({
4056
4121
  /* @__PURE__ */ jsxs(
4057
4122
  "button",
4058
4123
  {
4059
- className: "taskon-quest-share-menu-item",
4124
+ className: "taskon-quest-share-menu-item taskon-quest-share-menu-item--qr",
4060
4125
  onClick: handleShowQrCode,
4061
4126
  children: [
4062
4127
  /* @__PURE__ */ jsx(QrCodeIcon, {}),
@@ -4283,8 +4348,8 @@ function ArrowDownIcon() {
4283
4348
  y2: "-4.69753e-06",
4284
4349
  gradientUnits: "userSpaceOnUse",
4285
4350
  children: [
4286
- /* @__PURE__ */ jsx("stop", { stopColor: "#00FFA3" }),
4287
- /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#00FFA3", stopOpacity: "0.19" })
4351
+ /* @__PURE__ */ jsx("stop", { stopColor: "currentColor" }),
4352
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "currentColor", stopOpacity: "0.19" })
4288
4353
  ]
4289
4354
  }
4290
4355
  ) })
@@ -4771,6 +4836,7 @@ function ChainIcon({
4771
4836
  size = 16,
4772
4837
  chains
4773
4838
  }) {
4839
+ const portalContainer = useTaskOnPortalContainer();
4774
4840
  const [open, setOpen] = useState(false);
4775
4841
  const timeoutRef = useRef(null);
4776
4842
  const chainInfo = findChainInfo(chain, chains);
@@ -4802,7 +4868,7 @@ function ChainIcon({
4802
4868
  onMouseLeave: handleMouseLeave
4803
4869
  }
4804
4870
  ) }),
4805
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
4871
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(
4806
4872
  Content2,
4807
4873
  {
4808
4874
  className: "taskon-quest-rewards-chain-tooltip",
@@ -4836,6 +4902,7 @@ function getIsBrc20(chain, tokenAddress, chains) {
4836
4902
  return (chainInfo == null ? void 0 : chainInfo.chain_type) === "btc" && tokenAddress !== BTC_CONTRACT;
4837
4903
  }
4838
4904
  function TokenInfo({ rewardInfo, chains }) {
4905
+ const portalContainer = useTaskOnPortalContainer();
4839
4906
  const params = rewardInfo.reward_params;
4840
4907
  const distributeType = rewardInfo.reward_distribute_type;
4841
4908
  const [open, setOpen] = useState(false);
@@ -4895,7 +4962,7 @@ function TokenInfo({ rewardInfo, chains }) {
4895
4962
  ]
4896
4963
  }
4897
4964
  ) }),
4898
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
4965
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(
4899
4966
  Content2,
4900
4967
  {
4901
4968
  className: "taskon-quest-rewards-popover-content",
@@ -4944,6 +5011,7 @@ async function copyToClipboard$1(text) {
4944
5011
  }
4945
5012
  }
4946
5013
  function NftInfo({ rewardInfo, chains }) {
5014
+ const portalContainer = useTaskOnPortalContainer();
4947
5015
  const params = rewardInfo.reward_params;
4948
5016
  const [open, setOpen] = useState(false);
4949
5017
  const [copied, setCopied] = useState(false);
@@ -4990,7 +5058,7 @@ function NftInfo({ rewardInfo, chains }) {
4990
5058
  ]
4991
5059
  }
4992
5060
  ) }),
4993
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
5061
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(
4994
5062
  Content2,
4995
5063
  {
4996
5064
  className: "taskon-quest-rewards-popover-content",
@@ -5031,6 +5099,7 @@ async function copyToClipboard(text) {
5031
5099
  }
5032
5100
  }
5033
5101
  function MintedNftInfo({ rewardInfo, chains }) {
5102
+ const portalContainer = useTaskOnPortalContainer();
5034
5103
  const params = rewardInfo.reward_params;
5035
5104
  const [open, setOpen] = useState(false);
5036
5105
  const [copied, setCopied] = useState(false);
@@ -5077,7 +5146,7 @@ function MintedNftInfo({ rewardInfo, chains }) {
5077
5146
  ]
5078
5147
  }
5079
5148
  ) }),
5080
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
5149
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(
5081
5150
  Content2,
5082
5151
  {
5083
5152
  className: "taskon-quest-rewards-popover-content",
@@ -5891,7 +5960,6 @@ function LeaderboardModal({
5891
5960
  title: "Leaderboard",
5892
5961
  showCloseButton: true,
5893
5962
  className,
5894
- contentClassName: "taskon-quest-leaderboard-modal",
5895
5963
  maxWidth: 600,
5896
5964
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-content", children: [
5897
5965
  /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: "Leaderboard" }),
@@ -6237,6 +6305,32 @@ function formatLongStr(str, ellipsis = "...", prefixLen = 6, suffixLen = 4) {
6237
6305
  if (str.length <= prefixLen + suffixLen) return str;
6238
6306
  return `${str.slice(0, prefixLen)}${ellipsis}${str.slice(-suffixLen)}`;
6239
6307
  }
6308
+ function getOpenseaUrl(chainInfo) {
6309
+ if (!chainInfo) return "";
6310
+ const { name, nft_contract } = chainInfo;
6311
+ const chainName = name.toLowerCase();
6312
+ if (chainName === "core") return "";
6313
+ const openseaPrefix = "https://opensea.io/assets/";
6314
+ if (chainName === "polygon") {
6315
+ return `${openseaPrefix}matic/${nft_contract}`;
6316
+ }
6317
+ return `${openseaPrefix}${name}/${nft_contract}`;
6318
+ }
6319
+ function getIsOldCapNft(tokenId) {
6320
+ if (!tokenId) return false;
6321
+ try {
6322
+ return BigInt(tokenId) <= 2147483647n;
6323
+ } catch {
6324
+ return false;
6325
+ }
6326
+ }
6327
+ function getElementUrl(chainInfo, tokenId) {
6328
+ if (!chainInfo || !tokenId) return "";
6329
+ const chainName = chainInfo.name.toLowerCase();
6330
+ if (chainName === "core") return "";
6331
+ const nftContract = getIsOldCapNft(tokenId) ? chainInfo.old_nft_contract : chainInfo.nft_contract;
6332
+ return `https://element.market/assets/${chainInfo.name}/${nftContract}/${tokenId}`;
6333
+ }
6240
6334
  function getTxExplorerUrl(chainInfo, txHash) {
6241
6335
  if (!chainInfo || !txHash) return "";
6242
6336
  const explorerBase = chainInfo.explorer || `https://etherscan.io`;
@@ -6510,114 +6604,6 @@ function ClaimButton({
6510
6604
  }
6511
6605
  );
6512
6606
  }
6513
- function RewardModuleDialog({
6514
- open,
6515
- onOpenChange,
6516
- type,
6517
- pointsInfo
6518
- }) {
6519
- const isToken = type === "token";
6520
- const isPoints = type === "points";
6521
- const { messages, isLoading } = useWidgetLocale({
6522
- widgetId: "UserCenterWidget",
6523
- defaultMessages: enMessages,
6524
- loadMessages: (locale) => __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "../../../../UserCenter/locales/en.json": () => import("./UserCenterWidget-BE329iS7.js").then((n) => n.n), "../../../../UserCenter/locales/ja.json": () => import("./usercenter-ja-uu-XfVF9.js"), "../../../../UserCenter/locales/ko.json": () => import("./usercenter-ko-DYgUOVzd.js") }), `../../../../UserCenter/locales/${locale}.json`, 7)
6525
- });
6526
- const tokenAssets = useTokenAssets({
6527
- autoLoad: open && isToken
6528
- });
6529
- const tokenHistory = useRewardDetails({
6530
- rewardType: RewardType.Token,
6531
- autoLoad: open && isToken
6532
- });
6533
- const [showWithdrawForm, setShowWithdrawForm] = useState(false);
6534
- const [selectedTokenForWithdraw, setSelectedTokenForWithdraw] = useState(null);
6535
- const handleWithdraw = useCallback((token) => {
6536
- setSelectedTokenForWithdraw(token);
6537
- setShowWithdrawForm(true);
6538
- }, []);
6539
- const handleBatchWithdraw = useCallback(() => {
6540
- setSelectedTokenForWithdraw(null);
6541
- setShowWithdrawForm(true);
6542
- }, []);
6543
- const pointsHistory = usePointsHistory({
6544
- pointsId: (pointsInfo == null ? void 0 : pointsInfo.points_id) ?? 0,
6545
- autoLoad: open && isPoints && Boolean(pointsInfo == null ? void 0 : pointsInfo.points_id)
6546
- });
6547
- const dialogTitle = useMemo(() => {
6548
- if (isToken) return messages.rewardToken ?? "Token";
6549
- if (isPoints) return messages.pointsHistory ?? "Points History";
6550
- return "";
6551
- }, [isToken, isPoints, messages.rewardToken, messages.pointsHistory]);
6552
- const handleOpenChange = useCallback(
6553
- (nextOpen) => {
6554
- if (!nextOpen) {
6555
- setShowWithdrawForm(false);
6556
- setSelectedTokenForWithdraw(null);
6557
- }
6558
- onOpenChange(nextOpen);
6559
- },
6560
- [onOpenChange]
6561
- );
6562
- return /* @__PURE__ */ jsxs(Fragment, { children: [
6563
- /* @__PURE__ */ jsx(
6564
- Dialog,
6565
- {
6566
- open,
6567
- onOpenChange: handleOpenChange,
6568
- title: dialogTitle,
6569
- showCloseButton: true,
6570
- maxWidth: 960,
6571
- contentClassName: "taskon-quest-reward-dialog",
6572
- children: isLoading ? /* @__PURE__ */ jsx(LoadingState, { message: messages.loading }) : /* @__PURE__ */ jsxs("div", { className: "taskon-user-center taskon-user-center--popup", children: [
6573
- isToken && /* @__PURE__ */ jsx(
6574
- TokenRewardContent,
6575
- {
6576
- tokenAssets: tokenAssets.data,
6577
- tokenAssetsLoading: tokenAssets.loading,
6578
- tokenAssetsError: tokenAssets.error,
6579
- pendingWithdrawals: tokenAssets.pendingWithdrawals,
6580
- tokenHistory: tokenHistory.data,
6581
- tokenHistoryLoading: tokenHistory.loading,
6582
- tokenHistoryError: tokenHistory.error,
6583
- tokenHistoryPagination: tokenHistory.pagination,
6584
- messages,
6585
- onWithdraw: handleWithdraw,
6586
- onBatchWithdraw: handleBatchWithdraw
6587
- }
6588
- ),
6589
- isPoints && (pointsInfo ? /* @__PURE__ */ jsx(
6590
- PointsList,
6591
- {
6592
- pointsInfo,
6593
- data: pointsHistory.data,
6594
- loading: pointsHistory.loading,
6595
- error: pointsHistory.error,
6596
- pagination: pointsHistory.pagination,
6597
- messages
6598
- }
6599
- ) : /* @__PURE__ */ jsx(EmptyState, { message: messages.emptyPoints }))
6600
- ] })
6601
- }
6602
- ),
6603
- isToken && /* @__PURE__ */ jsx(
6604
- WithdrawForm,
6605
- {
6606
- open: showWithdrawForm,
6607
- messages,
6608
- tokenAssets: tokenAssets.data,
6609
- tokenAssetsLoading: tokenAssets.loading,
6610
- initialTokenId: selectedTokenForWithdraw == null ? void 0 : selectedTokenForWithdraw.token_id,
6611
- initialChain: selectedTokenForWithdraw == null ? void 0 : selectedTokenForWithdraw.chain,
6612
- onClose: () => setShowWithdrawForm(false),
6613
- onSuccess: () => {
6614
- tokenAssets.refresh();
6615
- setShowWithdrawForm(false);
6616
- }
6617
- }
6618
- )
6619
- ] });
6620
- }
6621
6607
  function RewardToken({
6622
6608
  layer,
6623
6609
  reward,
@@ -6691,10 +6677,66 @@ function RewardToken({
6691
6677
  )
6692
6678
  ] });
6693
6679
  }
6680
+ const ArrowIcon = () => /* @__PURE__ */ jsx(
6681
+ "svg",
6682
+ {
6683
+ className: "taskon-quest-footer-action-arrow",
6684
+ width: "6",
6685
+ height: "10",
6686
+ viewBox: "0 0 6 10",
6687
+ fill: "none",
6688
+ xmlns: "http://www.w3.org/2000/svg",
6689
+ children: /* @__PURE__ */ jsx(
6690
+ "path",
6691
+ {
6692
+ d: "M1 1L5 5L1 9",
6693
+ stroke: "currentColor",
6694
+ strokeWidth: "1.5",
6695
+ strokeLinecap: "round",
6696
+ strokeLinejoin: "round"
6697
+ }
6698
+ )
6699
+ }
6700
+ );
6701
+ function ActionButton({
6702
+ onClick,
6703
+ disabled = false,
6704
+ children,
6705
+ href
6706
+ }) {
6707
+ const className = `taskon-quest-footer-action-btn ${disabled ? "taskon-quest-footer-action-btn--disabled" : ""}`;
6708
+ if (href && !disabled) {
6709
+ return /* @__PURE__ */ jsxs(
6710
+ "a",
6711
+ {
6712
+ href,
6713
+ target: "_blank",
6714
+ rel: "noopener noreferrer",
6715
+ className,
6716
+ children: [
6717
+ /* @__PURE__ */ jsx("span", { children }),
6718
+ /* @__PURE__ */ jsx(ArrowIcon, {})
6719
+ ]
6720
+ }
6721
+ );
6722
+ }
6723
+ return /* @__PURE__ */ jsxs(
6724
+ "div",
6725
+ {
6726
+ className,
6727
+ onClick: disabled ? void 0 : onClick,
6728
+ role: onClick && !disabled ? "button" : void 0,
6729
+ tabIndex: onClick && !disabled ? 0 : void 0,
6730
+ children: [
6731
+ /* @__PURE__ */ jsx("span", { children }),
6732
+ !disabled && /* @__PURE__ */ jsx(ArrowIcon, {})
6733
+ ]
6734
+ }
6735
+ );
6736
+ }
6694
6737
  function RewardNft({
6695
6738
  layer,
6696
6739
  reward,
6697
- campaign,
6698
6740
  chains,
6699
6741
  onRefresh,
6700
6742
  onClaimNft
@@ -6703,22 +6745,17 @@ function RewardNft({
6703
6745
  const params = reward.reward_value;
6704
6746
  const chainInfo = useMemo(() => {
6705
6747
  if (!chains || !params.chain) return null;
6706
- return chains[params.chain] || null;
6748
+ return chains[params.chain] || chains[params.chain.toLowerCase()] || null;
6707
6749
  }, [chains, params.chain]);
6708
- const rewardInfo = useMemo(() => {
6709
- const winnerReward = campaign.winner_rewards[layer.winner_index];
6710
- if (!winnerReward) return null;
6711
- const layerReward = winnerReward.winner_layer_rewards[layer.layer_no];
6712
- if (!layerReward) return null;
6713
- return layerReward.rewards.find((item) => item.reward_id === reward.reward_id) || null;
6714
- }, [campaign, layer, reward.reward_id]);
6715
- const isDeposited = useMemo(() => {
6716
- const distributedByType = rewardInfo == null ? void 0 : rewardInfo.reward_distributed_by_type;
6717
- return distributedByType === RewardDistributedByType.Taskon;
6718
- }, [rewardInfo]);
6750
+ const openseaLink = useMemo(() => {
6751
+ if (!params.token_id) {
6752
+ return "";
6753
+ }
6754
+ return getOpenseaUrl(chainInfo);
6755
+ }, [chainInfo, params.token_id]);
6719
6756
  const handleClaim = useCallback(async () => {
6720
6757
  if (!onClaimNft) {
6721
- console.warn("onClaimNft callback not provided");
6758
+ console.warn("NFT claim handler not provided");
6722
6759
  return;
6723
6760
  }
6724
6761
  setLoading(true);
@@ -6731,8 +6768,6 @@ function RewardNft({
6731
6768
  setLoading(false);
6732
6769
  }
6733
6770
  }, [onClaimNft, reward, layer, onRefresh]);
6734
- const buttonText = params.tx_hash ? "Retry" : "Claim";
6735
- const showButton = params.claimable || isDeposited && params.tx_hash;
6736
6771
  return /* @__PURE__ */ jsxs(RewardCard, { children: [
6737
6772
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-row", children: [
6738
6773
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-info", children: [
@@ -6747,9 +6782,9 @@ function RewardNft({
6747
6782
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6748
6783
  ] }),
6749
6784
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6750
- showButton && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: buttonText })
6785
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6751
6786
  ] }),
6752
- params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6787
+ openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: "Check Collection on OpenSea" }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6753
6788
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: "Txn Hash:" }),
6754
6789
  /* @__PURE__ */ jsx(
6755
6790
  "a",
@@ -6775,14 +6810,20 @@ function RewardMintedNft({
6775
6810
  const params = reward.reward_value;
6776
6811
  const chainInfo = useMemo(() => {
6777
6812
  if (!chains || !params.chain) return null;
6778
- return chains[params.chain] || null;
6813
+ return chains[params.chain] || chains[params.chain.toLowerCase()] || null;
6779
6814
  }, [chains, params.chain]);
6815
+ const openseaLink = useMemo(() => {
6816
+ if (!params.token_id) {
6817
+ return "";
6818
+ }
6819
+ return getOpenseaUrl(chainInfo);
6820
+ }, [chainInfo, params.token_id]);
6780
6821
  const isGasStationDropping = useMemo(() => {
6781
6822
  return !!(params.gs_req_id && !params.tx_hash);
6782
6823
  }, [params.gs_req_id, params.tx_hash]);
6783
6824
  const handleClaim = useCallback(async () => {
6784
6825
  if (!onClaimNft) {
6785
- console.warn("onClaimNft callback not provided");
6826
+ console.warn("NFT claim handler not provided");
6786
6827
  return;
6787
6828
  }
6788
6829
  setLoading(true);
@@ -6795,8 +6836,6 @@ function RewardMintedNft({
6795
6836
  setLoading(false);
6796
6837
  }
6797
6838
  }, [onClaimNft, reward, layer, onRefresh]);
6798
- const buttonText = params.tx_hash ? "Retry" : "Claim";
6799
- const showButton = params.claimable;
6800
6839
  return /* @__PURE__ */ jsxs(RewardCard, { children: [
6801
6840
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-row", children: [
6802
6841
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-info", children: [
@@ -6811,9 +6850,9 @@ function RewardMintedNft({
6811
6850
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6812
6851
  ] }),
6813
6852
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6814
- showButton && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: buttonText })
6853
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6815
6854
  ] }),
6816
- params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6855
+ openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: "Check Collection on OpenSea" }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6817
6856
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: "Txn Hash:" }),
6818
6857
  /* @__PURE__ */ jsx(
6819
6858
  "a",
@@ -6840,14 +6879,17 @@ function RewardCap({
6840
6879
  const params = reward.reward_value;
6841
6880
  const chainInfo = useMemo(() => {
6842
6881
  if (!chains || !params.chain) return null;
6843
- return chains[params.chain] || null;
6882
+ return chains[params.chain] || chains[params.chain.toLowerCase()] || null;
6844
6883
  }, [chains, params.chain]);
6884
+ const elementLink = useMemo(() => {
6885
+ return getElementUrl(chainInfo, params.token_id);
6886
+ }, [chainInfo, params.token_id]);
6845
6887
  const isGasStationDropping = useMemo(() => {
6846
6888
  return !!(params.gs_req_id && !params.tx_hash);
6847
6889
  }, [params.gs_req_id, params.tx_hash]);
6848
6890
  const handleClaim = useCallback(async () => {
6849
6891
  if (!onClaimNft) {
6850
- console.warn("onClaimNft callback not provided");
6892
+ console.warn("NFT claim handler not provided");
6851
6893
  return;
6852
6894
  }
6853
6895
  setLoading(true);
@@ -6875,6 +6917,7 @@ function RewardCap({
6875
6917
  ] }),
6876
6918
  params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6877
6919
  ] }),
6920
+ elementLink && /* @__PURE__ */ jsx(ActionButton, { href: elementLink, children: "Check CAP on Element" }),
6878
6921
  isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "Cap will be airdropped soon..." })
6879
6922
  ] });
6880
6923
  }
@@ -6899,63 +6942,6 @@ function RewardWhitelist({
6899
6942
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Whitelist" })
6900
6943
  ] }) }) });
6901
6944
  }
6902
- const ArrowIcon = () => /* @__PURE__ */ jsx(
6903
- "svg",
6904
- {
6905
- className: "taskon-quest-footer-action-arrow",
6906
- width: "6",
6907
- height: "10",
6908
- viewBox: "0 0 6 10",
6909
- fill: "none",
6910
- xmlns: "http://www.w3.org/2000/svg",
6911
- children: /* @__PURE__ */ jsx(
6912
- "path",
6913
- {
6914
- d: "M1 1L5 5L1 9",
6915
- stroke: "currentColor",
6916
- strokeWidth: "1.5",
6917
- strokeLinecap: "round",
6918
- strokeLinejoin: "round"
6919
- }
6920
- )
6921
- }
6922
- );
6923
- function ActionButton({
6924
- onClick,
6925
- disabled = false,
6926
- children,
6927
- href
6928
- }) {
6929
- const className = `taskon-quest-footer-action-btn ${disabled ? "taskon-quest-footer-action-btn--disabled" : ""}`;
6930
- if (href && !disabled) {
6931
- return /* @__PURE__ */ jsxs(
6932
- "a",
6933
- {
6934
- href,
6935
- target: "_blank",
6936
- rel: "noopener noreferrer",
6937
- className,
6938
- children: [
6939
- /* @__PURE__ */ jsx("span", { children }),
6940
- /* @__PURE__ */ jsx(ArrowIcon, {})
6941
- ]
6942
- }
6943
- );
6944
- }
6945
- return /* @__PURE__ */ jsxs(
6946
- "div",
6947
- {
6948
- className,
6949
- onClick: disabled ? void 0 : onClick,
6950
- role: onClick && !disabled ? "button" : void 0,
6951
- tabIndex: onClick && !disabled ? 0 : void 0,
6952
- children: [
6953
- /* @__PURE__ */ jsx("span", { children }),
6954
- !disabled && /* @__PURE__ */ jsx(ArrowIcon, {})
6955
- ]
6956
- }
6957
- );
6958
- }
6959
6945
  function RewardPoint({
6960
6946
  reward,
6961
6947
  rewardDisplayMode = "popup",
@@ -7339,6 +7325,20 @@ function StatusCard(props) {
7339
7325
  ) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-card-message", children: description }) })
7340
7326
  ] });
7341
7327
  }
7328
+ const REPEAT_SUBMIT_ERROR_MESSAGE = "Oops! Seems like you already finished this quest";
7329
+ const DEFAULT_COMPLETE_ERROR_MESSAGE = "Failed to complete quest";
7330
+ function normalizeCompleteSubmitError(error) {
7331
+ if (error instanceof ApiError) {
7332
+ if (error.code === ErrorCode.RUSER_REPEAT_SUBMIT) {
7333
+ return new ApiError(error.code, REPEAT_SUBMIT_ERROR_MESSAGE, error.data);
7334
+ }
7335
+ return error;
7336
+ }
7337
+ if (error instanceof Error) {
7338
+ return error;
7339
+ }
7340
+ return new Error(DEFAULT_COMPLETE_ERROR_MESSAGE);
7341
+ }
7342
7342
  function CompleteButton({
7343
7343
  campaignId,
7344
7344
  hasPointProportionally: hasPointProportionally2 = false,
@@ -7361,33 +7361,35 @@ function CompleteButton({
7361
7361
  if (!api || isLoading || disabled) {
7362
7362
  return;
7363
7363
  }
7364
- if (onBeforeComplete) {
7365
- try {
7366
- const canContinue = await onBeforeComplete();
7367
- if (!canContinue) {
7364
+ setIsLoading(true);
7365
+ try {
7366
+ if (onBeforeComplete) {
7367
+ try {
7368
+ const canContinue = await onBeforeComplete();
7369
+ if (!canContinue) {
7370
+ return;
7371
+ }
7372
+ } catch (error) {
7373
+ console.error("[CompleteButton] onBeforeComplete error:", error);
7368
7374
  return;
7369
7375
  }
7370
- } catch (error) {
7371
- console.error("[CompleteButton] onBeforeComplete error:", error);
7376
+ }
7377
+ if (requiresRecaptcha && !captchaToken) {
7378
+ onError == null ? void 0 : onError(new Error("reCAPTCHA verification required"));
7372
7379
  return;
7373
7380
  }
7374
- }
7375
- if (requiresRecaptcha && !captchaToken) {
7376
- onError == null ? void 0 : onError(new Error("reCAPTCHA verification required"));
7377
- return;
7378
- }
7379
- setIsLoading(true);
7380
- try {
7381
- await api.submitCampaign({
7382
- campaign_id: campaignId,
7383
- // Widget version: always false (no auto-join checkbox)
7384
- auto_follow_community: false,
7385
- captcha_token: captchaToken
7386
- });
7387
- onComplete == null ? void 0 : onComplete();
7388
- } catch (error) {
7389
- const errorMessage = error instanceof Error ? error.message : "Failed to complete quest";
7390
- onError == null ? void 0 : onError(new Error(errorMessage));
7381
+ try {
7382
+ await api.submitCampaign({
7383
+ campaign_id: campaignId,
7384
+ // Widget version: always false (no auto-join checkbox)
7385
+ auto_follow_community: false,
7386
+ captcha_token: captchaToken
7387
+ });
7388
+ onComplete == null ? void 0 : onComplete();
7389
+ } catch (error) {
7390
+ const normalizedError = normalizeCompleteSubmitError(error);
7391
+ onError == null ? void 0 : onError(normalizedError);
7392
+ }
7391
7393
  } finally {
7392
7394
  setIsLoading(false);
7393
7395
  }
@@ -7416,6 +7418,9 @@ function CompleteButton({
7416
7418
  }
7417
7419
  );
7418
7420
  }
7421
+ const REPEAT_SUBMIT_NOTICE_TITLE = "Oops! Seems like You already finished this quest";
7422
+ const REPEAT_SUBMIT_NOTICE_DESC = "To ensure a fair experience, submissions with identical wallet addresses, X, Discord, or Telegram accounts, and email addresses are not permitted.";
7423
+ const REPEAT_SUBMIT_NOTICE_CONFIRM = "Confirm";
7419
7424
  function OperateFooter(props) {
7420
7425
  const {
7421
7426
  campaign,
@@ -7436,6 +7441,8 @@ function OperateFooter(props) {
7436
7441
  rewardDisplayMode,
7437
7442
  rewardRedirectUrl
7438
7443
  } = props;
7444
+ const { toast } = useToast();
7445
+ const [isRepeatSubmitDialogVisible, setIsRepeatSubmitDialogVisible] = useState(false);
7439
7446
  const hasRanking = useMemo(() => {
7440
7447
  return hasPointRanking(campaign.winner_rewards);
7441
7448
  }, [campaign.winner_rewards]);
@@ -7483,6 +7490,16 @@ function OperateFooter(props) {
7483
7490
  children: "Connect Wallet to Participate"
7484
7491
  }
7485
7492
  ) });
7493
+ const handleCompleteError = useCallback(
7494
+ (error) => {
7495
+ if (error instanceof ApiError && error.code === ErrorCode.RUSER_REPEAT_SUBMIT) {
7496
+ setIsRepeatSubmitDialogVisible(true);
7497
+ return;
7498
+ }
7499
+ toast.error(error.message);
7500
+ },
7501
+ [toast]
7502
+ );
7486
7503
  const renderCompleteButton = () => /* @__PURE__ */ jsx(
7487
7504
  CompleteButton,
7488
7505
  {
@@ -7492,9 +7509,7 @@ function OperateFooter(props) {
7492
7509
  disabled: !isActive,
7493
7510
  onBeforeComplete,
7494
7511
  onComplete,
7495
- onError: (error) => {
7496
- console.error("Complete quest error:", error.message);
7497
- }
7512
+ onError: handleCompleteError
7498
7513
  }
7499
7514
  );
7500
7515
  const renderStatusCard = () => {
@@ -7520,19 +7535,35 @@ function OperateFooter(props) {
7520
7535
  }
7521
7536
  );
7522
7537
  };
7538
+ const renderRepeatSubmitNoticeDialog = () => /* @__PURE__ */ jsx(
7539
+ ConfirmNoticeDialog,
7540
+ {
7541
+ open: isRepeatSubmitDialogVisible,
7542
+ onOpenChange: setIsRepeatSubmitDialogVisible,
7543
+ type: "warn",
7544
+ title: REPEAT_SUBMIT_NOTICE_TITLE,
7545
+ desc: REPEAT_SUBMIT_NOTICE_DESC,
7546
+ confirmButton: REPEAT_SUBMIT_NOTICE_CONFIRM,
7547
+ onConfirm: () => setIsRepeatSubmitDialogVisible(false),
7548
+ accessibilityTitle: REPEAT_SUBMIT_NOTICE_TITLE,
7549
+ accessibilityDescription: REPEAT_SUBMIT_NOTICE_DESC
7550
+ }
7551
+ );
7552
+ let footerContent = null;
7523
7553
  if (participationStatus === "not-logged-in") {
7524
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer", id: "detail-operate-footer", children: renderConnectWallet() });
7554
+ footerContent = renderConnectWallet();
7555
+ } else if (participationStatus === "can-complete") {
7556
+ footerContent = renderCompleteButton();
7557
+ } else if (participationStatus !== "none" && cardConfig) {
7558
+ footerContent = renderStatusCard();
7525
7559
  }
7526
- if (participationStatus === "none") {
7560
+ if (!footerContent && !isRepeatSubmitDialogVisible) {
7527
7561
  return null;
7528
7562
  }
7529
- if (participationStatus === "can-complete") {
7530
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer", id: "detail-operate-footer", children: renderCompleteButton() });
7531
- }
7532
- if (cardConfig) {
7533
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer", id: "detail-operate-footer", children: renderStatusCard() });
7534
- }
7535
- return null;
7563
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer", id: "detail-operate-footer", children: [
7564
+ footerContent,
7565
+ renderRepeatSubmitNoticeDialog()
7566
+ ] });
7536
7567
  }
7537
7568
  function getDialogTitle(errorType) {
7538
7569
  switch (errorType) {
@@ -7557,17 +7588,17 @@ function getDialogIcon(errorType) {
7557
7588
  fill: "none",
7558
7589
  xmlns: "http://www.w3.org/2000/svg",
7559
7590
  children: [
7560
- /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "22", stroke: "#FF9500", strokeWidth: "4" }),
7591
+ /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "22", stroke: "currentColor", strokeWidth: "4" }),
7561
7592
  /* @__PURE__ */ jsx(
7562
7593
  "path",
7563
7594
  {
7564
7595
  d: "M24 14V28",
7565
- stroke: "#FF9500",
7596
+ stroke: "currentColor",
7566
7597
  strokeWidth: "4",
7567
7598
  strokeLinecap: "round"
7568
7599
  }
7569
7600
  ),
7570
- /* @__PURE__ */ jsx("circle", { cx: "24", cy: "35", r: "2.5", fill: "#FF9500" })
7601
+ /* @__PURE__ */ jsx("circle", { cx: "24", cy: "35", r: "2.5", fill: "currentColor" })
7571
7602
  ]
7572
7603
  }
7573
7604
  );
@@ -7759,12 +7790,12 @@ function DiscordIcon() {
7759
7790
  fill: "none",
7760
7791
  xmlns: "http://www.w3.org/2000/svg",
7761
7792
  children: [
7762
- /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "24", fill: "#5865F2" }),
7793
+ /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "24", fill: "var(--taskon-color-link)" }),
7763
7794
  /* @__PURE__ */ jsx(
7764
7795
  "path",
7765
7796
  {
7766
7797
  d: "M32.6 17.3C31.1 16.6 29.5 16.1 27.8 15.8C27.6 16.2 27.3 16.7 27.1 17.1C25.3 16.8 23.5 16.8 21.7 17.1C21.5 16.7 21.2 16.2 21 15.8C19.3 16.1 17.7 16.6 16.2 17.3C13.2 21.8 12.4 26.2 12.8 30.5C14.8 32 16.7 32.8 18.6 33.4C19.1 32.7 19.5 31.9 19.9 31.1C19.1 30.8 18.4 30.4 17.7 29.9C17.9 29.8 18.1 29.6 18.2 29.5C22 31.3 26.2 31.3 29.9 29.5C30.1 29.7 30.3 29.8 30.4 29.9C29.7 30.4 29 30.8 28.2 31.1C28.6 31.9 29 32.7 29.5 33.4C31.4 32.8 33.3 32 35.3 30.5C35.8 25.5 34.5 21.2 32.6 17.3ZM19.4 28.1C18.4 28.1 17.6 27.2 17.6 26.1C17.6 25 18.4 24.1 19.4 24.1C20.4 24.1 21.2 25 21.2 26.1C21.2 27.2 20.4 28.1 19.4 28.1ZM28.6 28.1C27.6 28.1 26.8 27.2 26.8 26.1C26.8 25 27.6 24.1 28.6 24.1C29.6 24.1 30.4 25 30.4 26.1C30.4 27.2 29.6 28.1 28.6 28.1Z",
7767
- fill: "white"
7798
+ fill: "var(--taskon-color-text)"
7768
7799
  }
7769
7800
  )
7770
7801
  ]
@@ -8108,6 +8139,33 @@ function mergeQuestConfig(props, cloud) {
8108
8139
  rewardRedirectUrl: props.rewardRedirectUrl ?? (cloud == null ? void 0 : cloud.rewardRedirectUrl) ?? ""
8109
8140
  };
8110
8141
  }
8142
+ const QUEST_NFT_CLAIM_MESSAGES = {
8143
+ claimDialog: {
8144
+ claimNft: "Claim NFT",
8145
+ claimingNft: "Claiming NFT...",
8146
+ claimConnectingWallet: "Connecting wallet...",
8147
+ claimSwitchingNetwork: "Switching network...",
8148
+ claimGettingSignature: "Getting signature...",
8149
+ claimConfirmInWallet: "Please confirm in your wallet",
8150
+ claimTransactionPending: "Transaction pending...",
8151
+ claimSuccess: "Claim successful!",
8152
+ claimFailed: "Claim failed",
8153
+ claimCanceled: "Transaction was rejected by user.",
8154
+ viewOnExplorer: "View on Explorer",
8155
+ retry: "Retry",
8156
+ close: "Close"
8157
+ },
8158
+ pendingDialog: {
8159
+ pendingTransaction: "Pending Transaction",
8160
+ claimPendingTitle: "You have already claimed this NFT, please wait for this transaction to be confirmed.",
8161
+ claimPendingCheckExplorer: "You can check this transaction on explorer:",
8162
+ claimPendingHashLabel: "Transaction hash:",
8163
+ claimPendingClaimAgainWarn: '"Claim Again" will send a new transaction it is only recommended when you are sure there is something wrong with the current transaction.',
8164
+ claimPendingReceiveAddressNoChange: "This receive address can’t be changed:",
8165
+ claimAgain: "Claim Again",
8166
+ continueWaiting: "Continue Waiting"
8167
+ }
8168
+ };
8111
8169
  function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd) {
8112
8170
  const now = Date.now();
8113
8171
  const startMs = startTime;
@@ -8144,7 +8202,7 @@ function getHasRanking(winnerRewards) {
8144
8202
  );
8145
8203
  }
8146
8204
  function QuestWidget(props) {
8147
- const { widgetId } = props;
8205
+ const { widgetId, themeMode } = props;
8148
8206
  const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
8149
8207
  const mergedConfig = useMemo(() => {
8150
8208
  return mergeQuestConfig(
@@ -8171,6 +8229,7 @@ function QuestWidget(props) {
8171
8229
  widgetId,
8172
8230
  isConfigLoading,
8173
8231
  cloudTheme,
8232
+ themeMode,
8174
8233
  className: "taskon-quest",
8175
8234
  errorMessage: configError ?? (!mergedConfig.campaignId ? "Campaign ID is required. Please provide campaignId via props or widgetId." : void 0),
8176
8235
  children: /* @__PURE__ */ jsx(
@@ -8211,7 +8270,6 @@ function QuestWidgetInner(props) {
8211
8270
  onSubmitSuccess,
8212
8271
  onError,
8213
8272
  onConnectWallet,
8214
- onClaimNft,
8215
8273
  onClaimDiscordRole,
8216
8274
  // onBindChainRequired 和 onBindSnsRequired 已弃用,绑定现在由 Widget 内部处理
8217
8275
  shareUrl,
@@ -8283,6 +8341,34 @@ function QuestWidgetInner(props) {
8283
8341
  kolHandle,
8284
8342
  enabled: !isPreview
8285
8343
  });
8344
+ const {
8345
+ claimNftReward,
8346
+ isSupportedNftRewardType,
8347
+ dialogs: nftClaimDialogs
8348
+ } = useNftClaimFlow({
8349
+ campaignId,
8350
+ targetType: (campaign == null ? void 0 : campaign.campaign_type) === CampaignType.Event ? "event" : "campaign",
8351
+ messages: QUEST_NFT_CLAIM_MESSAGES,
8352
+ onClaimSuccess: async () => {
8353
+ refetchUserStatus();
8354
+ refetchStatus();
8355
+ },
8356
+ onClaimError: (error2) => {
8357
+ toast.error(error2.message || "Failed to claim NFT");
8358
+ },
8359
+ onWalletError: (errorMessage) => {
8360
+ toast.error(errorMessage);
8361
+ }
8362
+ });
8363
+ const handleQuestClaimNft = useCallback(
8364
+ async (reward, layer) => {
8365
+ if (!isSupportedNftRewardType(reward.reward_type)) {
8366
+ return;
8367
+ }
8368
+ await claimNftReward(reward, layer);
8369
+ },
8370
+ [isSupportedNftRewardType, claimNftReward]
8371
+ );
8286
8372
  const {
8287
8373
  mandatoryTasks,
8288
8374
  optionalTasks,
@@ -8458,6 +8544,22 @@ function QuestWidgetInner(props) {
8458
8544
  refetchUserStatus();
8459
8545
  }
8460
8546
  };
8547
+ const handleTaskVerifyAttempted = useCallback(
8548
+ (taskId, success) => {
8549
+ var _a2;
8550
+ if (success || isPreview) {
8551
+ return;
8552
+ }
8553
+ const targetTask = (_a2 = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _a2.find((task) => task.id === taskId);
8554
+ if (!targetTask) {
8555
+ return;
8556
+ }
8557
+ if (targetTask.template_id === "SwapDexContractInteractive") {
8558
+ refetchUserStatus();
8559
+ }
8560
+ },
8561
+ [campaign == null ? void 0 : campaign.tasks, isPreview, refetchUserStatus]
8562
+ );
8461
8563
  const handleSubmitSuccess = () => {
8462
8564
  refetchDetail();
8463
8565
  refetchUserStatus();
@@ -8474,7 +8576,6 @@ function QuestWidgetInner(props) {
8474
8576
  // 绑定弹窗相关
8475
8577
  eligsBindInfo,
8476
8578
  closeEligsBindDialog,
8477
- skipEligsBind,
8478
8579
  onAllEligsBind
8479
8580
  } = useEligibilityRefresh({
8480
8581
  api,
@@ -8493,6 +8594,42 @@ function QuestWidgetInner(props) {
8493
8594
  await refetchUserStatus();
8494
8595
  }
8495
8596
  });
8597
+ const [completeEligibilityFailedInfo, setCompleteEligibilityFailedInfo] = useState(null);
8598
+ const [isRefreshingCompleteEligs, setIsRefreshingCompleteEligs] = useState(false);
8599
+ const closeCompleteEligibilityFailedDialog = useCallback(() => {
8600
+ setCompleteEligibilityFailedInfo(null);
8601
+ }, []);
8602
+ const refreshCompleteEligibilityInDialog = useCallback(async () => {
8603
+ if (!api || !campaign) {
8604
+ return;
8605
+ }
8606
+ setIsRefreshingCompleteEligs(true);
8607
+ try {
8608
+ const result = await api.checkUserCampaignEligibility({
8609
+ campaign_id: campaign.id
8610
+ });
8611
+ if (result.result) {
8612
+ setCompleteEligibilityFailedInfo(null);
8613
+ await refetchUserStatus();
8614
+ return;
8615
+ }
8616
+ setCompleteEligibilityFailedInfo((previousInfo) => {
8617
+ if (!previousInfo) {
8618
+ return {
8619
+ eligs: campaign.eligs,
8620
+ eligibilityExpress: campaign.eligibility_express || "and",
8621
+ details: result.details
8622
+ };
8623
+ }
8624
+ return {
8625
+ ...previousInfo,
8626
+ details: result.details
8627
+ };
8628
+ });
8629
+ } finally {
8630
+ setIsRefreshingCompleteEligs(false);
8631
+ }
8632
+ }, [api, campaign, refetchUserStatus]);
8496
8633
  const {
8497
8634
  validateBeforeComplete,
8498
8635
  // Task validation error dialog
@@ -8528,9 +8665,10 @@ function QuestWidgetInner(props) {
8528
8665
  onBindSns: async (snsType) => {
8529
8666
  return await bindSnsAndWait(snsType);
8530
8667
  },
8531
- // When eligibility check fails, show the existing EligsNotPassDialog
8532
- onEligibilityFailed: () => {
8533
- return false;
8668
+ // Complete eligibility 检查失败:
8669
+ // 弹出 EligsNotPassDialog 并阻断 complete,行为对齐 Vue。
8670
+ onEligibilityFailed: (info) => {
8671
+ setCompleteEligibilityFailedInfo(info);
8534
8672
  }
8535
8673
  });
8536
8674
  const hasEligibility = (campaign == null ? void 0 : campaign.eligs) && campaign.eligs.length > 0;
@@ -8609,6 +8747,7 @@ function QuestWidgetInner(props) {
8609
8747
  optionalTasks: optionalTaskData,
8610
8748
  userTaskStatus: userTaskStatusMap,
8611
8749
  onTaskCompleted: handleTaskCompleted,
8750
+ onVerifyAttempted: handleTaskVerifyAttempted,
8612
8751
  onBeforeVerify: checkBeforeSubmitTask,
8613
8752
  disabled: isTaskDisabled,
8614
8753
  isStarted: statusDisplay == null ? void 0 : statusDisplay.isStarted,
@@ -8640,7 +8779,7 @@ function QuestWidgetInner(props) {
8640
8779
  refetchStatus();
8641
8780
  },
8642
8781
  onConnectWallet,
8643
- onClaimNft,
8782
+ onClaimNft: handleQuestClaimNft,
8644
8783
  onClaimDiscordRole,
8645
8784
  onBeforeComplete: validateBeforeComplete,
8646
8785
  rewardDisplayMode,
@@ -8769,6 +8908,21 @@ function QuestWidgetInner(props) {
8769
8908
  isRefreshing: isRefreshingEligs
8770
8909
  }
8771
8910
  ),
8911
+ completeEligibilityFailedInfo && campaign && /* @__PURE__ */ jsx(
8912
+ EligsNotPassDialog,
8913
+ {
8914
+ open: !!completeEligibilityFailedInfo,
8915
+ onClose: closeCompleteEligibilityFailedDialog,
8916
+ eligs: completeEligibilityFailedInfo.eligs,
8917
+ eligibilityExpress: completeEligibilityFailedInfo.eligibilityExpress,
8918
+ details: completeEligibilityFailedInfo.details,
8919
+ campaignId,
8920
+ communityKey: campaign.community_key,
8921
+ communityName: campaign.community_name,
8922
+ onRefresh: refreshCompleteEligibilityInDialog,
8923
+ isRefreshing: isRefreshingCompleteEligs
8924
+ }
8925
+ ),
8772
8926
  eligsBindInfo && campaign && /* @__PURE__ */ jsx(
8773
8927
  EligsBindDialog,
8774
8928
  {
@@ -8776,9 +8930,7 @@ function QuestWidgetInner(props) {
8776
8930
  chainTypes: eligsBindInfo.chainTypes,
8777
8931
  snsTypes: eligsBindInfo.snsTypes,
8778
8932
  campaign,
8779
- skippable: eligsBindInfo.skippable,
8780
8933
  onClose: closeEligsBindDialog,
8781
- onSkip: skipEligsBind,
8782
8934
  onAllBind: onAllEligsBind,
8783
8935
  onBindChain: bindChainAndWait,
8784
8936
  onBindSns: bindSnsAndWait
@@ -8820,15 +8972,13 @@ function QuestWidgetInner(props) {
8820
8972
  chainTypes: completeEligsBindInfo.chainTypes,
8821
8973
  snsTypes: completeEligsBindInfo.snsTypes,
8822
8974
  campaign,
8823
- skippable: completeEligsBindInfo.skippable,
8824
8975
  onClose: closeCompleteEligsBindDialog,
8825
- onSkip: () => {
8826
- },
8827
8976
  onAllBind: onAllCompleteEligsBind,
8828
8977
  onBindChain: bindChainAndWait,
8829
8978
  onBindSns: bindSnsAndWait
8830
8979
  }
8831
- )
8980
+ ),
8981
+ nftClaimDialogs
8832
8982
  ] });
8833
8983
  }
8834
8984
  export {