@taskon/widget-react 0.0.1-beta.4 → 0.0.1-beta.6

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 (58) hide show
  1. package/README.md +13 -4
  2. package/dist/CommunityTaskList.css +119 -111
  3. package/dist/EligibilityInfo.css +114 -110
  4. package/dist/LeaderboardWidget.css +73 -71
  5. package/dist/PageBuilder.css +5 -0
  6. package/dist/Quest.css +259 -255
  7. package/dist/TaskOnProvider.css +2 -0
  8. package/dist/UserCenterWidget.css +6 -6
  9. package/dist/UserCenterWidget2.css +1626 -1601
  10. package/dist/{dynamic-import-helper.css → WidgetShell.css} +2 -2
  11. package/dist/chunks/{CommunityTaskList-C9Gv8KOF.js → CommunityTaskList-Hde2OKHH.js} +1070 -580
  12. package/dist/chunks/{EligibilityInfo-D-Fuy9GE.js → EligibilityInfo-BV0Z2TgY.js} +1972 -1028
  13. package/dist/chunks/{LeaderboardWidget-BV2D2q1N.js → LeaderboardWidget-BNGRD5Bu.js} +270 -249
  14. package/dist/chunks/{PageBuilder-DQoU4Mwf.js → PageBuilder-C5DSHiW9.js} +5 -5
  15. package/dist/chunks/{Quest-B5NyVr3o.js → Quest-DG9zfXJo.js} +723 -513
  16. package/dist/chunks/{TaskOnProvider-93UxARFo.js → TaskOnProvider-BhamHIyY.js} +98 -68
  17. package/dist/chunks/{ThemeProvider-CPI_roeh.js → ThemeProvider-mXLdLSkq.js} +107 -20
  18. package/dist/chunks/{UserCenterWidget-cADBSVg7.js → UserCenterWidget-D5ttw4hO.js} +1328 -1337
  19. package/dist/chunks/{UserCenterWidget-BRtigY_S.js → UserCenterWidget-jDO5zTN1.js} +358 -254
  20. package/dist/chunks/{dynamic-import-helper-DwXlQC0S.js → WidgetShell-D7yC894Y.js} +447 -457
  21. package/dist/chunks/communitytask-es-CBNnS4o2.js +521 -0
  22. package/dist/chunks/communitytask-ja-GRf9cbdx.js +521 -0
  23. package/dist/chunks/communitytask-ko-Bf24PQKI.js +521 -0
  24. package/dist/chunks/communitytask-ru-CZm2CPoV.js +521 -0
  25. package/dist/chunks/leaderboardwidget-es-vKjrjQaz.js +146 -0
  26. package/dist/chunks/leaderboardwidget-ja-Q6u0HxKG.js +146 -0
  27. package/dist/chunks/leaderboardwidget-ko-CG6SWgxf.js +146 -0
  28. package/dist/chunks/leaderboardwidget-ru-DCcHcJGz.js +146 -0
  29. package/dist/chunks/quest-es-Dyyy0zaw.js +863 -0
  30. package/dist/chunks/quest-ja-Depog33y.js +863 -0
  31. package/dist/chunks/quest-ko-BMu3uRQJ.js +863 -0
  32. package/dist/chunks/quest-ru-xne814Rw.js +863 -0
  33. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  34. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  35. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  36. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  37. package/dist/chunks/usercenter-es-Dz3Wp2vV.js +512 -0
  38. package/dist/chunks/usercenter-ja-CKE4DJC6.js +512 -0
  39. package/dist/chunks/usercenter-ko-Dtpkn2qb.js +512 -0
  40. package/dist/chunks/usercenter-ru-DnBGee45.js +512 -0
  41. package/dist/community-task.d.ts +0 -390
  42. package/dist/community-task.js +2 -7
  43. package/dist/core.d.ts +46 -10
  44. package/dist/core.js +11 -11
  45. package/dist/index.d.ts +46 -667
  46. package/dist/index.js +19 -28
  47. package/dist/leaderboard.d.ts +0 -498
  48. package/dist/leaderboard.js +2 -16
  49. package/dist/page-builder.js +1 -1
  50. package/dist/quest.d.ts +0 -289
  51. package/dist/quest.js +2 -5
  52. package/dist/user-center.d.ts +0 -1608
  53. package/dist/user-center.js +2 -494
  54. package/package.json +5 -2
  55. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +0 -119
  56. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +0 -119
  57. package/dist/chunks/usercenter-ja-B2465c1O.js +0 -326
  58. package/dist/chunks/usercenter-ko-xAEYxqLg.js +0 -326
@@ -1,11 +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
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-CPI_roeh.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-DwXlQC0S.js";
4
+ import { x as useTaskOnPortalContainer, h as useTaskOnContext } from "./ThemeProvider-mXLdLSkq.js";
5
+ import { d as useTaskWidgetLocale, b as TaskItem, e as useQuestLocale, I as I18nT, f as EligibilityList, g as getDefaultExportFromCjs, s as sanitizeHtml, R as RewardModuleDialog, h as ConfirmNoticeDialog, u as useBindWallet, a as useNftClaimFlow, E as EligibilityInfo, B as BlindBoxDialog } from "./EligibilityInfo-BV0Z2TgY.js";
6
+ import { D as Dialog, B as Button, T as Table, P as Pagination, u as useResolvedWidgetConfig, W as WidgetShell } from "./WidgetShell-D7yC894Y.js";
6
7
  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-cADBSVg7.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-D-Fuy9GE.js";
8
+ import { R as Root2, i as Trigger, j as Portal, C as Content2, r as InfoIcon, k as Arrow2, q as TipPopover, a as useBindSocialAccount } from "./UserCenterWidget-D5ttw4hO.js";
9
9
  import '../Quest.css';function ButtonTabs({
10
10
  items,
11
11
  activeKey,
@@ -143,6 +143,7 @@ function GreenCheckIcon() {
143
143
  function CompletedCount({
144
144
  current,
145
145
  total,
146
+ completedLabel = "Completed",
146
147
  className
147
148
  }) {
148
149
  const isAllCompleted = current >= total && total > 0;
@@ -153,7 +154,8 @@ function CompletedCount({
153
154
  /* @__PURE__ */ jsx("span", { className: current > 0 ? "taskon-completed-count-em" : "", children: current }),
154
155
  "/",
155
156
  total,
156
- ") Completed"
157
+ ") ",
158
+ completedLabel
157
159
  ] })
158
160
  ] });
159
161
  }
@@ -209,6 +211,8 @@ function TaskList({
209
211
  onCooldownComplete,
210
212
  className
211
213
  }) {
214
+ const { t } = useTaskWidgetLocale();
215
+ const countPlaceholder = "__COUNT__";
212
216
  const completionStatus = useCompletionStatus(
213
217
  mandatoryTasks,
214
218
  optionalTasks,
@@ -218,12 +222,13 @@ function TaskList({
218
222
  return /* @__PURE__ */ jsxs("div", { className: `taskon-task-list ${className || ""}`, children: [
219
223
  mandatoryTasks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section taskon-task-list-section--mandatory", children: [
220
224
  showLabels && /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section-header", children: [
221
- /* @__PURE__ */ jsx("div", { className: "taskon-task-list-section-label", children: /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: "Mandatory Tasks" }) }),
225
+ /* @__PURE__ */ jsx("div", { className: "taskon-task-list-section-label", children: /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: t("mandatory_tasks") }) }),
222
226
  /* @__PURE__ */ jsx(
223
227
  CompletedCount,
224
228
  {
225
229
  current: completionStatus.mandatoryCompleted,
226
- total: completionStatus.mandatoryTotal
230
+ total: completionStatus.mandatoryTotal,
231
+ completedLabel: t("completed")
227
232
  }
228
233
  )
229
234
  ] }),
@@ -251,27 +256,36 @@ function TaskList({
251
256
  optionalTasks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section taskon-task-list-section--optional", children: [
252
257
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section-header", children: [
253
258
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section-label", children: [
254
- /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: "Optional Tasks" }),
255
- minOptionalTasks !== void 0 && minOptionalTasks > 0 && /* @__PURE__ */ jsxs("span", { className: "taskon-task-list-section-hint", children: [
256
- "(Min.",
257
- " ",
258
- /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalTasks }),
259
- " ",
260
- "Required)"
261
- ] }),
262
- !minOptionalTasks && minOptionalPoints !== void 0 && minOptionalPoints > 0 && /* @__PURE__ */ jsxs("span", { className: "taskon-task-list-section-hint", children: [
263
- "(Min.",
264
- " ",
265
- /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalPoints }),
266
- " ",
267
- "Points Required)"
268
- ] })
259
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: t("optional_tasks") }),
260
+ minOptionalTasks !== void 0 && minOptionalTasks > 0 && /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint", children: (() => {
261
+ const text = t("min_required", {
262
+ count: countPlaceholder
263
+ });
264
+ const [before, after] = text.split(countPlaceholder);
265
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
266
+ before,
267
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalTasks }),
268
+ after
269
+ ] });
270
+ })() }),
271
+ !minOptionalTasks && minOptionalPoints !== void 0 && minOptionalPoints > 0 && /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint", children: (() => {
272
+ const text = t("min_points_required", {
273
+ count: countPlaceholder
274
+ });
275
+ const [before, after] = text.split(countPlaceholder);
276
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
277
+ before,
278
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalPoints }),
279
+ after
280
+ ] });
281
+ })() })
269
282
  ] }),
270
283
  /* @__PURE__ */ jsx(
271
284
  CompletedCount,
272
285
  {
273
286
  current: completionStatus.optionalCompleted,
274
- total: completionStatus.optionalTotal
287
+ total: completionStatus.optionalTotal,
288
+ completedLabel: t("completed")
275
289
  }
276
290
  )
277
291
  ] }),
@@ -296,7 +310,7 @@ function TaskList({
296
310
  task.id
297
311
  )) })
298
312
  ] }),
299
- mandatoryTasks.length === 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-task-list-empty", children: /* @__PURE__ */ jsx("p", { children: "No tasks available" }) })
313
+ mandatoryTasks.length === 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-task-list-empty", children: /* @__PURE__ */ jsx("p", { children: t("no_tasks_available") }) })
300
314
  ] });
301
315
  }
302
316
  function formatAmount(amount) {
@@ -327,12 +341,13 @@ function RewardCard$2({
327
341
  reward,
328
342
  tokenPrice
329
343
  }) {
344
+ const { t } = useQuestLocale();
330
345
  if (reward.reward_type !== RewardType.Token) {
331
346
  return null;
332
347
  }
333
348
  const tokenValue = reward.reward_value;
334
349
  const amount = tokenValue.amount || "0";
335
- const tokenName = tokenValue.token_name || "Token";
350
+ const tokenName = tokenValue.token_name || t("token_name");
336
351
  const tokenLogo = tokenValue.token_logo;
337
352
  const usdValue = formatUsdValue(amount, tokenPrice);
338
353
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-blindbox-reward-card", children: [
@@ -354,10 +369,11 @@ function RewardCard$2({
354
369
  ] });
355
370
  }
356
371
  function BlindBoxRewardDialog(props) {
372
+ const { t } = useQuestLocale();
357
373
  const { rewards, emptyReward, tokenPrice, loading, onClose } = props;
358
374
  const hasRewards = rewards.length > 0;
359
- const title = hasRewards ? "Congratulations!" : "Oops! Better Luck Next Time!";
360
- const subtitle = hasRewards ? "You Have Won" : "Rewards Missed";
375
+ const title = hasRewards ? t("congratulations") : t("oops_better_luck_next_time");
376
+ const subtitle = hasRewards ? t("won") : t("rewards_missed");
361
377
  const displayRewards = useMemo(() => {
362
378
  if (hasRewards) {
363
379
  return rewards;
@@ -381,7 +397,7 @@ function BlindBoxRewardDialog(props) {
381
397
  className: "taskon-quest-blindbox-reward-btn",
382
398
  disabled: loading,
383
399
  onClick: onClose,
384
- children: loading ? "Loading..." : "Back"
400
+ children: loading ? t("loading") : t("close")
385
401
  }
386
402
  ) })
387
403
  ] });
@@ -463,6 +479,7 @@ function EligsNotPassDialog({
463
479
  onRefresh,
464
480
  isRefreshing = false
465
481
  }) {
482
+ const { t } = useQuestLocale();
466
483
  const [isExpanded, setIsExpanded] = useState(true);
467
484
  const [currentDetails, setCurrentDetails] = useState(details);
468
485
  const isEligible = useMemo(() => {
@@ -479,7 +496,7 @@ function EligsNotPassDialog({
479
496
  const eligibleDetails = useMemo(() => {
480
497
  return currentDetails.map((d) => d.is_pass);
481
498
  }, [currentDetails]);
482
- const expressLabel = eligibilityExpress === "and" ? "all" : "any";
499
+ const expressLabel = eligibilityExpress === "and" ? t("all") : t("any");
483
500
  const handleRefresh = async () => {
484
501
  if (onRefresh) {
485
502
  await onRefresh();
@@ -493,7 +510,7 @@ function EligsNotPassDialog({
493
510
  {
494
511
  open,
495
512
  onOpenChange: (isOpen) => !isOpen && onClose(),
496
- title: isEligible ? "Congratulations" : "Oops",
513
+ title: isEligible ? t("congratulations") : t("oops"),
497
514
  showCloseButton: true,
498
515
  maxWidth: 400,
499
516
  contentClassName: "taskon-eligs-dialog",
@@ -507,17 +524,22 @@ function EligsNotPassDialog({
507
524
  className: "taskon-eligs-dialog-icon"
508
525
  }
509
526
  ),
510
- /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-dialog-title", children: isEligible ? "Congratulations" : "Oops" })
527
+ /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-dialog-title", children: isEligible ? t("congratulations") : t("oops") })
511
528
  ] }),
512
529
  /* @__PURE__ */ jsx(
513
530
  "p",
514
531
  {
515
532
  className: `taskon-eligs-dialog-desc ${isEligible ? "taskon-eligs-dialog-desc--success" : ""}`,
516
- children: isEligible ? "Awesome! You already meet the requirements." : /* @__PURE__ */ jsxs(Fragment, { children: [
517
- "Before you join please meet ",
518
- /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-highlight", children: expressLabel }),
519
- " the following Eligibilities"
520
- ] })
533
+ children: isEligible ? t("awesome_already_meet_requirements") : /* @__PURE__ */ jsx(
534
+ I18nT,
535
+ {
536
+ t,
537
+ i18nKey: "before_join_please_meet_express_following_eligibilities",
538
+ components: {
539
+ express: /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-highlight", children: expressLabel })
540
+ }
541
+ }
542
+ )
521
543
  }
522
544
  ),
523
545
  /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-dialog-eligs", children: [
@@ -536,7 +558,7 @@ function EligsNotPassDialog({
536
558
  className: "taskon-eligs-dialog-eligs-icon"
537
559
  }
538
560
  ),
539
- /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-eligs-label", children: "Meet Eligibilities Below" }),
561
+ /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-eligs-label", children: t("meet_eligibilities_below") }),
540
562
  /* @__PURE__ */ jsx(ArrowIcon$1, { expanded: isExpanded })
541
563
  ]
542
564
  }
@@ -563,8 +585,8 @@ function EligsNotPassDialog({
563
585
  disabled: isRefreshing,
564
586
  children: isRefreshing ? /* @__PURE__ */ jsxs("span", { className: "taskon-eligs-dialog-loading", children: [
565
587
  /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-spinner" }),
566
- "Refreshing..."
567
- ] }) : isEligible || !onRefresh ? "OK" : "Refresh"
588
+ t("refreshing")
589
+ ] }) : isEligible || !onRefresh ? t("ok") : t("refresh")
568
590
  }
569
591
  )
570
592
  ] })
@@ -572,7 +594,7 @@ function EligsNotPassDialog({
572
594
  );
573
595
  }
574
596
  const CHAIN_TYPE_LABELS$1 = {
575
- evm: "EVM Chain",
597
+ evm: "evm_chain",
576
598
  btc: "Bitcoin",
577
599
  starknet: "Starknet",
578
600
  solana: "Solana",
@@ -584,12 +606,15 @@ const CHAIN_TYPE_LABELS$1 = {
584
606
  ton: "TON"
585
607
  };
586
608
  const SNS_TYPE_LABELS = {
587
- twitter: "X (Twitter)",
588
- discord: "Discord",
609
+ twitter: "x_twitter",
610
+ discord: "discord",
589
611
  telegram: "Telegram"
590
612
  };
591
613
  function BindItem$1({ type, bindType, isBinding, isBound, onBind }) {
592
- const label = type === "chain" ? CHAIN_TYPE_LABELS$1[bindType.toLowerCase()] || bindType : SNS_TYPE_LABELS[bindType.toLowerCase()] || bindType;
614
+ const { t } = useQuestLocale();
615
+ const chainLabelKey = CHAIN_TYPE_LABELS$1[bindType.toLowerCase()];
616
+ const snsLabelKey = SNS_TYPE_LABELS[bindType.toLowerCase()];
617
+ const label = type === "chain" ? chainLabelKey ? t(chainLabelKey) : bindType : snsLabelKey ? t(snsLabelKey) : bindType;
593
618
  return /* @__PURE__ */ jsxs("div", { className: `taskon-eligs-bind-item ${isBound ? "taskon-eligs-bind-item--bound" : ""}`, children: [
594
619
  /* @__PURE__ */ jsx("span", { className: "taskon-eligs-bind-item-label", children: label }),
595
620
  isBound ? /* @__PURE__ */ jsxs("span", { className: "taskon-eligs-bind-item-status", children: [
@@ -603,7 +628,7 @@ function BindItem$1({ type, bindType, isBinding, isBound, onBind }) {
603
628
  strokeLinejoin: "round"
604
629
  }
605
630
  ) }),
606
- "Bound"
631
+ t("bound")
607
632
  ] }) : /* @__PURE__ */ jsx(
608
633
  "button",
609
634
  {
@@ -612,8 +637,8 @@ function BindItem$1({ type, bindType, isBinding, isBound, onBind }) {
612
637
  disabled: isBinding,
613
638
  children: isBinding ? /* @__PURE__ */ jsxs(Fragment, { children: [
614
639
  /* @__PURE__ */ jsx("svg", { className: "taskon-eligs-bind-item-spinner", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeDasharray: "31.4 31.4" }) }),
615
- "Binding..."
616
- ] }) : "Bind"
640
+ t("binding")
641
+ ] }) : t("bind")
617
642
  }
618
643
  )
619
644
  ] });
@@ -628,6 +653,7 @@ function EligsBindDialog({
628
653
  onBindChain,
629
654
  onBindSns
630
655
  }) {
656
+ const { t } = useQuestLocale();
631
657
  const [notBoundChains, setNotBoundChains] = useState(chainTypes);
632
658
  const [notBoundSns, setNotBoundSns] = useState(snsTypes);
633
659
  const [bindingType, setBindingType] = useState(null);
@@ -650,7 +676,7 @@ function EligsBindDialog({
650
676
  try {
651
677
  const success = await onBindChain(chainType);
652
678
  if (success) {
653
- setNotBoundChains((prev) => prev.filter((t) => t !== chainType));
679
+ setNotBoundChains((prev) => prev.filter((t2) => t2 !== chainType));
654
680
  }
655
681
  } finally {
656
682
  setBindingType(null);
@@ -661,7 +687,7 @@ function EligsBindDialog({
661
687
  try {
662
688
  const success = await onBindSns(snsType);
663
689
  if (success) {
664
- setNotBoundSns((prev) => prev.filter((t) => t !== snsType));
690
+ setNotBoundSns((prev) => prev.filter((t2) => t2 !== snsType));
665
691
  }
666
692
  } finally {
667
693
  setBindingType(null);
@@ -679,12 +705,12 @@ function EligsBindDialog({
679
705
  handleClose();
680
706
  }
681
707
  },
682
- title: "Bind Required Accounts",
708
+ title: t("bind_required_accounts"),
683
709
  showCloseButton: true,
684
710
  maxWidth: 560,
685
711
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-dialog", children: [
686
712
  campaign.eligs && campaign.eligs.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-eligs-section", children: [
687
- /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-bind-section-title", children: "Quest Eligibility" }),
713
+ /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-bind-section-title", children: t("quest_eligibility") }),
688
714
  /* @__PURE__ */ jsx(
689
715
  EligibilityList,
690
716
  {
@@ -698,9 +724,9 @@ function EligsBindDialog({
698
724
  }
699
725
  )
700
726
  ] }),
701
- /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: "Please bind the following accounts to verify eligibility." }),
727
+ /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: t("please_bind_following_accounts_verify_eligibility") }),
702
728
  chainTypes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-section", children: [
703
- /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: "Wallet Address" }),
729
+ /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: t("wallet_address") }),
704
730
  /* @__PURE__ */ jsx("div", { className: "taskon-eligs-bind-list", children: chainTypes.map((chainType) => /* @__PURE__ */ jsx(
705
731
  BindItem$1,
706
732
  {
@@ -714,7 +740,7 @@ function EligsBindDialog({
714
740
  )) })
715
741
  ] }),
716
742
  snsTypes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-section", children: [
717
- /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: "Social Accounts" }),
743
+ /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: t("social_accounts") }),
718
744
  /* @__PURE__ */ jsx("div", { className: "taskon-eligs-bind-list", children: snsTypes.map((snsType) => /* @__PURE__ */ jsx(
719
745
  BindItem$1,
720
746
  {
@@ -732,6 +758,7 @@ function EligsBindDialog({
732
758
  );
733
759
  }
734
760
  function useQuestDetail(options) {
761
+ const { t } = useQuestLocale();
735
762
  const {
736
763
  api,
737
764
  campaignId,
@@ -761,14 +788,14 @@ function useQuestDetail(options) {
761
788
  const result = await api.getCampaignInfo(params);
762
789
  setData(result);
763
790
  } catch (err) {
764
- const errorMessage = err instanceof Error ? err.message : "Failed to load quest detail";
791
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_quest_detail");
765
792
  setError(errorMessage);
766
793
  setData(null);
767
794
  console.error("[useQuestDetail] Error:", err);
768
795
  } finally {
769
796
  setIsLoading(false);
770
797
  }
771
- }, [enabled, api, campaignId, channel, kolHandle, inviteCode, boostId]);
798
+ }, [enabled, api, campaignId, channel, kolHandle, inviteCode, boostId, t]);
772
799
  useEffect(() => {
773
800
  fetchDetail();
774
801
  }, [fetchDetail]);
@@ -780,7 +807,15 @@ function useQuestDetail(options) {
780
807
  };
781
808
  }
782
809
  function useQuestUserStatus(options) {
783
- const { api, campaignId, channel, kolHandle, enabled = true } = options;
810
+ const { t } = useQuestLocale();
811
+ const {
812
+ api,
813
+ campaignId,
814
+ channel,
815
+ kolHandle,
816
+ enabled = true,
817
+ authToken
818
+ } = options;
784
819
  const [data, setData] = useState(null);
785
820
  const [isLoading, setIsLoading] = useState(false);
786
821
  const [error, setError] = useState(null);
@@ -799,14 +834,14 @@ function useQuestUserStatus(options) {
799
834
  const result = await api.getUserCampaignStatus(params);
800
835
  setData(result);
801
836
  } catch (err) {
802
- const errorMessage = err instanceof Error ? err.message : "Failed to load user status";
837
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_user_status");
803
838
  setError(errorMessage);
804
839
  setData(null);
805
840
  console.error("[useQuestUserStatus] Error:", err);
806
841
  } finally {
807
842
  setIsLoading(false);
808
843
  }
809
- }, [enabled, api, campaignId, channel, kolHandle]);
844
+ }, [enabled, api, campaignId, channel, kolHandle, authToken, t]);
810
845
  const updateTaskStatus = useCallback(
811
846
  (taskId, isAsync = false) => {
812
847
  setData((prev) => {
@@ -845,6 +880,7 @@ function useQuestUserStatus(options) {
845
880
  };
846
881
  }
847
882
  function useQuestStatus(options) {
883
+ const { t } = useQuestLocale();
848
884
  const { api, campaignId, channel, kolHandle, enabled = true } = options;
849
885
  const [data, setData] = useState(null);
850
886
  const [isLoading, setIsLoading] = useState(false);
@@ -864,14 +900,14 @@ function useQuestStatus(options) {
864
900
  const result = await api.getCampaignStatusInfo(params);
865
901
  setData(result);
866
902
  } catch (err) {
867
- const errorMessage = err instanceof Error ? err.message : "Failed to load quest status";
903
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_quest_status");
868
904
  setError(errorMessage);
869
905
  setData(null);
870
906
  console.error("[useQuestStatus] Error:", err);
871
907
  } finally {
872
908
  setIsLoading(false);
873
909
  }
874
- }, [enabled, api, campaignId, channel, kolHandle]);
910
+ }, [enabled, api, campaignId, channel, kolHandle, t]);
875
911
  useEffect(() => {
876
912
  fetchStatus();
877
913
  }, [fetchStatus]);
@@ -1229,7 +1265,7 @@ function getNeedBindChainTypeList(requiredChainTypes, userProfile) {
1229
1265
  (chainType) => requiredChainTypes.includes(chainType) && !boundChainTypes.includes(chainType)
1230
1266
  );
1231
1267
  }
1232
- function validateTaskCompletion(campaign, userStatus) {
1268
+ function validateTaskCompletion(campaign, userStatus, t) {
1233
1269
  const { tasks, min_finished_optional_task_num, min_finished_optional_task_points } = campaign;
1234
1270
  const { task_status_details } = userStatus;
1235
1271
  const notCompletedMandatory = tasks.find(
@@ -1241,7 +1277,7 @@ function validateTaskCompletion(campaign, userStatus) {
1241
1277
  if (notCompletedMandatory) {
1242
1278
  return {
1243
1279
  type: "mandatory",
1244
- message: "Please complete all mandatory tasks"
1280
+ message: t("please_complete_mandatory_tasks")
1245
1281
  };
1246
1282
  }
1247
1283
  if (min_finished_optional_task_num && min_finished_optional_task_num > 0) {
@@ -1255,7 +1291,7 @@ function validateTaskCompletion(campaign, userStatus) {
1255
1291
  if (completedCount < min_finished_optional_task_num) {
1256
1292
  return {
1257
1293
  type: "optional_count",
1258
- message: "Please complete more optional tasks",
1294
+ message: t("please_complete_optional_tasks"),
1259
1295
  required: min_finished_optional_task_num,
1260
1296
  current: completedCount
1261
1297
  };
@@ -1272,7 +1308,12 @@ function validateTaskCompletion(campaign, userStatus) {
1272
1308
  if (totalPoints < min_finished_optional_task_points) {
1273
1309
  return {
1274
1310
  type: "optional_points",
1275
- message: `Please earn at least ${min_finished_optional_task_points} points from optional tasks`,
1311
+ message: t(
1312
+ "please_earn_least_count_points_optional_tasks",
1313
+ {
1314
+ count: min_finished_optional_task_points
1315
+ }
1316
+ ),
1276
1317
  required: min_finished_optional_task_points,
1277
1318
  current: totalPoints
1278
1319
  };
@@ -1317,6 +1358,7 @@ function isDiscordBound(userProfile) {
1317
1358
  return (userProfile == null ? void 0 : userProfile.sns.some((item) => item.sns_type === SnsType.Discord)) || false;
1318
1359
  }
1319
1360
  function useCompleteValidation(options) {
1361
+ const { t } = useQuestLocale();
1320
1362
  const {
1321
1363
  api,
1322
1364
  campaign,
@@ -1407,7 +1449,11 @@ function useCompleteValidation(options) {
1407
1449
  onLogin == null ? void 0 : onLogin();
1408
1450
  return false;
1409
1451
  }
1410
- const taskError = validateTaskCompletion(campaign, userStatus);
1452
+ const taskError = validateTaskCompletion(
1453
+ campaign,
1454
+ userStatus,
1455
+ t
1456
+ );
1411
1457
  if (taskError) {
1412
1458
  setTaskValidationError(taskError);
1413
1459
  return false;
@@ -1493,7 +1539,8 @@ function useCompleteValidation(options) {
1493
1539
  userProfile,
1494
1540
  isLoggedIn,
1495
1541
  onLogin,
1496
- onEligibilityFailed
1542
+ onEligibilityFailed,
1543
+ t
1497
1544
  ]);
1498
1545
  return {
1499
1546
  validateBeforeComplete,
@@ -1571,16 +1618,17 @@ function formatLongNumber$1(input, symbol = true) {
1571
1618
  }
1572
1619
  return String(Math.round(num * 100) / 100);
1573
1620
  }
1574
- function getRewardSymbol(info) {
1621
+ function getRewardSymbol(info, t) {
1575
1622
  var _a;
1623
+ const translate = t ?? ((key) => key);
1576
1624
  if (info.reward_type === RewardType.Points) {
1577
- return "Points";
1625
+ return translate("points");
1578
1626
  }
1579
1627
  if (info.reward_type === RewardType.GTCPoints) {
1580
- return ((_a = info.points_info) == null ? void 0 : _a.points_name) || "Points";
1628
+ return ((_a = info.points_info) == null ? void 0 : _a.points_name) || translate("points");
1581
1629
  }
1582
1630
  if (info.reward_type === RewardType.Whitelist) {
1583
- return "WL";
1631
+ return translate("whitelist");
1584
1632
  }
1585
1633
  if (info.reward_type === RewardType.Token) {
1586
1634
  return info.reward_symbol || "";
@@ -1595,23 +1643,26 @@ function getRewardSymbol(info) {
1595
1643
  return "EXP";
1596
1644
  }
1597
1645
  if (info.reward_type === RewardType.DiscordRole) {
1598
- return "Discord Role";
1646
+ return translate("discord_role");
1599
1647
  }
1600
1648
  return "";
1601
1649
  }
1602
- function formatRewardLabel(info) {
1650
+ function formatRewardLabel(info, t) {
1651
+ const translate = t ?? ((key) => key);
1603
1652
  if (info.reward_type === RewardType.Points || info.reward_type === RewardType.GTCPoints) {
1604
1653
  const amount = info.reward_amount ? formatLongNumber$1(info.reward_amount) : "?";
1605
- return `${amount} ${getRewardSymbol(info)}`;
1654
+ return `${amount} ${getRewardSymbol(info, translate)}`;
1606
1655
  }
1607
1656
  if (info.reward_type === RewardType.Token) {
1608
1657
  if (info.is_usdt_equal) {
1609
- return `$${info.reward_amount || ""} USD in ${info.reward_symbol}`;
1658
+ return `${info.reward_amount || ""} ${translate("usd_token_name", {
1659
+ token_name: info.reward_symbol || ""
1660
+ })}`.trim();
1610
1661
  }
1611
1662
  const amount = info.reward_amount ? formatLongNumber$1(info.reward_amount) : "?";
1612
- return `${amount} ${getRewardSymbol(info)}`;
1663
+ return `${amount} ${getRewardSymbol(info, translate)}`;
1613
1664
  }
1614
- return getRewardSymbol(info);
1665
+ return getRewardSymbol(info, translate);
1615
1666
  }
1616
1667
  function addUrlParam(url, key, value) {
1617
1668
  try {
@@ -1623,7 +1674,7 @@ function addUrlParam(url, key, value) {
1623
1674
  }
1624
1675
  }
1625
1676
  function getDefaultShareText(campaignName) {
1626
- return `Join the ${campaignName || "Quest"} with me 🙌`;
1677
+ return `Join the ${campaignName || "quest"} with me 🙌`;
1627
1678
  }
1628
1679
  function buildFinalShareText(shareUrl, shareText, shareAutoAppendLink, campaignName) {
1629
1680
  const baseText = shareText || getDefaultShareText(campaignName);
@@ -3848,6 +3899,7 @@ function QrCodeDialog({
3848
3899
  endTime,
3849
3900
  winnerRewardsSimple
3850
3901
  }) {
3902
+ const { t } = useQuestLocale();
3851
3903
  const [qrCodeUrl, setQrCodeUrl] = useState("");
3852
3904
  const posterRef = useRef(null);
3853
3905
  useEffect(() => {
@@ -3880,7 +3932,7 @@ function QrCodeDialog({
3880
3932
  link.href = dataUrl;
3881
3933
  link.click();
3882
3934
  } catch (error) {
3883
- console.error("Failed to download poster:", error);
3935
+ console.error("failed_download_poster", error);
3884
3936
  }
3885
3937
  };
3886
3938
  return /* @__PURE__ */ jsx(
@@ -3890,7 +3942,7 @@ function QrCodeDialog({
3890
3942
  onOpenChange: (isOpen) => !isOpen && onClose(),
3891
3943
  showCloseButton: true,
3892
3944
  contentClassName: "taskon-quest-qr-dialog-content",
3893
- title: "Share QR Code",
3945
+ title: t("share_qr_code"),
3894
3946
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-dialog", children: [
3895
3947
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-poster-outer", children: /* @__PURE__ */ jsxs("div", { ref: posterRef, className: "taskon-quest-qr-poster", children: [
3896
3948
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-poster-header", children: [
@@ -3920,13 +3972,16 @@ function QrCodeDialog({
3920
3972
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-poster-footer", children: [
3921
3973
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-info", children: [
3922
3974
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-reward-title", children: [
3923
- "Reward",
3975
+ t("reward"),
3924
3976
  /* @__PURE__ */ jsx(ArrowRightIcon, {})
3925
3977
  ] }),
3926
3978
  winnerRewardsSimple && winnerRewardsSimple.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-rewards-list", children: [
3927
3979
  "🎁",
3928
3980
  winnerRewardsSimple.map((reward, index) => /* @__PURE__ */ jsxs("span", { className: "taskon-quest-qr-reward-item", children: [
3929
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-qr-reward-label", children: formatRewardLabel(reward) }),
3981
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-qr-reward-label", children: formatRewardLabel(
3982
+ reward,
3983
+ t
3984
+ ) }),
3930
3985
  reward.chain_icon && /* @__PURE__ */ jsx(
3931
3986
  "img",
3932
3987
  {
@@ -3944,12 +3999,12 @@ function QrCodeDialog({
3944
3999
  /* @__PURE__ */ jsx("span", { children: timeRangeText })
3945
4000
  ] })
3946
4001
  ] }),
3947
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-code", children: qrCodeUrl && /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: "QR Code" }) })
4002
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-code", children: qrCodeUrl && /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: t("qr_code") }) })
3948
4003
  ] })
3949
4004
  ] }) }),
3950
4005
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-actions", children: [
3951
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: "Cancel" }),
3952
- /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleDownload, children: "Save" })
4006
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: t("close") }),
4007
+ /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleDownload, children: t("save") })
3953
4008
  ] })
3954
4009
  ] })
3955
4010
  }
@@ -4071,20 +4126,29 @@ function ShareDropdown({
4071
4126
  endTime,
4072
4127
  winnerRewardsSimple
4073
4128
  }) {
4129
+ const { t } = useQuestLocale();
4074
4130
  const portalContainer = useTaskOnPortalContainer();
4075
4131
  const { toast } = useToast();
4076
4132
  const [qrDialogOpen, setQrDialogOpen] = useState(false);
4077
4133
  const [popoverOpen, setPopoverOpen] = useState(false);
4078
4134
  const resolvedUrl = shareUrl || window.location.href;
4079
4135
  const handleShareTwitter = () => {
4080
- const text = buildFinalShareText(resolvedUrl, shareText, shareAutoAppendLink, campaignName);
4136
+ const resolvedShareText = shareText || t("join_campaignname_me", {
4137
+ campaignName: campaignName || t("quest")
4138
+ });
4139
+ const text = buildFinalShareText(
4140
+ resolvedUrl,
4141
+ resolvedShareText,
4142
+ shareAutoAppendLink,
4143
+ campaignName
4144
+ );
4081
4145
  shareToTwitter(text);
4082
4146
  setPopoverOpen(false);
4083
4147
  };
4084
4148
  const handleCopyLink = async () => {
4085
4149
  const success = await copyToClipboard$3(resolvedUrl);
4086
4150
  if (success) {
4087
- toast.success("Link copied!");
4151
+ toast.success(t("link_copied"));
4088
4152
  }
4089
4153
  setPopoverOpen(false);
4090
4154
  };
@@ -4094,7 +4158,7 @@ function ShareDropdown({
4094
4158
  };
4095
4159
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4096
4160
  /* @__PURE__ */ jsxs(Root2, { open: popoverOpen, onOpenChange: setPopoverOpen, children: [
4097
- /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "taskon-quest-share-trigger", "aria-label": "Share", children: /* @__PURE__ */ jsx(ShareIcon, {}) }) }),
4161
+ /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "taskon-quest-share-trigger", "aria-label": t("share"), children: /* @__PURE__ */ jsx(ShareIcon, {}) }) }),
4098
4162
  /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(Content2, { className: "taskon-quest-share-menu", sideOffset: 8, children: [
4099
4163
  /* @__PURE__ */ jsxs(
4100
4164
  "button",
@@ -4103,7 +4167,7 @@ function ShareDropdown({
4103
4167
  onClick: handleShareTwitter,
4104
4168
  children: [
4105
4169
  /* @__PURE__ */ jsx(TwitterIcon, {}),
4106
- /* @__PURE__ */ jsx("span", { children: "Twitter" })
4170
+ /* @__PURE__ */ jsx("span", { children: t("twitter") })
4107
4171
  ]
4108
4172
  }
4109
4173
  ),
@@ -4114,7 +4178,7 @@ function ShareDropdown({
4114
4178
  onClick: handleCopyLink,
4115
4179
  children: [
4116
4180
  /* @__PURE__ */ jsx(CopyLinkIcon, {}),
4117
- /* @__PURE__ */ jsx("span", { children: "Copy Link" })
4181
+ /* @__PURE__ */ jsx("span", { children: t("copy_link") })
4118
4182
  ]
4119
4183
  }
4120
4184
  ),
@@ -4125,7 +4189,7 @@ function ShareDropdown({
4125
4189
  onClick: handleShowQrCode,
4126
4190
  children: [
4127
4191
  /* @__PURE__ */ jsx(QrCodeIcon, {}),
4128
- /* @__PURE__ */ jsx("span", { children: "QR Code" })
4192
+ /* @__PURE__ */ jsx("span", { children: t("qr_code") })
4129
4193
  ]
4130
4194
  }
4131
4195
  )
@@ -4188,6 +4252,7 @@ function QuestTitle({
4188
4252
  communityAvatar,
4189
4253
  winnerRewardsSimple
4190
4254
  }) {
4255
+ const { t } = useQuestLocale();
4191
4256
  const countdownTarget = !isStarted ? startTime : isActive ? endTime : void 0;
4192
4257
  const countdown = useCountdown(countdownTarget);
4193
4258
  const startDate = new Date(startTime);
@@ -4202,7 +4267,7 @@ function QuestTitle({
4202
4267
  };
4203
4268
  const offset = -startDate.getTimezoneOffset() / 60;
4204
4269
  const offsetString = offset >= 0 ? `+${offset}` : String(offset);
4205
- const countdownLabel = isEnded ? "ENDED" : !isStarted ? "Starts In" : "Ends In";
4270
+ const countdownLabel = isEnded ? t("ended") : !isStarted ? t("starts") : t("ends");
4206
4271
  const hasValidCountdown = !isEnded && countdown && countdown.totalSeconds > 0;
4207
4272
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-header-title-section", children: [
4208
4273
  show && /* @__PURE__ */ jsx("h1", { className: "taskon-quest-title", children: title }),
@@ -4253,6 +4318,7 @@ function QuestDescription({
4253
4318
  description,
4254
4319
  show = true
4255
4320
  }) {
4321
+ const { t } = useQuestLocale();
4256
4322
  const [isExpanded, setIsExpanded] = useState(false);
4257
4323
  const sanitizedHtml = useMemo(() => {
4258
4324
  if (!description) return "";
@@ -4274,7 +4340,7 @@ function QuestDescription({
4274
4340
  {
4275
4341
  className: "taskon-quest-desc-more",
4276
4342
  onClick: () => setIsExpanded(!isExpanded),
4277
- children: isExpanded ? "Show less" : "Read more"
4343
+ children: isExpanded ? t("show_less") : t("read")
4278
4344
  }
4279
4345
  )
4280
4346
  ] });
@@ -4365,6 +4431,7 @@ function ParticipantsInfo({
4365
4431
  participantCount,
4366
4432
  className
4367
4433
  }) {
4434
+ const { t } = useQuestLocale();
4368
4435
  const [isDialogOpen, setIsDialogOpen] = useState(false);
4369
4436
  if (participantCount === 0) {
4370
4437
  return null;
@@ -4377,15 +4444,15 @@ function ParticipantsInfo({
4377
4444
  type: "button",
4378
4445
  className: "taskon-quest-participants-info-header",
4379
4446
  onClick: () => setIsDialogOpen(true),
4380
- "aria-label": "View participants info details",
4447
+ "aria-label": t("view_participants_info_details"),
4381
4448
  children: [
4382
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-participants-info-title", children: "Participants Info" }),
4449
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-participants-info-title", children: t("participants_info") }),
4383
4450
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-icon", children: /* @__PURE__ */ jsx(InfoIcon, {}) })
4384
4451
  ]
4385
4452
  }
4386
4453
  ),
4387
4454
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-info-row", children: [
4388
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-label", children: "Participants" }),
4455
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-label", children: t("participants_2") }),
4389
4456
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-value", children: formattedParticipantCount })
4390
4457
  ] }),
4391
4458
  /* @__PURE__ */ jsx(
@@ -4393,36 +4460,48 @@ function ParticipantsInfo({
4393
4460
  {
4394
4461
  open: isDialogOpen,
4395
4462
  onOpenChange: setIsDialogOpen,
4396
- title: "Participants",
4463
+ title: t("participants_2"),
4397
4464
  maxWidth: 480,
4398
4465
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog", children: [
4399
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-participants-dialog-title", children: "Participants" }),
4466
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-participants-dialog-title", children: t("participants_2") }),
4400
4467
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-section", children: [
4401
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: "What is Participants?" }),
4402
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: "Participants: any user who complete at least 1 task of this quest." })
4468
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: t("what_participants") }),
4469
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: t("participants_any_user_who_complete_least_1_task_quest") })
4403
4470
  ] }),
4404
4471
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-section", children: [
4405
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: "How is winner be selected?" }),
4406
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: "Winner is generated from the following chart." })
4472
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: t("how_winner_selected") }),
4473
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: t("winner_generated_following_chart") })
4407
4474
  ] }),
4408
4475
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-chart", children: [
4409
4476
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-arrow-wrap", children: /* @__PURE__ */ jsx(ArrowDownIcon, {}) }),
4410
4477
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-cards", children: [
4411
4478
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level1", children: [
4412
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Participants" }),
4413
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-desc", children: "*Who completes at least 1 task." })
4479
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("participants_2") }),
4480
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4481
+ "*",
4482
+ t("who_completes_least_1_task")
4483
+ ] })
4414
4484
  ] }),
4415
4485
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level2", children: [
4416
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Submitters" }),
4417
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-desc", children: "*Who completes the quest." })
4486
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("submitters") }),
4487
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4488
+ "*",
4489
+ t("who_completes_quest")
4490
+ ] })
4418
4491
  ] }),
4419
4492
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level3", children: [
4420
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Qualifiers" }),
4421
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-desc", children: "*All the tasks of this quest is verified as valid, some tasks may verified by quest creator not by TaskOn." })
4493
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("qualifiers") }),
4494
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4495
+ "*",
4496
+ t("tasks_quest_verified_valid_some_tasks_may_verified_quest")
4497
+ ] })
4422
4498
  ] }),
4423
4499
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level4", children: [
4424
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "👑 Winners" }),
4425
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-desc", children: "*Only Qualifier can be selected as winner, the select method depends on the settings such as FCFS." })
4500
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("winners_2") }),
4501
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4502
+ "*",
4503
+ t("qualifier_selected_winner_select_method_depends_settings_fcfs")
4504
+ ] })
4426
4505
  ] })
4427
4506
  ] })
4428
4507
  ] }),
@@ -4433,7 +4512,7 @@ function ParticipantsInfo({
4433
4512
  size: "large",
4434
4513
  className: "taskon-quest-participants-dialog-btn",
4435
4514
  onClick: () => setIsDialogOpen(false),
4436
- children: "Confirm"
4515
+ children: t("confirm")
4437
4516
  }
4438
4517
  )
4439
4518
  ] })
@@ -4441,14 +4520,14 @@ function ParticipantsInfo({
4441
4520
  )
4442
4521
  ] });
4443
4522
  }
4444
- function getRewardTypeLabel$1(rewardType, pointName) {
4523
+ function getRewardTypeLabel$1(rewardType, pointName, t) {
4445
4524
  if ([RewardType.BMintedNft, RewardType.Cap, RewardType.Nft].includes(
4446
4525
  rewardType
4447
4526
  )) {
4448
4527
  return "NFT:";
4449
4528
  }
4450
4529
  if (rewardType === String(RewardType.DiscordRole)) {
4451
- return "Discord Role:";
4530
+ return `${t("discord_role")}:`;
4452
4531
  }
4453
4532
  if (rewardType === String(RewardType.Exp)) {
4454
4533
  return "EXP:";
@@ -4460,14 +4539,14 @@ function getRewardTypeLabel$1(rewardType, pointName) {
4460
4539
  return `${pointName}:`;
4461
4540
  }
4462
4541
  if (rewardType === String(RewardType.Token)) {
4463
- return "Token:";
4542
+ return `${t("token_name")}:`;
4464
4543
  }
4465
4544
  if (rewardType === String(RewardType.Whitelist)) {
4466
- return "Whitelist";
4545
+ return t("whitelist");
4467
4546
  }
4468
4547
  return String(rewardType);
4469
4548
  }
4470
- function getRewardLabel$1(data) {
4549
+ function getRewardLabel$1(data, t) {
4471
4550
  const { reward_type, reward_symbol, amount, chain_label, is_usdt_equal } = data;
4472
4551
  if ([
4473
4552
  RewardType.BMintedNft,
@@ -4485,7 +4564,9 @@ function getRewardLabel$1(data) {
4485
4564
  }
4486
4565
  if (reward_type === String(RewardType.Token)) {
4487
4566
  if (is_usdt_equal) {
4488
- return `$${amount || ""} in ${reward_symbol}`;
4567
+ return `${amount || ""} ${t("usd_token_name", {
4568
+ token_name: reward_symbol || ""
4569
+ })}`.trim();
4489
4570
  }
4490
4571
  return `${amount || ""} ${reward_symbol} ${chain_label || ""}`.trim();
4491
4572
  }
@@ -4496,13 +4577,21 @@ function getRewardLabel$1(data) {
4496
4577
  }
4497
4578
  function WinnerRewardLabel({
4498
4579
  data,
4499
- pointName = "Points"
4580
+ pointName
4500
4581
  }) {
4582
+ const { t } = useQuestLocale();
4583
+ const resolvedPointName = pointName || t("points");
4501
4584
  const typeLabel = useMemo(
4502
- () => getRewardTypeLabel$1(data.reward_type, pointName),
4503
- [data.reward_type, pointName]
4585
+ () => getRewardTypeLabel$1(data.reward_type, resolvedPointName, t),
4586
+ [data.reward_type, resolvedPointName, t]
4587
+ );
4588
+ const valueLabel = useMemo(
4589
+ () => getRewardLabel$1(
4590
+ data,
4591
+ t
4592
+ ),
4593
+ [data, t]
4504
4594
  );
4505
- const valueLabel = useMemo(() => getRewardLabel$1(data), [data]);
4506
4595
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-reward-label", children: [
4507
4596
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-type", children: typeLabel }),
4508
4597
  valueLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-value", children: valueLabel })
@@ -4528,32 +4617,32 @@ function getHowToSelectWinner$1(group) {
4528
4617
  }
4529
4618
  function getWinnerSelectionLabel$1(howToSelect) {
4530
4619
  const labels = {
4531
- FCFS: "FCFS",
4532
- LuckyDraw: "Lucky Draw",
4533
- PointRanking: "Ranking",
4534
- ManualUpload: "Manually Upload",
4535
- OpenToAll: "Open to All"
4620
+ FCFS: "fcfs",
4621
+ LuckyDraw: "lucky_draw",
4622
+ PointRanking: "ranking_2",
4623
+ ManualUpload: "manually_upload",
4624
+ OpenToAll: "open"
4536
4625
  };
4537
4626
  return labels[howToSelect];
4538
4627
  }
4539
- function formatRankingLabel(ranking) {
4628
+ function formatRankingLabel(ranking, t) {
4540
4629
  if (ranking.range_type === QuestWinnerRangeType.Number) {
4541
4630
  if (ranking.from < 2) {
4542
- return `Top ${ranking.to}`;
4631
+ return t("top_2", { to: ranking.to });
4543
4632
  }
4544
- return `Top ${ranking.from}-${ranking.to}`;
4633
+ return t("top", { from: ranking.from, to: ranking.to });
4545
4634
  } else {
4546
4635
  if (ranking.from === 0) {
4547
- return `Top ${ranking.to}%`;
4636
+ return t("top_percent_2", { to: ranking.to });
4548
4637
  }
4549
- return `Top ${ranking.from}%-${ranking.to}%`;
4638
+ return t("top_percent", { from: ranking.from, to: ranking.to });
4550
4639
  }
4551
4640
  }
4552
- function getTierLabel(layerIndex, isCurrentLayer) {
4641
+ function getTierLabel(layerIndex, isCurrentLayer, t) {
4553
4642
  if (isCurrentLayer) {
4554
- return "You are here";
4643
+ return t("here");
4555
4644
  }
4556
- return `Tier ${layerIndex + 1}`;
4645
+ return t("tier_index", { index: layerIndex + 1 });
4557
4646
  }
4558
4647
  function calculateFcfsAvailable(rewardLayer, currentWinner) {
4559
4648
  var _a;
@@ -4635,9 +4724,11 @@ function WinnerListModal({
4635
4724
  onClose,
4636
4725
  campaignId,
4637
4726
  winnerRewards,
4638
- pointsName = "Points"
4727
+ pointsName
4639
4728
  }) {
4729
+ const { t } = useQuestLocale();
4640
4730
  const { client } = useTaskOnContext();
4731
+ const resolvedPointsName = pointsName || t("points");
4641
4732
  const api = useMemo(() => {
4642
4733
  if (!client) return null;
4643
4734
  return createQuestApi(client);
@@ -4652,13 +4743,14 @@ function WinnerListModal({
4652
4743
  const tabItems = useMemo(() => {
4653
4744
  return winnerRewards.map((item, index) => {
4654
4745
  const howToSelect = getHowToSelectWinner$1(item);
4746
+ const label = getWinnerSelectionLabel$1(howToSelect);
4655
4747
  return {
4656
4748
  key: index,
4657
- label: getWinnerSelectionLabel$1(howToSelect),
4749
+ label: t(label),
4658
4750
  type: howToSelect
4659
4751
  };
4660
4752
  });
4661
- }, [winnerRewards]);
4753
+ }, [winnerRewards, t]);
4662
4754
  const currentType = useMemo(() => {
4663
4755
  var _a;
4664
4756
  return ((_a = tabItems[currentIndex]) == null ? void 0 : _a.type) || "FCFS";
@@ -4688,7 +4780,7 @@ function WinnerListModal({
4688
4780
  }
4689
4781
  setPage(pageNo);
4690
4782
  } catch (err) {
4691
- setError(err instanceof Error ? err.message : "Failed to load winners");
4783
+ setError(err instanceof Error ? err.message : t("failed_load_winners"));
4692
4784
  if (!append) {
4693
4785
  setTotal(0);
4694
4786
  setList([]);
@@ -4697,7 +4789,7 @@ function WinnerListModal({
4697
4789
  setLoading(false);
4698
4790
  }
4699
4791
  },
4700
- [api, campaignId, currentIndex, loading]
4792
+ [api, campaignId, currentIndex, loading, t]
4701
4793
  );
4702
4794
  useEffect(() => {
4703
4795
  if (isOpen && api) {
@@ -4743,13 +4835,14 @@ function WinnerListModal({
4743
4835
  onOpenChange: (open) => {
4744
4836
  if (!open) onClose();
4745
4837
  },
4746
- title: "Winners",
4838
+ title: t("winners"),
4747
4839
  showCloseButton: true,
4748
4840
  contentClassName: "taskon-quest-winner-modal",
4749
4841
  maxWidth: 600,
4750
4842
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-content", children: [
4751
4843
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-header", children: /* @__PURE__ */ jsxs("h2", { className: "taskon-quest-winner-title", children: [
4752
- "Winners (",
4844
+ t("winners"),
4845
+ " (",
4753
4846
  total.toLocaleString(),
4754
4847
  ")"
4755
4848
  ] }) }),
@@ -4770,16 +4863,16 @@ function WinnerListModal({
4770
4863
  variant: "primary",
4771
4864
  size: "small",
4772
4865
  onClick: () => loadPage(0, false),
4773
- children: "Retry"
4866
+ children: t("retry")
4774
4867
  }
4775
4868
  )
4776
4869
  ] }),
4777
4870
  !error && /* @__PURE__ */ jsxs("div", { ref: scrollRef, className: "taskon-quest-winner-list", children: [
4778
4871
  /* @__PURE__ */ jsxs("table", { className: "taskon-quest-winner-table", children: [
4779
4872
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
4780
- showPosition && /* @__PURE__ */ jsx("th", { children: "Position" }),
4781
- /* @__PURE__ */ jsx("th", { children: "User" }),
4782
- /* @__PURE__ */ jsx("th", { children: "Rewards" })
4873
+ showPosition && /* @__PURE__ */ jsx("th", { children: t("position") }),
4874
+ /* @__PURE__ */ jsx("th", { children: t("user") }),
4875
+ /* @__PURE__ */ jsx("th", { children: t("rewards") })
4783
4876
  ] }) }),
4784
4877
  /* @__PURE__ */ jsxs("tbody", { children: [
4785
4878
  list.map((item, index) => {
@@ -4793,7 +4886,7 @@ function WinnerListModal({
4793
4886
  WinnerRewardLabel,
4794
4887
  {
4795
4888
  data: reward,
4796
- pointName: pointsName
4889
+ pointName: resolvedPointsName
4797
4890
  },
4798
4891
  `${reward.reward_type}-${rewardIndex}`
4799
4892
  )) }) })
@@ -4804,14 +4897,14 @@ function WinnerListModal({
4804
4897
  {
4805
4898
  colSpan: showPosition ? 3 : 2,
4806
4899
  className: "taskon-quest-winner-empty",
4807
- children: "No winners yet"
4900
+ children: t("no_winners")
4808
4901
  }
4809
4902
  ) })
4810
4903
  ] })
4811
4904
  ] }),
4812
4905
  loading && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-loading", children: [
4813
4906
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-loading-spinner" }),
4814
- /* @__PURE__ */ jsx("span", { children: "Loading..." })
4907
+ /* @__PURE__ */ jsx("span", { children: t("loading") })
4815
4908
  ] })
4816
4909
  ] })
4817
4910
  ] })
@@ -4906,6 +4999,7 @@ function getIsBrc20(chain, tokenAddress, chains) {
4906
4999
  return (chainInfo == null ? void 0 : chainInfo.chain_type) === "btc" && tokenAddress !== BTC_CONTRACT;
4907
5000
  }
4908
5001
  function TokenInfo({ rewardInfo, chains }) {
5002
+ const { t } = useQuestLocale();
4909
5003
  const portalContainer = useTaskOnPortalContainer();
4910
5004
  const params = rewardInfo.reward_params;
4911
5005
  const distributeType = rewardInfo.reward_distribute_type;
@@ -4916,7 +5010,7 @@ function TokenInfo({ rewardInfo, chains }) {
4916
5010
  const isBrc20 = getIsBrc20(params.chain, params.token_address, chains);
4917
5011
  const totalAmount = formatTokenAmount(params.total_amount);
4918
5012
  const perAmount = params.per_amount;
4919
- const tokenNameDisplay = params.is_usdt_equal_amount ? `USD in ${params.token_name}` : params.token_name;
5013
+ const tokenNameDisplay = params.is_usdt_equal_amount ? t("usd_token_name", { token_name: params.token_name }) : params.token_name;
4920
5014
  const handleMouseEnter = () => {
4921
5015
  if (timeoutRef.current) {
4922
5016
  clearTimeout(timeoutRef.current);
@@ -4941,9 +5035,9 @@ function TokenInfo({ rewardInfo, chains }) {
4941
5035
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token", children: [
4942
5036
  isBlindBox && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token-blindbox", children: [
4943
5037
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-blindbox-icon", children: "✨" }),
4944
- /* @__PURE__ */ jsx("span", { children: "Smart Blind Box" })
5038
+ /* @__PURE__ */ jsx("span", { children: t("smart_blind_box") })
4945
5039
  ] }),
4946
- /* @__PURE__ */ jsx(BaseRow, { label: "Total Rewards Pool", children: /* @__PURE__ */ jsxs(Root2, { open, onOpenChange: setOpen, children: [
5040
+ /* @__PURE__ */ jsx(BaseRow, { label: t("total_rewards_pool"), children: /* @__PURE__ */ jsxs(Root2, { open, onOpenChange: setOpen, children: [
4947
5041
  /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
4948
5042
  "div",
4949
5043
  {
@@ -4976,12 +5070,11 @@ function TokenInfo({ rewardInfo, chains }) {
4976
5070
  onMouseEnter: handleMouseEnter,
4977
5071
  onMouseLeave: handleMouseLeave,
4978
5072
  children: [
4979
- params.is_usdt_equal_amount && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-name", children: [
4980
- "Equivalent amounts of ",
4981
- params.token_name
4982
- ] }),
5073
+ params.is_usdt_equal_amount && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: t("equivalent_amounts_token_name", {
5074
+ token_name: params.token_name
5075
+ }) }),
4983
5076
  params.token_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
4984
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: "Contract Address" }),
5077
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
4985
5078
  /* @__PURE__ */ jsxs(
4986
5079
  "button",
4987
5080
  {
@@ -5001,8 +5094,8 @@ function TokenInfo({ rewardInfo, chains }) {
5001
5094
  ) })
5002
5095
  ] }) }),
5003
5096
  distributeType !== QuestRewardsDistributeType.PointProportionally && (distributeType === QuestRewardsDistributeType.Random || distributeType === QuestRewardsDistributeType.BlindBox || Number(params.per_amount) > 0) && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token-per", children: [
5004
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-label", children: "Rewards Per Winner" }),
5005
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-value", children: distributeType === QuestRewardsDistributeType.Random || distributeType === QuestRewardsDistributeType.BlindBox ? "Random Amount" : `${perAmount} ${params.token_name}` })
5097
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-label", children: t("rewards_per_winner") }),
5098
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-value", children: distributeType === QuestRewardsDistributeType.Random || distributeType === QuestRewardsDistributeType.BlindBox ? t("random_amount") : `${perAmount} ${params.token_name}` })
5006
5099
  ] })
5007
5100
  ] });
5008
5101
  }
@@ -5015,6 +5108,7 @@ async function copyToClipboard$1(text) {
5015
5108
  }
5016
5109
  }
5017
5110
  function NftInfo({ rewardInfo, chains }) {
5111
+ const { t } = useQuestLocale();
5018
5112
  const portalContainer = useTaskOnPortalContainer();
5019
5113
  const params = rewardInfo.reward_params;
5020
5114
  const [open, setOpen] = useState(false);
@@ -5074,7 +5168,7 @@ function NftInfo({ rewardInfo, chains }) {
5074
5168
  children: [
5075
5169
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5076
5170
  params.nft_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
5077
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: "Contract Address" }),
5171
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
5078
5172
  /* @__PURE__ */ jsxs(
5079
5173
  "button",
5080
5174
  {
@@ -5103,6 +5197,7 @@ async function copyToClipboard(text) {
5103
5197
  }
5104
5198
  }
5105
5199
  function MintedNftInfo({ rewardInfo, chains }) {
5200
+ const { t } = useQuestLocale();
5106
5201
  const portalContainer = useTaskOnPortalContainer();
5107
5202
  const params = rewardInfo.reward_params;
5108
5203
  const [open, setOpen] = useState(false);
@@ -5162,7 +5257,7 @@ function MintedNftInfo({ rewardInfo, chains }) {
5162
5257
  children: [
5163
5258
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5164
5259
  params.nft_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
5165
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: "Contract Address" }),
5260
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
5166
5261
  /* @__PURE__ */ jsxs(
5167
5262
  "button",
5168
5263
  {
@@ -5195,8 +5290,9 @@ function CapInfo({ rewardInfo, chains }) {
5195
5290
  ) }) });
5196
5291
  }
5197
5292
  function WhitelistInfo({ rewardInfo, chains }) {
5293
+ const { t } = useQuestLocale();
5198
5294
  const params = rewardInfo.reward_params;
5199
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-whitelist", children: /* @__PURE__ */ jsx(BaseRow, { label: "Whitelist", children: params.chain && /* @__PURE__ */ jsx(
5295
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-whitelist", children: /* @__PURE__ */ jsx(BaseRow, { label: t("whitelist"), children: params.chain && /* @__PURE__ */ jsx(
5200
5296
  ChainIcon,
5201
5297
  {
5202
5298
  chain: params.chain,
@@ -5207,9 +5303,10 @@ function WhitelistInfo({ rewardInfo, chains }) {
5207
5303
  ) }) });
5208
5304
  }
5209
5305
  function PointsInfo({ rewardInfo }) {
5306
+ const { t } = useQuestLocale();
5210
5307
  const params = rewardInfo.reward_params;
5211
5308
  const formattedAmount = formatLargeNumber(params.amount);
5212
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-points", children: /* @__PURE__ */ jsx(BaseRow, { label: "Points/Winner", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-points-info", children: [
5309
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-points", children: /* @__PURE__ */ jsx(BaseRow, { label: t("points_winner"), children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-points-info", children: [
5213
5310
  params.points_icon && /* @__PURE__ */ jsx(
5214
5311
  "img",
5215
5312
  {
@@ -5223,21 +5320,23 @@ function PointsInfo({ rewardInfo }) {
5223
5320
  ] }) }) });
5224
5321
  }
5225
5322
  function ExpInfo({ rewardInfo }) {
5323
+ const { t } = useQuestLocale();
5226
5324
  const params = rewardInfo.reward_params;
5227
5325
  const formattedAmount = formatLargeNumber(params.per_amount);
5228
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-exp", children: /* @__PURE__ */ jsx(BaseRow, { label: "EXP/Winner", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-exp-info", children: [
5326
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-exp", children: /* @__PURE__ */ jsx(BaseRow, { label: t("exp_winner"), children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-exp-info", children: [
5229
5327
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-amount", children: formattedAmount }),
5230
5328
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-label", children: "EXP" })
5231
5329
  ] }) }) });
5232
5330
  }
5233
5331
  function DiscordRoleInfo({ rewardInfo }) {
5332
+ const { t } = useQuestLocale();
5234
5333
  const params = rewardInfo.reward_params;
5235
5334
  const handleClick = () => {
5236
5335
  if (params.discord_server_url) {
5237
5336
  window.open(params.discord_server_url, "_blank", "noopener,noreferrer");
5238
5337
  }
5239
5338
  };
5240
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-discord-role", children: /* @__PURE__ */ jsx(BaseRow, { label: "Discord Role", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-discord-role-info", children: [
5339
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-discord-role", children: /* @__PURE__ */ jsx(BaseRow, { label: t("discord_role"), children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-discord-role-info", children: [
5241
5340
  /* @__PURE__ */ jsx(
5242
5341
  "span",
5243
5342
  {
@@ -5247,7 +5346,7 @@ function DiscordRoleInfo({ rewardInfo }) {
5247
5346
  children: params.role_name
5248
5347
  }
5249
5348
  ),
5250
- params.not_official_discord && /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-discord-role-warning", children: "⚠️ Not Official" })
5349
+ params.not_official_discord && /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-discord-role-warning", children: t("official") })
5251
5350
  ] }) }) });
5252
5351
  }
5253
5352
  function TheReward({ rewardInfo, chains }) {
@@ -5281,6 +5380,7 @@ function WinnerCount({
5281
5380
  currentWinner,
5282
5381
  rankingLabel
5283
5382
  }) {
5383
+ const { t } = useQuestLocale();
5284
5384
  const maxWinners = rewardLayer.max_winners;
5285
5385
  if (howToSelectWinner === "OpenToAll") {
5286
5386
  return null;
@@ -5295,7 +5395,7 @@ function WinnerCount({
5295
5395
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-separator", children: "/" }),
5296
5396
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-total", children: maxWinners })
5297
5397
  ] }),
5298
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: "Available" })
5398
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: t("available") })
5299
5399
  ] });
5300
5400
  }
5301
5401
  case "PointRanking":
@@ -5306,11 +5406,12 @@ function WinnerCount({
5306
5406
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-count", children: maxWinners });
5307
5407
  }
5308
5408
  };
5309
- return /* @__PURE__ */ jsx(BaseRow, { label: "Winners", children: renderContent() });
5409
+ return /* @__PURE__ */ jsx(BaseRow, { label: t("winners"), children: renderContent() });
5310
5410
  }
5311
5411
  function GasStationProgress({
5312
5412
  gasStation
5313
5413
  }) {
5414
+ const { t } = useQuestLocale();
5314
5415
  if (!gasStation.gas_covered) {
5315
5416
  return null;
5316
5417
  }
@@ -5319,7 +5420,7 @@ function GasStationProgress({
5319
5420
  gasStation.used_gas_amount
5320
5421
  );
5321
5422
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-gas", children: [
5322
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-label", children: "Limited spots for gas free claiming!" }),
5423
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-label", children: t("limited_spots_gas_free_claiming") }),
5323
5424
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-bar", children: /* @__PURE__ */ jsx(
5324
5425
  "div",
5325
5426
  {
@@ -5333,8 +5434,10 @@ function GasStationProgress({
5333
5434
  function NftPreview({
5334
5435
  imageUrl,
5335
5436
  mediaType = "Image",
5336
- alt = "NFT Preview"
5437
+ alt
5337
5438
  }) {
5439
+ const { t } = useQuestLocale();
5440
+ const previewAlt = alt || t("nft_preview");
5338
5441
  if (!imageUrl) {
5339
5442
  return null;
5340
5443
  }
@@ -5352,7 +5455,7 @@ function NftPreview({
5352
5455
  "img",
5353
5456
  {
5354
5457
  src: imageUrl,
5355
- alt,
5458
+ alt: previewAlt,
5356
5459
  className: "taskon-quest-rewards-preview-image",
5357
5460
  loading: "lazy"
5358
5461
  }
@@ -5368,18 +5471,19 @@ function EstimatedRewards({
5368
5471
  isEnded,
5369
5472
  finalReward
5370
5473
  }) {
5474
+ const { t } = useQuestLocale();
5371
5475
  const rewardLabel = useMemo(() => {
5372
5476
  if (!isEnded) {
5373
- return "Your Estimated Rewards";
5477
+ return t("estimated_rewards");
5374
5478
  }
5375
5479
  if (!isCompleted) {
5376
5480
  return "";
5377
5481
  }
5378
5482
  if (finalReward) {
5379
- return "Your Final Rewards";
5483
+ return t("final_rewards");
5380
5484
  }
5381
- return "Your Estimated Rewards";
5382
- }, [isEnded, isCompleted, finalReward]);
5485
+ return t("estimated_rewards");
5486
+ }, [isEnded, isCompleted, finalReward, t]);
5383
5487
  if (!rewardLabel) {
5384
5488
  return null;
5385
5489
  }
@@ -5409,24 +5513,15 @@ function EstimatedRewards({
5409
5513
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-symbol", children: rewardSymbol })
5410
5514
  ] })
5411
5515
  ] }),
5412
- /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-formula", children: [
5413
- "= Total Rewards Pool * Your ",
5414
- pointName,
5415
- " / Total ",
5516
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-formula", children: t("eq_total_rewards_pool_pointname_total_pointname", {
5416
5517
  pointName
5417
- ] }),
5518
+ }) }),
5418
5519
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-row", children: [
5419
- /* @__PURE__ */ jsxs("span", { className: "taskon-quest-rewards-estimated-label", children: [
5420
- "Your ",
5421
- pointName
5422
- ] }),
5520
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-label", children: t("pointname", { pointName }) }),
5423
5521
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-points", children: formattedUserPoints })
5424
5522
  ] }),
5425
5523
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-total", children: [
5426
- /* @__PURE__ */ jsxs("span", { children: [
5427
- "Total ",
5428
- pointName
5429
- ] }),
5524
+ /* @__PURE__ */ jsx("span", { children: t("total_pointname", { pointName }) }),
5430
5525
  /* @__PURE__ */ jsx("span", { children: formattedTotalPoints })
5431
5526
  ] }),
5432
5527
  !isCompleted && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-mask", children: [
@@ -5438,29 +5533,31 @@ function EstimatedRewards({
5438
5533
  alt: ""
5439
5534
  }
5440
5535
  ),
5441
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-title", children: "Complete to qualify for rewards!" }),
5442
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-subtitle", children: "Once qualified, every point counts toward better rewards!" })
5536
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-title", children: t("complete_qualify_rewards") }),
5537
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-subtitle", children: t("once_qualified_every_point_counts_toward_better_rewards") })
5443
5538
  ] })
5444
5539
  ] });
5445
5540
  }
5446
5541
  function RankingPoint({
5447
5542
  userStatus,
5448
- pointsName = "Points"
5543
+ pointsName
5449
5544
  }) {
5450
5545
  var _a, _b;
5546
+ const { t } = useQuestLocale();
5547
+ const resolvedPointsName = pointsName || t("points");
5451
5548
  const ranking = userStatus.ranking;
5452
5549
  const tier = userStatus.tier;
5453
5550
  const points = ((_a = userStatus.current_point) == null ? void 0 : _a.amount) ?? 0;
5454
- const displayPointsName = ((_b = userStatus.current_point) == null ? void 0 : _b.points_name) || pointsName;
5551
+ const displayPointsName = ((_b = userStatus.current_point) == null ? void 0 : _b.points_name) || resolvedPointsName;
5455
5552
  const hasValidRanking = ranking >= 0;
5456
5553
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point", children: [
5457
5554
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-row", children: [
5458
5555
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-label", children: [
5459
- "Your Ranking",
5556
+ t("ranking"),
5460
5557
  /* @__PURE__ */ jsx(
5461
5558
  TipPopover,
5462
5559
  {
5463
- content: "You will be ranked only after completing all mandatory tasks in this quest.",
5560
+ content: t("ranked_after_completing_mandatory_tasks_quest"),
5464
5561
  side: "top",
5465
5562
  className: "taskon-quest-rewards-ranking-point-tip-icon"
5466
5563
  }
@@ -5468,21 +5565,20 @@ function RankingPoint({
5468
5565
  ] }),
5469
5566
  hasValidRanking ? /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-value", children: [
5470
5567
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-number", children: ranking }),
5471
- tier > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-tier", children: [
5472
- "Tier ",
5473
- tier
5474
- ] })
5475
- ] }) : /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-tip", children: [
5476
- "Complete all ",
5477
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-tip-highlight", children: "REQUIRED" }),
5478
- " tasks to secure a valid ranking."
5479
- ] })
5568
+ tier > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-tier", children: t("tier_index", { index: tier }) })
5569
+ ] }) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-tip", children: /* @__PURE__ */ jsx(
5570
+ I18nT,
5571
+ {
5572
+ t,
5573
+ i18nKey: "complete_required_tasks_secure_valid_ranking",
5574
+ components: {
5575
+ required: /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-tip-highlight", children: t("required") })
5576
+ }
5577
+ }
5578
+ ) })
5480
5579
  ] }),
5481
5580
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-row taskon-quest-rewards-ranking-point-row--points", children: [
5482
- /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-label", children: [
5483
- "Your ",
5484
- displayPointsName
5485
- ] }),
5581
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-label", children: t("pointname", { pointName: displayPointsName }) }),
5486
5582
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-amount", children: points })
5487
5583
  ] })
5488
5584
  ] });
@@ -5490,8 +5586,10 @@ function RankingPoint({
5490
5586
  function RewardBonus({
5491
5587
  extraBonus,
5492
5588
  qualifierRewards,
5493
- pointName = "Points"
5589
+ pointName
5494
5590
  }) {
5591
+ const { t } = useQuestLocale();
5592
+ const resolvedPointName = pointName || t("points");
5495
5593
  const qualifierPointParams = useMemo(() => {
5496
5594
  const pointsReward = qualifierRewards == null ? void 0 : qualifierRewards.find(
5497
5595
  (item) => item.reward_type === QuestRewardType.Points || item.reward_type === QuestRewardType.GTCPoints
@@ -5503,13 +5601,16 @@ function RewardBonus({
5503
5601
  return null;
5504
5602
  }
5505
5603
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus", children: [
5506
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: "Bonus" }),
5604
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: t("bonus") }),
5507
5605
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus-card", children: [
5508
- extraBonus && /* @__PURE__ */ jsx(BaseRow, { label: "Winner Bonus", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-desc", children: extraBonus }) }),
5509
- qualifierPointParams && /* @__PURE__ */ jsx(BaseRow, { label: "Qualifier Point", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus-value", children: [
5606
+ extraBonus && /* @__PURE__ */ jsx(BaseRow, { label: t("winner_bonus"), children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-desc", children: extraBonus }) }),
5607
+ qualifierPointParams && /* @__PURE__ */ jsx(BaseRow, { label: t("qualifier_point"), children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus-value", children: [
5510
5608
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-amount", children: qualifierPointParams.amount }),
5511
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-name", children: qualifierPointParams.points_name || pointName }),
5512
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-unit", children: "/Qualifier" })
5609
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-name", children: qualifierPointParams.points_name || resolvedPointName }),
5610
+ /* @__PURE__ */ jsxs("span", { className: "taskon-quest-rewards-bonus-unit", children: [
5611
+ "/",
5612
+ t("qualifiers")
5613
+ ] })
5513
5614
  ] }) })
5514
5615
  ] })
5515
5616
  ] });
@@ -5718,10 +5819,7 @@ function formatLongStr$1(str, separator = "...", prefixLen = 6, suffixLen = 6) {
5718
5819
  if (str.length <= prefixLen + suffixLen + 2) return str;
5719
5820
  return `${str.slice(0, prefixLen)}${separator}${str.slice(-suffixLen)}`;
5720
5821
  }
5721
- const NA_TIPS = "You will be ranked only after completing all mandatory tasks in this quest.";
5722
- const UNRANKED_TIP = "You are not ranked yet.";
5723
- const NOT_QUALIFIED_TIP = "You are not qualified for rewards in this tier.";
5724
- function getRewardTypeLabel(rewardType, pointsName) {
5822
+ function getRewardTypeLabel(rewardType, pointsName, t) {
5725
5823
  if (!rewardType) return "";
5726
5824
  switch (rewardType) {
5727
5825
  case RewardType.Nft:
@@ -5729,21 +5827,21 @@ function getRewardTypeLabel(rewardType, pointsName) {
5729
5827
  case RewardType.Cap:
5730
5828
  return "NFT:";
5731
5829
  case RewardType.DiscordRole:
5732
- return "Discord Role:";
5830
+ return `${t("discord_role")}:`;
5733
5831
  case RewardType.Exp:
5734
5832
  return "EXP:";
5735
5833
  case RewardType.GTCPoints:
5736
5834
  case RewardType.Points:
5737
5835
  return `${pointsName}:`;
5738
5836
  case RewardType.Token:
5739
- return "Token:";
5837
+ return `${t("token_name")}:`;
5740
5838
  case RewardType.Whitelist:
5741
- return "Whitelist";
5839
+ return t("whitelist");
5742
5840
  default:
5743
5841
  return "";
5744
5842
  }
5745
5843
  }
5746
- function getRewardLabel(row) {
5844
+ function getRewardLabel(row, t) {
5747
5845
  const { rewardType, rewardSymbol, rewardAmount, chainLabel, isUsdtEqual } = row;
5748
5846
  if (!rewardType) {
5749
5847
  return rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : "";
@@ -5761,7 +5859,9 @@ function getRewardLabel(row) {
5761
5859
  return rewardAmount || "";
5762
5860
  case RewardType.Token:
5763
5861
  if (isUsdtEqual) {
5764
- return `${rewardAmount} USD in ${rewardSymbol}`;
5862
+ return `${rewardAmount || ""} ${t("usd_token_name", {
5863
+ token_name: rewardSymbol || ""
5864
+ })}`.trim();
5765
5865
  }
5766
5866
  return `${rewardAmount} ${rewardSymbol}${chainLabel ? ` ${chainLabel}` : ""}`;
5767
5867
  case RewardType.Whitelist:
@@ -5771,25 +5871,44 @@ function getRewardLabel(row) {
5771
5871
  }
5772
5872
  }
5773
5873
  function RewardCell({ row }) {
5874
+ const { t } = useQuestLocale();
5875
+ const translate = t;
5774
5876
  if (row.winnerLayer !== void 0 && row.winnerLayer < 0) {
5775
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-reward-cell", children: /* @__PURE__ */ jsx(TipPopover, { content: NOT_QUALIFIED_TIP, side: "top", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-not-qualified", children: "Not Qualified" }) }) });
5877
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-reward-cell", children: /* @__PURE__ */ jsx(
5878
+ TipPopover,
5879
+ {
5880
+ content: t("qualified_rewards_tier"),
5881
+ side: "top",
5882
+ children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-not-qualified", children: t("qualified") })
5883
+ }
5884
+ ) });
5776
5885
  }
5777
5886
  if (!row.rewardAmount) {
5778
5887
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-no-reward", children: "--" });
5779
5888
  }
5780
- const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName);
5781
- const rewardLabel = getRewardLabel(row);
5889
+ const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName, translate);
5890
+ const rewardLabel = getRewardLabel(row, translate);
5782
5891
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-reward-cell", children: [
5783
5892
  typeLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward-type", children: typeLabel }),
5784
5893
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward", children: rewardLabel })
5785
5894
  ] });
5786
5895
  }
5787
5896
  function RankBadge({ rank }) {
5897
+ const { t } = useQuestLocale();
5788
5898
  if (rank < 0) {
5789
- return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank taskon-quest-leaderboard-rank--unranked", children: /* @__PURE__ */ jsx(TipPopover, { content: NA_TIPS, side: "top", children: /* @__PURE__ */ jsx("span", { children: "N/A" }) }) });
5899
+ return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank taskon-quest-leaderboard-rank--unranked", children: /* @__PURE__ */ jsx(
5900
+ TipPopover,
5901
+ {
5902
+ content: t(
5903
+ "ranked_after_completing_mandatory_tasks_quest"
5904
+ ),
5905
+ side: "top",
5906
+ children: /* @__PURE__ */ jsx("span", { children: t("na") })
5907
+ }
5908
+ ) });
5790
5909
  }
5791
5910
  if (rank === 0) {
5792
- return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank taskon-quest-leaderboard-rank--unranked", children: /* @__PURE__ */ jsx(TipPopover, { content: UNRANKED_TIP, side: "top", children: /* @__PURE__ */ jsx("span", { children: "Unranked" }) }) });
5911
+ return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank taskon-quest-leaderboard-rank--unranked", children: /* @__PURE__ */ jsx(TipPopover, { content: t("ranked"), side: "top", children: /* @__PURE__ */ jsx("span", { children: t("unranked") }) }) });
5793
5912
  }
5794
5913
  if (rank === 1) {
5795
5914
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank", children: /* @__PURE__ */ jsx(Rank1Icon, { size: 24 }) });
@@ -5806,8 +5925,9 @@ function UserCell({
5806
5925
  userName,
5807
5926
  isCurrentUser
5808
5927
  }) {
5928
+ const { t } = useQuestLocale();
5809
5929
  if (isCurrentUser) {
5810
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-user taskon-quest-leaderboard-user--current", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-user-badge", children: "YOU" }) });
5930
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-user taskon-quest-leaderboard-user--current", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-user-badge", children: t("you") }) });
5811
5931
  }
5812
5932
  return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-user", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-user-name", children: formatLongStr$1(userName) }) });
5813
5933
  }
@@ -5834,10 +5954,12 @@ function LeaderboardModal({
5834
5954
  isOpen,
5835
5955
  onClose,
5836
5956
  campaignId,
5837
- pointsName = "Points",
5957
+ pointsName,
5838
5958
  className = ""
5839
5959
  }) {
5960
+ const { t } = useQuestLocale();
5840
5961
  const { client, userId } = useTaskOnContext();
5962
+ const resolvedPointsName = pointsName || t("points");
5841
5963
  const [data, setData] = useState(null);
5842
5964
  const [loading, setLoading] = useState(false);
5843
5965
  const [error, setError] = useState(null);
@@ -5856,11 +5978,11 @@ function LeaderboardModal({
5856
5978
  });
5857
5979
  setData(result);
5858
5980
  } catch (err) {
5859
- setError(err instanceof Error ? err.message : "Failed to load leaderboard");
5981
+ setError(err instanceof Error ? err.message : t("failed_load_leaderboard"));
5860
5982
  } finally {
5861
5983
  setLoading(false);
5862
5984
  }
5863
- }, [client, isOpen, campaignId, page]);
5985
+ }, [client, isOpen, campaignId, page, t]);
5864
5986
  useEffect(() => {
5865
5987
  if (isOpen) {
5866
5988
  fetchData();
@@ -5880,15 +6002,21 @@ function LeaderboardModal({
5880
6002
  if (!data) return 0;
5881
6003
  return Math.ceil(data.total / PAGE_SIZE);
5882
6004
  }, [data]);
5883
- const positionTip = `The rankings are based on the total ${pointsName} earned from all tasks within this quest. In instances of tied ${pointsName}, submitters are ranked according to chronological order.`;
5884
- const tierTip = NA_TIPS;
5885
- const pointsTip = `${pointsName} collected from all tasks completed during the quest.`;
6005
+ const positionTip = t(
6006
+ "rankings_based_total_pointsname_earned_tasks_within_quest_instances",
6007
+ { pointsName: resolvedPointsName }
6008
+ );
6009
+ const tierTip = t("ranked_after_completing_mandatory_tasks_quest");
6010
+ const pointsTip = t(
6011
+ "pointsname_collected_tasks_completed_during_quest",
6012
+ { pointsName: resolvedPointsName }
6013
+ );
5886
6014
  const columns = useMemo(
5887
6015
  () => [
5888
6016
  {
5889
6017
  key: "rank",
5890
6018
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5891
- /* @__PURE__ */ jsx("span", { children: "Position" }),
6019
+ /* @__PURE__ */ jsx("span", { children: t("position") }),
5892
6020
  /* @__PURE__ */ jsx(TipPopover, { content: positionTip, side: "top" })
5893
6021
  ] }),
5894
6022
  width: 100,
@@ -5897,15 +6025,15 @@ function LeaderboardModal({
5897
6025
  {
5898
6026
  key: "tier",
5899
6027
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5900
- /* @__PURE__ */ jsx("span", { children: "Tier" }),
6028
+ /* @__PURE__ */ jsx("span", { children: t("tier") }),
5901
6029
  /* @__PURE__ */ jsx(TipPopover, { content: tierTip, side: "top" })
5902
6030
  ] }),
5903
6031
  width: 80,
5904
- render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-tier", children: row.tier !== void 0 && row.tier > 0 ? row.tier : "--" })
6032
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-tier", children: row.tier !== void 0 && row.tier > 0 ? row.tier : t("na") })
5905
6033
  },
5906
6034
  {
5907
6035
  key: "user",
5908
- title: "User",
6036
+ title: t("user"),
5909
6037
  minWidth: 120,
5910
6038
  render: (_, row) => /* @__PURE__ */ jsx(
5911
6039
  UserCell,
@@ -5918,21 +6046,21 @@ function LeaderboardModal({
5918
6046
  {
5919
6047
  key: "points",
5920
6048
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5921
- /* @__PURE__ */ jsx("span", { children: pointsName }),
6049
+ /* @__PURE__ */ jsx("span", { children: resolvedPointsName }),
5922
6050
  /* @__PURE__ */ jsx(TipPopover, { content: pointsTip, side: "top" })
5923
6051
  ] }),
5924
6052
  width: 100,
5925
- render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-points", children: row.points > 0 ? row.points.toLocaleString() : "--" })
6053
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-points", children: row.points > 0 ? row.points.toLocaleString() : t("na") })
5926
6054
  },
5927
6055
  {
5928
6056
  key: "rewards",
5929
- title: "Rewards",
6057
+ title: t("rewards"),
5930
6058
  width: 150,
5931
6059
  align: "right",
5932
6060
  render: (_, row) => /* @__PURE__ */ jsx(RewardCell, { row })
5933
6061
  }
5934
6062
  ],
5935
- [pointsName, positionTip, pointsTip, tierTip, userId]
6063
+ [positionTip, pointsTip, resolvedPointsName, t, tierTip, userId]
5936
6064
  );
5937
6065
  const rowConfig = useMemo(
5938
6066
  () => ({
@@ -5961,19 +6089,20 @@ function LeaderboardModal({
5961
6089
  onOpenChange: (open) => {
5962
6090
  if (!open) onClose();
5963
6091
  },
5964
- title: "Leaderboard",
6092
+ title: t("leaderboard"),
5965
6093
  showCloseButton: true,
5966
6094
  className,
5967
6095
  maxWidth: 600,
5968
6096
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-content", children: [
5969
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: "Leaderboard" }),
6097
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: t("leaderboard") }),
5970
6098
  data && /* @__PURE__ */ jsxs("p", { className: "taskon-quest-leaderboard-subtitle", children: [
5971
6099
  data.total_user.toLocaleString(),
5972
- " participants"
6100
+ " ",
6101
+ t("participants_2")
5973
6102
  ] }),
5974
6103
  error && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-error", children: [
5975
6104
  /* @__PURE__ */ jsx("p", { children: error }),
5976
- /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: "Retry" })
6105
+ /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: t("retry") })
5977
6106
  ] }),
5978
6107
  !error && /* @__PURE__ */ jsx(
5979
6108
  Table,
@@ -5982,10 +6111,10 @@ function LeaderboardModal({
5982
6111
  data: tableData,
5983
6112
  rowConfig,
5984
6113
  loading,
5985
- loadingText: "Loading...",
6114
+ loadingText: t("loading"),
5986
6115
  empty: {
5987
- title: "No Data",
5988
- description: "No participants yet"
6116
+ title: t("no_data"),
6117
+ description: t("no_participants")
5989
6118
  },
5990
6119
  striped: true,
5991
6120
  className: "taskon-quest-leaderboard-table"
@@ -6041,14 +6170,19 @@ function RewardCard$1({
6041
6170
  chains
6042
6171
  }) {
6043
6172
  var _a, _b, _c;
6173
+ const { t } = useQuestLocale();
6044
6174
  const [isDescOpen, setIsDescOpen] = useState(false);
6045
6175
  const isPointRanking = howToSelectWinner === "PointRanking";
6046
6176
  const ranking = (_a = rewardLayer.winner_layer) == null ? void 0 : _a.winner_rank_range;
6047
6177
  const rankingLabel = useMemo(() => {
6048
6178
  if (!ranking) return "";
6049
- return formatRankingLabel(ranking);
6050
- }, [ranking]);
6051
- const tierLabel = getTierLabel(layerIndex, isCurrentLayer);
6179
+ return formatRankingLabel(ranking, t);
6180
+ }, [ranking, t]);
6181
+ const tierLabel = getTierLabel(
6182
+ layerIndex,
6183
+ isCurrentLayer,
6184
+ t
6185
+ );
6052
6186
  const showEstimatedRewards = useMemo(() => {
6053
6187
  return rewardInfo.reward_distribute_type === QuestRewardsDistributeType.PointProportionally && totalPoints !== -1;
6054
6188
  }, [rewardInfo.reward_distribute_type, totalPoints]);
@@ -6139,7 +6273,7 @@ function RewardCard$1({
6139
6273
  className: "taskon-quest-rewards-whitelist-desc-trigger",
6140
6274
  onClick: () => setIsDescOpen(!isDescOpen),
6141
6275
  type: "button",
6142
- children: /* @__PURE__ */ jsx(BaseRow, { label: "Whitelist Description", children: /* @__PURE__ */ jsx(
6276
+ children: /* @__PURE__ */ jsx(BaseRow, { label: t("whitelist_description"), children: /* @__PURE__ */ jsx(
6143
6277
  UnfoldIcon,
6144
6278
  {
6145
6279
  className: `taskon-quest-rewards-whitelist-desc-icon ${isDescOpen ? "taskon-quest-rewards-whitelist-desc-icon--open" : ""}`
@@ -6179,12 +6313,13 @@ function WinnerGroup({
6179
6313
  groupIndex,
6180
6314
  chains
6181
6315
  }) {
6316
+ const { t } = useQuestLocale();
6182
6317
  const howToSelectWinner = useMemo(() => {
6183
6318
  return getHowToSelectWinner$1(group);
6184
6319
  }, [group]);
6185
6320
  const winnerSelectionLabel = useMemo(() => {
6186
- return getWinnerSelectionLabel$1(howToSelectWinner);
6187
- }, [howToSelectWinner]);
6321
+ return t(getWinnerSelectionLabel$1(howToSelectWinner));
6322
+ }, [howToSelectWinner, t]);
6188
6323
  const getTotalPoints = (layerIndex) => {
6189
6324
  if (group.automatically_winner_draw_type !== QuestAutomaticallyWinnerDrawType.PointRank) {
6190
6325
  return (userStatus == null ? void 0 : userStatus.open_to_all_total_points) || 0;
@@ -6230,12 +6365,14 @@ function QuestRewards({
6230
6365
  winnerRewards,
6231
6366
  campaignStatus,
6232
6367
  userStatus,
6233
- pointName = "Points",
6368
+ pointName,
6234
6369
  isEnded,
6235
6370
  isOngoingOrEnded = false,
6236
6371
  chains
6237
6372
  }) {
6238
6373
  var _a;
6374
+ const { t } = useQuestLocale();
6375
+ const resolvedPointName = pointName || t("points");
6239
6376
  const [isLeaderboardOpen, setIsLeaderboardOpen] = useState(false);
6240
6377
  if (!winnerRewards || winnerRewards.length === 0) {
6241
6378
  return null;
@@ -6252,7 +6389,7 @@ function QuestRewards({
6252
6389
  };
6253
6390
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards", children: [
6254
6391
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-container", children: [
6255
- showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: pointName }),
6392
+ showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: resolvedPointName }),
6256
6393
  showViewLeaderboard && /* @__PURE__ */ jsxs(
6257
6394
  "button",
6258
6395
  {
@@ -6260,7 +6397,7 @@ function QuestRewards({
6260
6397
  className: "taskon-quest-rewards-view-leaderboard",
6261
6398
  onClick: handleOpenLeaderboard,
6262
6399
  children: [
6263
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-text", children: "View Leaderboard" }),
6400
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-text", children: t("view_leaderboard") }),
6264
6401
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-arrow", children: "→" })
6265
6402
  ]
6266
6403
  }
@@ -6270,7 +6407,7 @@ function QuestRewards({
6270
6407
  {
6271
6408
  group,
6272
6409
  currentWinners,
6273
- pointName,
6410
+ pointName: resolvedPointName,
6274
6411
  isEnded,
6275
6412
  userStatus,
6276
6413
  groupIndex,
@@ -6285,7 +6422,7 @@ function QuestRewards({
6285
6422
  isOpen: isLeaderboardOpen,
6286
6423
  onClose: handleCloseLeaderboard,
6287
6424
  campaignId,
6288
- pointsName: pointName
6425
+ pointsName: resolvedPointName
6289
6426
  }
6290
6427
  )
6291
6428
  ] });
@@ -6365,26 +6502,29 @@ function getHowToSelectWinner(winnerReward) {
6365
6502
  function getWinnerSelectionLabel(howToSelectWinner) {
6366
6503
  switch (howToSelectWinner) {
6367
6504
  case 1:
6368
- return { label: "Lucky Draw", desc: "Winners are randomly selected" };
6505
+ return { label: "lucky_draw", desc: "winners_randomly_selected" };
6369
6506
  case 0:
6370
6507
  return {
6371
- label: "FCFS",
6372
- desc: "First to complete gets the reward"
6508
+ label: "fcfs",
6509
+ desc: "first_complete_gets_reward"
6373
6510
  };
6374
6511
  case 4:
6375
6512
  return {
6376
- label: "Open to All",
6377
- desc: "All qualified users receive reward"
6513
+ label: "open",
6514
+ desc: "qualified_users_receive_reward"
6378
6515
  };
6379
6516
  case 3:
6380
- return { label: "Ranking", desc: "Top ranked users win" };
6517
+ return { label: "ranking_2", desc: "top_ranked_users_win" };
6381
6518
  case 2:
6382
6519
  return {
6383
- label: "Manually Upload",
6384
- desc: "Project owner selects winners"
6520
+ label: "manually_upload",
6521
+ desc: "project_owner_selects_winners"
6385
6522
  };
6386
6523
  default:
6387
- return { label: "", desc: "" };
6524
+ return {
6525
+ label: "fcfs",
6526
+ desc: "first_complete_gets_reward"
6527
+ };
6388
6528
  }
6389
6529
  }
6390
6530
  function getEarnedWinnerSelectionList(winnerRewards, userStatus, campaignStatus) {
@@ -6530,52 +6670,52 @@ function getStatusCardConfig(status, params) {
6530
6670
  case "winner":
6531
6671
  return {
6532
6672
  badgeType: "winner",
6533
- title: "Congratulations!"
6673
+ title: "congratulations"
6534
6674
  };
6535
6675
  case "blind-box-failed":
6536
6676
  case "qualifier-failed":
6537
6677
  return {
6538
6678
  badgeType: "qualifier",
6539
- title: "Oops! Better Luck Next Time!",
6540
- description: "You have won multiple rewards!"
6679
+ title: "oops_better_luck_next_time",
6680
+ description: "won_multiple_rewards"
6541
6681
  // Will be overridden if has rewards
6542
6682
  };
6543
6683
  case "qualifier-wait":
6544
6684
  if (params == null ? void 0 : params.hasLegacyManual) {
6545
6685
  return {
6546
6686
  badgeType: "qualifier",
6547
- title: "Successfully Entered!",
6548
- description: "Waiting for project owner to upload the winner list. Stay tuned to see if you win!"
6687
+ title: "successfully_entered",
6688
+ description: "waiting_project_owner_upload_winner_list_stay_tuned_see_2"
6549
6689
  };
6550
6690
  }
6551
6691
  if (params == null ? void 0 : params.hasPointRanking) {
6552
6692
  return {
6553
6693
  badgeType: "qualifier",
6554
- title: "Successfully Entered!",
6555
- description: "Waiting for final ranking. Stay tuned to see if you win!"
6694
+ title: "successfully_entered",
6695
+ description: "waiting_final_ranking_stay_tuned_see_win_2"
6556
6696
  };
6557
6697
  }
6558
6698
  return {
6559
6699
  badgeType: "qualifier",
6560
- title: "Waiting for drawing winners",
6561
- description: "Please keep participating in tasks (e.g. keep following on X) to stay eligible for winner draws!"
6700
+ title: "waiting_drawing_winners",
6701
+ description: "please_keep_participating_tasks_e_g_keep_following_x"
6562
6702
  };
6563
6703
  case "submitter-failed":
6564
6704
  return {
6565
6705
  badgeType: "submitter",
6566
- title: "Oops!",
6567
- description: "Not all tasks are successfully verified, better luck next time!"
6706
+ title: "oops",
6707
+ description: "tasks_successfully_verified_better_luck_next_time"
6568
6708
  };
6569
6709
  case "submitter-wait":
6570
6710
  return {
6571
6711
  badgeType: "submitter",
6572
- title: "Waiting For Task Verification",
6573
- description: "Stay tuned! Only verified users are eligible to compete for rewards."
6712
+ title: "waiting_task_verification",
6713
+ description: "stay_tuned_verified_users_eligible_compete_rewards"
6574
6714
  };
6575
6715
  case "too-late":
6576
6716
  return {
6577
- title: "Oops!",
6578
- description: "Sorry you are late."
6717
+ title: "oops",
6718
+ description: "sorry_late"
6579
6719
  };
6580
6720
  case "can-complete":
6581
6721
  return null;
@@ -6616,6 +6756,7 @@ function RewardToken({
6616
6756
  rewardDisplayMode = "popup",
6617
6757
  rewardRedirectUrl
6618
6758
  }) {
6759
+ const { t } = useQuestLocale();
6619
6760
  const [popupOpen, setPopupOpen] = useState(false);
6620
6761
  const params = reward.reward_value;
6621
6762
  const chainInfo = useMemo(() => {
@@ -6639,10 +6780,10 @@ function RewardToken({
6639
6780
  }, [params.amount]);
6640
6781
  const typeText = useMemo(() => {
6641
6782
  if (params.is_usdt_equal_amount) {
6642
- return `USD in ${params.token_name}`;
6783
+ return t("usd_token_name", { token_name: params.token_name });
6643
6784
  }
6644
6785
  return params.token_name;
6645
- }, [params.is_usdt_equal_amount, params.token_name]);
6786
+ }, [params.is_usdt_equal_amount, params.token_name, t]);
6646
6787
  const showAmountNotRevealed = !params.amount;
6647
6788
  const showWithdraw = isDeposited && params.amount;
6648
6789
  const handleWithdraw = useCallback(() => {
@@ -6667,9 +6808,9 @@ function RewardToken({
6667
6808
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: formattedAmount })
6668
6809
  ] }),
6669
6810
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: typeText }),
6670
- showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: "Withdraw" })
6811
+ showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: t("withdraw") })
6671
6812
  ] }),
6672
- showAmountNotRevealed && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "Reward amount will be revealed once quest ends." })
6813
+ showAmountNotRevealed && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("reward_amount_revealed_once_quest_ends") })
6673
6814
  ] }),
6674
6815
  /* @__PURE__ */ jsx(
6675
6816
  RewardModuleDialog,
@@ -6745,6 +6886,7 @@ function RewardNft({
6745
6886
  onRefresh,
6746
6887
  onClaimNft
6747
6888
  }) {
6889
+ const { t } = useQuestLocale();
6748
6890
  const [loading, setLoading] = useState(false);
6749
6891
  const params = reward.reward_value;
6750
6892
  const chainInfo = useMemo(() => {
@@ -6786,10 +6928,10 @@ function RewardNft({
6786
6928
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6787
6929
  ] }),
6788
6930
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6789
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6931
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6790
6932
  ] }),
6791
- 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: [
6792
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: "Txn Hash:" }),
6933
+ openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: t("check_collection_opensea") }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6934
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: t("txn_hash") }),
6793
6935
  /* @__PURE__ */ jsx(
6794
6936
  "a",
6795
6937
  {
@@ -6810,6 +6952,7 @@ function RewardMintedNft({
6810
6952
  onRefresh,
6811
6953
  onClaimNft
6812
6954
  }) {
6955
+ const { t } = useQuestLocale();
6813
6956
  const [loading, setLoading] = useState(false);
6814
6957
  const params = reward.reward_value;
6815
6958
  const chainInfo = useMemo(() => {
@@ -6854,10 +6997,10 @@ function RewardMintedNft({
6854
6997
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6855
6998
  ] }),
6856
6999
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6857
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
7000
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6858
7001
  ] }),
6859
- 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: [
6860
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: "Txn Hash:" }),
7002
+ openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: t("check_collection_opensea") }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
7003
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: t("txn_hash") }),
6861
7004
  /* @__PURE__ */ jsx(
6862
7005
  "a",
6863
7006
  {
@@ -6869,7 +7012,7 @@ function RewardMintedNft({
6869
7012
  }
6870
7013
  )
6871
7014
  ] }),
6872
- isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "NFT will be airdropped soon..." })
7015
+ isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("nft_airdropped_soon") })
6873
7016
  ] });
6874
7017
  }
6875
7018
  function RewardCap({
@@ -6879,6 +7022,7 @@ function RewardCap({
6879
7022
  onRefresh,
6880
7023
  onClaimNft
6881
7024
  }) {
7025
+ const { t } = useQuestLocale();
6882
7026
  const [loading, setLoading] = useState(false);
6883
7027
  const params = reward.reward_value;
6884
7028
  const chainInfo = useMemo(() => {
@@ -6917,18 +7061,19 @@ function RewardCap({
6917
7061
  className: "taskon-quest-footer-earned-single-icon"
6918
7062
  }
6919
7063
  ),
6920
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Cap" })
7064
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "CAP" })
6921
7065
  ] }),
6922
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
7066
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6923
7067
  ] }),
6924
- elementLink && /* @__PURE__ */ jsx(ActionButton, { href: elementLink, children: "Check CAP on Element" }),
6925
- isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "Cap will be airdropped soon..." })
7068
+ elementLink && /* @__PURE__ */ jsx(ActionButton, { href: elementLink, children: t("check_cap_element") }),
7069
+ isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("cap_airdropped_soon") })
6926
7070
  ] });
6927
7071
  }
6928
7072
  function RewardWhitelist({
6929
7073
  reward,
6930
7074
  chains
6931
7075
  }) {
7076
+ const { t } = useQuestLocale();
6932
7077
  const params = reward.reward_value;
6933
7078
  const chainInfo = useMemo(() => {
6934
7079
  if (!chains || !params.chain) return null;
@@ -6943,7 +7088,7 @@ function RewardWhitelist({
6943
7088
  className: "taskon-quest-footer-earned-single-icon"
6944
7089
  }
6945
7090
  ),
6946
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Whitelist" })
7091
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: t("whitelist") })
6947
7092
  ] }) }) });
6948
7093
  }
6949
7094
  function RewardPoint({
@@ -6951,14 +7096,15 @@ function RewardPoint({
6951
7096
  rewardDisplayMode = "popup",
6952
7097
  rewardRedirectUrl
6953
7098
  }) {
7099
+ const { t } = useQuestLocale();
6954
7100
  const [popupOpen, setPopupOpen] = useState(false);
6955
7101
  const params = reward.reward_value;
6956
7102
  const pointName = useMemo(() => {
6957
7103
  if (reward.reward_type === RewardType.GTCPoints) {
6958
- return params.points_name || "Points";
7104
+ return params.points_name || t("points");
6959
7105
  }
6960
- return "Points";
6961
- }, [reward.reward_type, params.points_name]);
7106
+ return t("points");
7107
+ }, [reward.reward_type, params.points_name, t]);
6962
7108
  const handlePointsHistory = useCallback(() => {
6963
7109
  if (rewardDisplayMode === "redirect" && rewardRedirectUrl) {
6964
7110
  window.open(rewardRedirectUrl, "_blank", "noopener,noreferrer");
@@ -6973,7 +7119,7 @@ function RewardPoint({
6973
7119
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-single-info", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: params.amount }) }),
6974
7120
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: pointName })
6975
7121
  ] }),
6976
- /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: "Points History" })
7122
+ /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: t("points_history") })
6977
7123
  ] }),
6978
7124
  /* @__PURE__ */ jsx(
6979
7125
  RewardModuleDialog,
@@ -6992,6 +7138,7 @@ function RewardDiscordRole({
6992
7138
  onRefresh,
6993
7139
  onClaimDiscordRole
6994
7140
  }) {
7141
+ const { t } = useQuestLocale();
6995
7142
  const [loading, setLoading] = useState(false);
6996
7143
  const params = reward.reward_value;
6997
7144
  const isClaimable = useMemo(() => {
@@ -7013,9 +7160,9 @@ function RewardDiscordRole({
7013
7160
  }
7014
7161
  }, [onClaimDiscordRole, reward, layer, onRefresh]);
7015
7162
  return /* @__PURE__ */ jsx(RewardCard, { children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-row", children: [
7016
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-single-info", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Discord Role" }) }),
7163
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-single-info", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: t("discord_role") }) }),
7017
7164
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.role_name }),
7018
- isClaimable ? /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" }) : /* @__PURE__ */ jsx(ClaimButton, { disabled: true, children: "Claimed" })
7165
+ isClaimable ? /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") }) : /* @__PURE__ */ jsx(ClaimButton, { disabled: true, children: t("claimed") })
7019
7166
  ] }) });
7020
7167
  }
7021
7168
  const REWARD_COMPONENT_MAP = {
@@ -7039,24 +7186,24 @@ function RewardItem(props) {
7039
7186
  }
7040
7187
  const OOPS_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23FF6B6B'/%3E%3Cpath d='M8 4v5' stroke='white' stroke-width='1.5' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='11.5' r='0.75' fill='white'/%3E%3C/svg%3E";
7041
7188
  const WAIT_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='34' viewBox='0 0 34 34' fill='none'%3E%3Ccircle cx='17' cy='17' r='16' stroke='%23CBFF01' stroke-width='2'/%3E%3Cpath d='M17 9v8l5 3' stroke='%23CBFF01' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E";
7042
- function getFailedLabel(status) {
7189
+ function getFailedLabel(status, t) {
7043
7190
  if (status === "join-earlier") {
7044
- return "Join the quest earlier next time!";
7191
+ return t("join_quest_earlier_next_time");
7045
7192
  }
7046
7193
  if (status === "better-luck") {
7047
- return "Oops, Better Luck Next Time!";
7194
+ return t("oops_better_luck_next_time_2");
7048
7195
  }
7049
7196
  return "";
7050
7197
  }
7051
- function getWaitLabel(status) {
7198
+ function getWaitLabel(status, t) {
7052
7199
  if (status === "wait-draw") {
7053
- return "Waiting for drawing winners, Stay tuned to see if you win!";
7200
+ return t("waiting_drawing_winners_stay_tuned_see_win");
7054
7201
  }
7055
7202
  if (status === "wait-upload") {
7056
- return "Waiting for project owner to upload the winner list, Stay tuned to see if you win!";
7203
+ return t("waiting_project_owner_upload_winner_list_stay_tuned_see");
7057
7204
  }
7058
7205
  if (status === "wait-ranking") {
7059
- return "Waiting For Final Ranking, Stay tuned to see if you win!";
7206
+ return t("waiting_final_ranking_stay_tuned_see_win");
7060
7207
  }
7061
7208
  return "";
7062
7209
  }
@@ -7072,12 +7219,14 @@ function SelectionItem({
7072
7219
  rewardDisplayMode,
7073
7220
  rewardRedirectUrl
7074
7221
  }) {
7222
+ const { t } = useQuestLocale();
7075
7223
  const { howToSelectWinner, status, rewards } = selection;
7076
7224
  const label = getWinnerSelectionLabel(howToSelectWinner);
7077
- const failedLabel = getFailedLabel(status);
7078
- const waitLabel = getWaitLabel(status);
7225
+ const translate = t;
7226
+ const failedLabel = getFailedLabel(status, translate);
7227
+ const waitLabel = getWaitLabel(status, translate);
7079
7228
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-item", children: [
7080
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-selection-label", children: label.label }),
7229
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-selection-label", children: t(label.label) }),
7081
7230
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-rewards", children: [
7082
7231
  status === "winner" && rewards.map((layer) => /* @__PURE__ */ jsx(React__default.Fragment, { children: layer.reward.map((reward) => /* @__PURE__ */ jsx(
7083
7232
  RewardItem,
@@ -7136,6 +7285,7 @@ function DetailPanelDialog({
7136
7285
  rewardDisplayMode,
7137
7286
  rewardRedirectUrl
7138
7287
  }) {
7288
+ const { t } = useQuestLocale();
7139
7289
  const winnerSelectionList = useMemo(() => {
7140
7290
  return getEarnedWinnerSelectionList(
7141
7291
  campaign.winner_rewards,
@@ -7147,7 +7297,7 @@ function DetailPanelDialog({
7147
7297
  const qualifierRewards = campaign.qualifier_rewards;
7148
7298
  if (!qualifierRewards) return null;
7149
7299
  const reward = qualifierRewards.find(
7150
- (item) => item.reward_type === "Points" || item.reward_type === "GTCPoints"
7300
+ (item) => item.reward_type === "points" || item.reward_type === "GTCPoints"
7151
7301
  );
7152
7302
  if (!reward) return null;
7153
7303
  return reward.reward_params;
@@ -7157,12 +7307,12 @@ function DetailPanelDialog({
7157
7307
  {
7158
7308
  open,
7159
7309
  onOpenChange,
7160
- title: "Multiple Rewards Detail",
7310
+ title: t("multiple_rewards_detail"),
7161
7311
  showCloseButton: true,
7162
7312
  maxWidth: 480,
7163
7313
  contentClassName: "taskon-quest-footer-detail-dialog",
7164
7314
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-panel", children: [
7165
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-footer-detail-title", children: "Multiple Rewards Detail" }),
7315
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-footer-detail-title", children: t("multiple_rewards_detail") }),
7166
7316
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-content", children: winnerSelectionList.map((item, index) => /* @__PURE__ */ jsx(
7167
7317
  SelectionItem,
7168
7318
  {
@@ -7180,13 +7330,11 @@ function DetailPanelDialog({
7180
7330
  index
7181
7331
  )) }),
7182
7332
  qualifierPointParams && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-bonus", children: [
7183
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-label", children: "Bonus" }),
7184
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-right", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-bonus-item", children: [
7185
- qualifierPointParams.amount,
7186
- " Qualifier",
7187
- " ",
7188
- qualifierPointParams.points_name || "Points"
7189
- ] }) })
7333
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-label", children: t("bonus") }),
7334
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-right", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-item", children: t("amount_qualifier_pointsname", {
7335
+ amount: qualifierPointParams.amount,
7336
+ pointsName: qualifierPointParams.points_name || t("points")
7337
+ }) }) })
7190
7338
  ] })
7191
7339
  ] })
7192
7340
  }
@@ -7206,6 +7354,7 @@ function EarnedRewards({
7206
7354
  rewardDisplayMode = "popup",
7207
7355
  rewardRedirectUrl
7208
7356
  }) {
7357
+ const { t } = useQuestLocale();
7209
7358
  const [dialogOpen, setDialogOpen] = useState(false);
7210
7359
  const rewardCount = useMemo(() => {
7211
7360
  return earnedRewards.reduce(
@@ -7234,8 +7383,8 @@ function EarnedRewards({
7234
7383
  hasMultiReward ? (
7235
7384
  // Multiple rewards: show text + button
7236
7385
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-multi", children: [
7237
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-multi-text", children: "You have won multiple rewards!" }),
7238
- /* @__PURE__ */ jsx(ClaimButton, { onClick: handleOpenDialog, children: "Check & Claim" })
7386
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-multi-text", children: t("won_multiple_rewards") }),
7387
+ /* @__PURE__ */ jsx(ClaimButton, { onClick: handleOpenDialog, children: t("check_claim") })
7239
7388
  ] })
7240
7389
  ) : (
7241
7390
  // Single reward: show detailed card
@@ -7277,7 +7426,13 @@ function EarnedRewards({
7277
7426
  ] });
7278
7427
  }
7279
7428
  function StatusBadge({ type }) {
7280
- const badgeText = type.toUpperCase();
7429
+ const { t } = useQuestLocale();
7430
+ const badgeTextMap = {
7431
+ winner: t("winners"),
7432
+ qualifier: t("qualifiers"),
7433
+ submitter: t("submitters")
7434
+ };
7435
+ const badgeText = badgeTextMap[type];
7281
7436
  return /* @__PURE__ */ jsx("div", { className: `taskon-quest-footer-badge taskon-quest-footer-badge--${type}`, children: badgeText });
7282
7437
  }
7283
7438
  function StatusCard(props) {
@@ -7329,19 +7484,21 @@ function StatusCard(props) {
7329
7484
  ) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-card-message", children: description }) })
7330
7485
  ] });
7331
7486
  }
7332
- const REPEAT_SUBMIT_ERROR_MESSAGE = "Oops! Seems like you already finished this quest";
7333
- const DEFAULT_COMPLETE_ERROR_MESSAGE = "Failed to complete quest";
7334
- function normalizeCompleteSubmitError(error) {
7487
+ function normalizeCompleteSubmitError(error, t) {
7335
7488
  if (error instanceof ApiError) {
7336
7489
  if (error.code === ErrorCode.RUSER_REPEAT_SUBMIT) {
7337
- return new ApiError(error.code, REPEAT_SUBMIT_ERROR_MESSAGE, error.data);
7490
+ return new ApiError(
7491
+ error.code,
7492
+ t("oops_seems_like_already_finished_quest_2"),
7493
+ error.data
7494
+ );
7338
7495
  }
7339
7496
  return error;
7340
7497
  }
7341
7498
  if (error instanceof Error) {
7342
7499
  return error;
7343
7500
  }
7344
- return new Error(DEFAULT_COMPLETE_ERROR_MESSAGE);
7501
+ return new Error(t("failed_complete_quest"));
7345
7502
  }
7346
7503
  function CompleteButton({
7347
7504
  campaignId,
@@ -7354,13 +7511,14 @@ function CompleteButton({
7354
7511
  className,
7355
7512
  onBeforeComplete
7356
7513
  }) {
7514
+ const { t } = useQuestLocale();
7357
7515
  const [isLoading, setIsLoading] = useState(false);
7358
7516
  const { client } = useTaskOnContext();
7359
7517
  const api = useMemo(() => {
7360
7518
  if (!client) return null;
7361
7519
  return createQuestApi(client);
7362
7520
  }, [client]);
7363
- const buttonText = hasPointProportionally2 ? "Complete to qualify for rewards!" : "Complete";
7521
+ const buttonText = hasPointProportionally2 ? t("complete_qualify_rewards") : t("complete");
7364
7522
  const handleComplete = useCallback(async () => {
7365
7523
  if (!api || isLoading || disabled) {
7366
7524
  return;
@@ -7379,7 +7537,7 @@ function CompleteButton({
7379
7537
  }
7380
7538
  }
7381
7539
  if (requiresRecaptcha && !captchaToken) {
7382
- onError == null ? void 0 : onError(new Error("reCAPTCHA verification required"));
7540
+ onError == null ? void 0 : onError(new Error(t("recaptcha_verification_required")));
7383
7541
  return;
7384
7542
  }
7385
7543
  try {
@@ -7391,7 +7549,10 @@ function CompleteButton({
7391
7549
  });
7392
7550
  onComplete == null ? void 0 : onComplete();
7393
7551
  } catch (error) {
7394
- const normalizedError = normalizeCompleteSubmitError(error);
7552
+ const normalizedError = normalizeCompleteSubmitError(
7553
+ error,
7554
+ t
7555
+ );
7395
7556
  onError == null ? void 0 : onError(normalizedError);
7396
7557
  }
7397
7558
  } finally {
@@ -7406,7 +7567,8 @@ function CompleteButton({
7406
7567
  onBeforeComplete,
7407
7568
  onComplete,
7408
7569
  onError,
7409
- requiresRecaptcha
7570
+ requiresRecaptcha,
7571
+ t
7410
7572
  ]);
7411
7573
  return /* @__PURE__ */ jsx(
7412
7574
  "button",
@@ -7417,15 +7579,13 @@ function CompleteButton({
7417
7579
  disabled: disabled || isLoading || !api,
7418
7580
  children: isLoading ? /* @__PURE__ */ jsxs("span", { className: "taskon-quest-footer-complete-btn-loading", children: [
7419
7581
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-complete-btn-spinner" }),
7420
- "Completing..."
7582
+ t("completing")
7421
7583
  ] }) : buttonText
7422
7584
  }
7423
7585
  );
7424
7586
  }
7425
- const REPEAT_SUBMIT_NOTICE_TITLE = "Oops! Seems like You already finished this quest";
7426
- 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.";
7427
- const REPEAT_SUBMIT_NOTICE_CONFIRM = "Confirm";
7428
7587
  function OperateFooter(props) {
7588
+ const { t } = useQuestLocale();
7429
7589
  const {
7430
7590
  campaign,
7431
7591
  userStatus,
@@ -7486,12 +7646,22 @@ function OperateFooter(props) {
7486
7646
  hasPointRanking: hasRanking
7487
7647
  });
7488
7648
  }, [participationStatus, hasLegacyManual, hasRanking]);
7649
+ const localizedCardConfig = useMemo(() => {
7650
+ if (!cardConfig) {
7651
+ return null;
7652
+ }
7653
+ return {
7654
+ ...cardConfig,
7655
+ title: t(cardConfig.title),
7656
+ description: cardConfig.description ? t(cardConfig.description) : void 0
7657
+ };
7658
+ }, [cardConfig, t]);
7489
7659
  const renderConnectWallet = () => /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-connect", children: /* @__PURE__ */ jsx(
7490
7660
  "button",
7491
7661
  {
7492
7662
  className: "taskon-quest-footer-connect-btn",
7493
7663
  onClick: onConnectWallet,
7494
- children: "Connect Wallet to Participate"
7664
+ children: t("start_to_earn")
7495
7665
  }
7496
7666
  ) });
7497
7667
  const handleCompleteError = useCallback(
@@ -7517,13 +7687,13 @@ function OperateFooter(props) {
7517
7687
  }
7518
7688
  );
7519
7689
  const renderStatusCard = () => {
7520
- if (!cardConfig) return null;
7690
+ if (!localizedCardConfig) return null;
7521
7691
  return /* @__PURE__ */ jsx(
7522
7692
  StatusCard,
7523
7693
  {
7524
- title: cardConfig.title,
7525
- badgeType: cardConfig.badgeType,
7526
- description: cardConfig.description,
7694
+ title: localizedCardConfig.title,
7695
+ badgeType: localizedCardConfig.badgeType,
7696
+ description: localizedCardConfig.description,
7527
7697
  campaign,
7528
7698
  userStatus: userStatus || void 0,
7529
7699
  campaignStatus: campaignStatus || void 0,
@@ -7545,12 +7715,16 @@ function OperateFooter(props) {
7545
7715
  open: isRepeatSubmitDialogVisible,
7546
7716
  onOpenChange: setIsRepeatSubmitDialogVisible,
7547
7717
  type: "warn",
7548
- title: REPEAT_SUBMIT_NOTICE_TITLE,
7549
- desc: REPEAT_SUBMIT_NOTICE_DESC,
7550
- confirmButton: REPEAT_SUBMIT_NOTICE_CONFIRM,
7718
+ title: t("oops_seems_like_already_finished_quest"),
7719
+ desc: t(
7720
+ "ensure_fair_experience_submissions_identical_wallet_addresses_x_discord"
7721
+ ),
7722
+ confirmButton: t("confirm"),
7551
7723
  onConfirm: () => setIsRepeatSubmitDialogVisible(false),
7552
- accessibilityTitle: REPEAT_SUBMIT_NOTICE_TITLE,
7553
- accessibilityDescription: REPEAT_SUBMIT_NOTICE_DESC
7724
+ accessibilityTitle: t("oops_seems_like_already_finished_quest"),
7725
+ accessibilityDescription: t(
7726
+ "ensure_fair_experience_submissions_identical_wallet_addresses_x_discord"
7727
+ )
7554
7728
  }
7555
7729
  );
7556
7730
  let footerContent = null;
@@ -7558,7 +7732,7 @@ function OperateFooter(props) {
7558
7732
  footerContent = renderConnectWallet();
7559
7733
  } else if (participationStatus === "can-complete") {
7560
7734
  footerContent = renderCompleteButton();
7561
- } else if (participationStatus !== "none" && cardConfig) {
7735
+ } else if (participationStatus !== "none" && localizedCardConfig) {
7562
7736
  footerContent = renderStatusCard();
7563
7737
  }
7564
7738
  if (!footerContent && !isRepeatSubmitDialogVisible) {
@@ -7569,16 +7743,16 @@ function OperateFooter(props) {
7569
7743
  renderRepeatSubmitNoticeDialog()
7570
7744
  ] });
7571
7745
  }
7572
- function getDialogTitle(errorType) {
7746
+ function getDialogTitle(errorType, t) {
7573
7747
  switch (errorType) {
7574
7748
  case "mandatory":
7575
- return "Tasks Incomplete";
7749
+ return t("tasks_incomplete");
7576
7750
  case "optional_count":
7577
- return "More Tasks Required";
7751
+ return t("tasks_required");
7578
7752
  case "optional_points":
7579
- return "More Points Required";
7753
+ return t("points_required");
7580
7754
  default:
7581
- return "Validation Failed";
7755
+ return t("validation_failed");
7582
7756
  }
7583
7757
  }
7584
7758
  function getDialogIcon(errorType) {
@@ -7612,6 +7786,7 @@ function TaskValidationDialog({
7612
7786
  error,
7613
7787
  onClose
7614
7788
  }) {
7789
+ const { t } = useQuestLocale();
7615
7790
  return /* @__PURE__ */ jsx(
7616
7791
  Dialog,
7617
7792
  {
@@ -7621,32 +7796,29 @@ function TaskValidationDialog({
7621
7796
  onClose();
7622
7797
  }
7623
7798
  },
7624
- title: getDialogTitle(error == null ? void 0 : error.type),
7799
+ title: getDialogTitle(
7800
+ error == null ? void 0 : error.type,
7801
+ t
7802
+ ),
7625
7803
  showCloseButton: true,
7626
7804
  maxWidth: 400,
7627
7805
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-task-validation-dialog", children: [
7628
7806
  /* @__PURE__ */ jsx("div", { className: "taskon-task-validation-dialog-icon-wrap", children: getDialogIcon(error == null ? void 0 : error.type) }),
7629
- /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-message", children: (error == null ? void 0 : error.message) || "Please complete all required tasks before continuing." }),
7630
- (error == null ? void 0 : error.type) === "optional_count" && error.required !== void 0 && error.current !== void 0 && /* @__PURE__ */ jsxs("p", { className: "taskon-task-validation-dialog-progress", children: [
7631
- "Completed: ",
7632
- error.current,
7633
- " / ",
7634
- error.required,
7635
- " optional tasks"
7636
- ] }),
7637
- (error == null ? void 0 : error.type) === "optional_points" && error.required !== void 0 && error.current !== void 0 && /* @__PURE__ */ jsxs("p", { className: "taskon-task-validation-dialog-progress", children: [
7638
- "Earned: ",
7639
- error.current,
7640
- " / ",
7641
- error.required,
7642
- " points"
7643
- ] }),
7807
+ /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-message", children: (error == null ? void 0 : error.message) || t("please_complete_required_tasks_before_continuing") }),
7808
+ (error == null ? void 0 : error.type) === "optional_count" && error.required !== void 0 && error.current !== void 0 && /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-progress", children: t("completed_current_required_optional_tasks", {
7809
+ current: error.current,
7810
+ required: error.required
7811
+ }) }),
7812
+ (error == null ? void 0 : error.type) === "optional_points" && error.required !== void 0 && error.current !== void 0 && /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-progress", children: t("earned_current_required_points", {
7813
+ current: error.current,
7814
+ required: error.required
7815
+ }) }),
7644
7816
  /* @__PURE__ */ jsx(
7645
7817
  "button",
7646
7818
  {
7647
7819
  className: "taskon-task-validation-dialog-btn",
7648
7820
  onClick: onClose,
7649
- children: "OK"
7821
+ children: t("ok")
7650
7822
  }
7651
7823
  )
7652
7824
  ] })
@@ -7654,7 +7826,7 @@ function TaskValidationDialog({
7654
7826
  );
7655
7827
  }
7656
7828
  const CHAIN_TYPE_LABELS = {
7657
- evm: "EVM Chain",
7829
+ evm: "evm_chain",
7658
7830
  btc: "Bitcoin",
7659
7831
  starknet: "Starknet",
7660
7832
  solana: "Solana",
@@ -7666,6 +7838,7 @@ const CHAIN_TYPE_LABELS = {
7666
7838
  ton: "TON"
7667
7839
  };
7668
7840
  function BindItem({ chainType, isBinding, isBound, onBind }) {
7841
+ const { t } = useQuestLocale();
7669
7842
  const label = CHAIN_TYPE_LABELS[chainType.toLowerCase()] || chainType;
7670
7843
  return /* @__PURE__ */ jsxs("div", { className: `taskon-reward-bind-item ${isBound ? "taskon-reward-bind-item--bound" : ""}`, children: [
7671
7844
  /* @__PURE__ */ jsx("span", { className: "taskon-reward-bind-item-label", children: label }),
@@ -7680,7 +7853,7 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7680
7853
  strokeLinejoin: "round"
7681
7854
  }
7682
7855
  ) }),
7683
- "Bound"
7856
+ t("bound")
7684
7857
  ] }) : /* @__PURE__ */ jsx(
7685
7858
  "button",
7686
7859
  {
@@ -7700,8 +7873,8 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7700
7873
  strokeDasharray: "31.4 31.4"
7701
7874
  }
7702
7875
  ) }),
7703
- "Binding..."
7704
- ] }) : "Bind"
7876
+ t("binding")
7877
+ ] }) : t("bind")
7705
7878
  }
7706
7879
  )
7707
7880
  ] });
@@ -7715,6 +7888,7 @@ function RewardBindDialog({
7715
7888
  onAllBind,
7716
7889
  onBindChain
7717
7890
  }) {
7891
+ const { t } = useQuestLocale();
7718
7892
  const [notBoundChains, setNotBoundChains] = useState(chainTypes);
7719
7893
  const [bindingType, setBindingType] = useState(null);
7720
7894
  React__default.useEffect(() => {
@@ -7733,7 +7907,7 @@ function RewardBindDialog({
7733
7907
  try {
7734
7908
  const success = await onBindChain(chainType);
7735
7909
  if (success) {
7736
- setNotBoundChains((prev) => prev.filter((t) => t !== chainType));
7910
+ setNotBoundChains((prev) => prev.filter((t2) => t2 !== chainType));
7737
7911
  }
7738
7912
  } finally {
7739
7913
  setBindingType(null);
@@ -7746,7 +7920,7 @@ function RewardBindDialog({
7746
7920
  onClose();
7747
7921
  }
7748
7922
  }, [skippable, onSkip, onClose]);
7749
- const tipText = skippable ? "Please link the following wallet addresses to receive rewards. You can skip this step and link later before the campaign ends." : "Please link the following wallet addresses to receive rewards. This is required for FCFS rewards.";
7923
+ const tipText = skippable ? t("please_link_following_wallet_addresses_receive_rewards_skip_step") : t("please_link_following_wallet_addresses_receive_rewards_required_fcfs");
7750
7924
  return /* @__PURE__ */ jsx(
7751
7925
  Dialog,
7752
7926
  {
@@ -7756,7 +7930,7 @@ function RewardBindDialog({
7756
7930
  handleClose();
7757
7931
  }
7758
7932
  },
7759
- title: "Link Wallet Address",
7933
+ title: t("link_wallet_address"),
7760
7934
  showCloseButton: true,
7761
7935
  maxWidth: 480,
7762
7936
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-reward-bind-dialog", children: [
@@ -7776,7 +7950,7 @@ function RewardBindDialog({
7776
7950
  {
7777
7951
  className: "taskon-reward-bind-skip-btn",
7778
7952
  onClick: onSkip,
7779
- children: "Complete the Campaign"
7953
+ children: t("complete_campaign_2")
7780
7954
  }
7781
7955
  )
7782
7956
  ] })
@@ -7812,6 +7986,7 @@ function DiscordBindDialog({
7812
7986
  onLinkDiscord,
7813
7987
  onContinue
7814
7988
  }) {
7989
+ const { t } = useQuestLocale();
7815
7990
  return /* @__PURE__ */ jsx(
7816
7991
  Dialog,
7817
7992
  {
@@ -7821,19 +7996,23 @@ function DiscordBindDialog({
7821
7996
  onClose();
7822
7997
  }
7823
7998
  },
7824
- title: "Discord Account Not Linked",
7999
+ title: t("discord_account_linked"),
7825
8000
  showCloseButton: true,
7826
8001
  maxWidth: 440,
7827
8002
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog", children: [
7828
8003
  /* @__PURE__ */ jsx("div", { className: "taskon-discord-bind-dialog-icon-wrap", children: /* @__PURE__ */ jsx(DiscordIcon, {}) }),
7829
- /* @__PURE__ */ jsx("p", { className: "taskon-discord-bind-dialog-desc", children: "To receive the Discord Role reward, you need to link your Discord account. You can still complete the campaign without linking, but you won't be able to claim the Discord Role reward." }),
8004
+ /* @__PURE__ */ jsxs("p", { className: "taskon-discord-bind-dialog-desc", children: [
8005
+ t("receive_discord_role_reward_need_link_discord_account"),
8006
+ " ",
8007
+ t("complete_campaign_without_linking_won_t_able_claim_discord")
8008
+ ] }),
7830
8009
  /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog-buttons", children: [
7831
8010
  /* @__PURE__ */ jsx(
7832
8011
  "button",
7833
8012
  {
7834
8013
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--secondary",
7835
8014
  onClick: onLinkDiscord,
7836
- children: "Link Discord Account"
8015
+ children: t("link_discord_account")
7837
8016
  }
7838
8017
  ),
7839
8018
  /* @__PURE__ */ jsx(
@@ -7841,7 +8020,7 @@ function DiscordBindDialog({
7841
8020
  {
7842
8021
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--primary",
7843
8022
  onClick: onContinue,
7844
- children: "Complete Campaign"
8023
+ children: t("complete_campaign")
7845
8024
  }
7846
8025
  )
7847
8026
  ] })
@@ -7915,11 +8094,13 @@ function ChevronRightIcon() {
7915
8094
  function WinnersRow({
7916
8095
  campaignId,
7917
8096
  winnerRewards,
7918
- pointsName = "Points",
8097
+ pointsName,
7919
8098
  onVisibleChange,
7920
8099
  className
7921
8100
  }) {
8101
+ const { t } = useQuestLocale();
7922
8102
  const { client } = useTaskOnContext();
8103
+ const resolvedPointsName = pointsName || t("points");
7923
8104
  const api = useMemo(() => {
7924
8105
  if (!client) return null;
7925
8106
  return createQuestApi(client);
@@ -7955,9 +8136,9 @@ function WinnersRow({
7955
8136
  type: "button",
7956
8137
  className: `taskon-quest-winners-row ${className || ""}`,
7957
8138
  onClick: () => setIsModalOpen(true),
7958
- "aria-label": "View winners list",
8139
+ "aria-label": t("view_winners_list"),
7959
8140
  children: [
7960
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: "Winners" }),
8141
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: t("winners") }),
7961
8142
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-count", children: total.toLocaleString() }),
7962
8143
  /* @__PURE__ */ jsx(ChevronRightIcon, {})
7963
8144
  ]
@@ -7970,7 +8151,7 @@ function WinnersRow({
7970
8151
  onClose: () => setIsModalOpen(false),
7971
8152
  campaignId,
7972
8153
  winnerRewards,
7973
- pointsName
8154
+ pointsName: resolvedPointsName
7974
8155
  }
7975
8156
  )
7976
8157
  ] });
@@ -8024,23 +8205,10 @@ function ArrowUpRightIcon() {
8024
8205
  }
8025
8206
  function formatDateShort(timestamp) {
8026
8207
  const date = new Date(timestamp);
8027
- const months = [
8028
- "Jan",
8029
- "Feb",
8030
- "Mar",
8031
- "Apr",
8032
- "May",
8033
- "Jun",
8034
- "Jul",
8035
- "Aug",
8036
- "Sep",
8037
- "Oct",
8038
- "Nov",
8039
- "Dec"
8040
- ];
8041
- const month = months[date.getMonth()];
8042
- const day = String(date.getDate()).padStart(2, "0");
8043
- return `${month} ${day}`;
8208
+ return new Intl.DateTimeFormat("en-US", {
8209
+ month: "short",
8210
+ day: "2-digit"
8211
+ }).format(date);
8044
8212
  }
8045
8213
  function WinnersStatus({
8046
8214
  campaign,
@@ -8051,6 +8219,7 @@ function WinnersStatus({
8051
8219
  className = ""
8052
8220
  }) {
8053
8221
  var _a, _b, _c;
8222
+ const { t } = useQuestLocale();
8054
8223
  const [hasWinners, setHasWinners] = useState(false);
8055
8224
  const endTime = campaign.end_time;
8056
8225
  const isWaitingReviewPow = useMemo(() => {
@@ -8083,9 +8252,9 @@ function WinnersStatus({
8083
8252
  if (discordLink) return discordLink;
8084
8253
  return void 0;
8085
8254
  }, [discordLink]);
8086
- const handleWinnersVisibleChange = (visible) => {
8255
+ const handleWinnersVisibleChange = useCallback((visible) => {
8087
8256
  setHasWinners(visible);
8088
- };
8257
+ }, []);
8089
8258
  return /* @__PURE__ */ jsxs("div", { className: `taskon-winners ${className}`, children: [
8090
8259
  isWaitingReviewPow && (powReviewLink ? /* @__PURE__ */ jsxs(
8091
8260
  "a",
@@ -8096,29 +8265,35 @@ function WinnersStatus({
8096
8265
  className: "taskon-winners-alert",
8097
8266
  children: [
8098
8267
  /* @__PURE__ */ jsx(TimerIcon, {}),
8099
- /* @__PURE__ */ jsxs("span", { className: "taskon-winners-alert-text", children: [
8100
- "Waiting for",
8101
- " ",
8102
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name }),
8103
- " ",
8104
- "Reviewed All Tasks"
8105
- ] }),
8268
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: /* @__PURE__ */ jsx(
8269
+ I18nT,
8270
+ {
8271
+ t,
8272
+ i18nKey: "waiting_community_reviewed_tasks",
8273
+ components: {
8274
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name })
8275
+ }
8276
+ }
8277
+ ) }),
8106
8278
  /* @__PURE__ */ jsx(ArrowUpRightIcon, {})
8107
8279
  ]
8108
8280
  }
8109
8281
  ) : /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8110
8282
  /* @__PURE__ */ jsx(TimerIcon, {}),
8111
- /* @__PURE__ */ jsxs("span", { className: "taskon-winners-alert-text", children: [
8112
- "Waiting for",
8113
- " ",
8114
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name }),
8115
- " ",
8116
- "Reviewed All Tasks"
8117
- ] })
8283
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: /* @__PURE__ */ jsx(
8284
+ I18nT,
8285
+ {
8286
+ t,
8287
+ i18nKey: "waiting_community_reviewed_tasks",
8288
+ components: {
8289
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name })
8290
+ }
8291
+ }
8292
+ ) })
8118
8293
  ] })),
8119
8294
  !isWaitingReviewPow && isDrawingWinner && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8120
8295
  /* @__PURE__ */ jsx(TimerIcon, {}),
8121
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: "System is Drawing Winners..." })
8296
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: t("system_drawing_winners") })
8122
8297
  ] }),
8123
8298
  /* @__PURE__ */ jsxs(
8124
8299
  "div",
@@ -8127,22 +8302,26 @@ function WinnersStatus({
8127
8302
  style: { display: isShowContent ? "block" : "none" },
8128
8303
  children: [
8129
8304
  isWaitingReviewPow && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-pow-info", children: [
8130
- "*This quest includes Proof of Work (POW) tasks, which",
8131
- " ",
8132
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-community", children: campaign.community_name }),
8133
- " ",
8134
- "will review. Winners will be selected",
8135
- " ",
8136
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-only", children: "ONLY" }),
8137
- " after all tasks have been reviewed."
8305
+ "*",
8306
+ /* @__PURE__ */ jsx(
8307
+ I18nT,
8308
+ {
8309
+ t,
8310
+ i18nKey: "quest_includes_proof_work_pow_tasks_which_community_review",
8311
+ components: {
8312
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-community", children: campaign.community_name }),
8313
+ only: /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-only", children: t("only") })
8314
+ }
8315
+ }
8316
+ )
8138
8317
  ] }),
8139
8318
  /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card", children: [
8140
8319
  isWaitingReviewPow && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card-row", children: [
8141
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: "System will automatically select winners in" }),
8320
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: t("system_automatically_select_winners") }),
8142
8321
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value", children: reviewDeadlineText })
8143
8322
  ] }),
8144
8323
  isDrawingWinner && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card-row", children: [
8145
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: "All winners are to be announced by" }),
8324
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: t("winners_announced") }),
8146
8325
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value--primary", children: drawWinnersDeadlineText })
8147
8326
  ] }),
8148
8327
  /* @__PURE__ */ jsx(
@@ -8183,34 +8362,40 @@ function mergeQuestConfig(props, cloud) {
8183
8362
  rewardRedirectUrl: props.rewardRedirectUrl ?? (cloud == null ? void 0 : cloud.rewardRedirectUrl) ?? ""
8184
8363
  };
8185
8364
  }
8186
- const QUEST_NFT_CLAIM_MESSAGES = {
8187
- claimDialog: {
8188
- claimNft: "Claim NFT",
8189
- claimingNft: "Claiming NFT...",
8190
- claimConnectingWallet: "Connecting wallet...",
8191
- claimSwitchingNetwork: "Switching network...",
8192
- claimGettingSignature: "Getting signature...",
8193
- claimConfirmInWallet: "Please confirm in your wallet",
8194
- claimTransactionPending: "Transaction pending...",
8195
- claimSuccess: "Claim successful!",
8196
- claimFailed: "Claim failed",
8197
- claimCanceled: "Transaction was rejected by user.",
8198
- viewOnExplorer: "View on Explorer",
8199
- retry: "Retry",
8200
- close: "Close"
8201
- },
8202
- pendingDialog: {
8203
- pendingTransaction: "Pending Transaction",
8204
- claimPendingTitle: "You have already claimed this NFT, please wait for this transaction to be confirmed.",
8205
- claimPendingCheckExplorer: "You can check this transaction on explorer:",
8206
- claimPendingHashLabel: "Transaction hash:",
8207
- claimPendingClaimAgainWarn: '"Claim Again" will send a new transaction it is only recommended when you are sure there is something wrong with the current transaction.',
8208
- claimPendingReceiveAddressNoChange: "This receive address can’t be changed:",
8209
- claimAgain: "Claim Again",
8210
- continueWaiting: "Continue Waiting"
8211
- }
8212
- };
8213
- function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd) {
8365
+ function createQuestNftClaimMessages(t) {
8366
+ return {
8367
+ claimDialog: {
8368
+ claimNft: t("claim_nft"),
8369
+ claimingNft: t("claiming_nft"),
8370
+ claimConnectingWallet: t("connecting_wallet"),
8371
+ claimSwitchingNetwork: t("switching_network"),
8372
+ claimGettingSignature: t("getting_signature"),
8373
+ claimConfirmInWallet: t("please_confirm_wallet"),
8374
+ claimTransactionPending: t("transaction_pending"),
8375
+ claimSuccess: t("claim_successful"),
8376
+ claimFailed: t("claim_failed"),
8377
+ claimCanceled: t("transaction_rejected_user"),
8378
+ viewOnExplorer: t("view_explorer"),
8379
+ retry: t("retry"),
8380
+ close: t("close")
8381
+ },
8382
+ pendingDialog: {
8383
+ pendingTransaction: t("pending_transaction"),
8384
+ claimPendingTitle: t(
8385
+ "already_claimed_nft_please_wait_transaction_confirmed"
8386
+ ),
8387
+ claimPendingCheckExplorer: t("check_transaction_explorer"),
8388
+ claimPendingHashLabel: t("transaction_hash"),
8389
+ claimPendingClaimAgainWarn: t(
8390
+ "claim_again_send_new_transaction_recommended_when_sure_there"
8391
+ ),
8392
+ claimPendingReceiveAddressNoChange: t("receive_address_t_changed"),
8393
+ claimAgain: t("claim_again"),
8394
+ continueWaiting: t("continue_waiting")
8395
+ }
8396
+ };
8397
+ }
8398
+ function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd, labels) {
8214
8399
  const now = Date.now();
8215
8400
  const startMs = startTime;
8216
8401
  const endMs = endTime;
@@ -8221,13 +8406,13 @@ function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd) {
8221
8406
  let label;
8222
8407
  if (!isStarted) {
8223
8408
  status = "upcoming";
8224
- label = "Upcoming";
8409
+ label = labels.upcoming;
8225
8410
  } else if (isEnded) {
8226
8411
  status = "ended";
8227
- label = "Ended";
8412
+ label = labels.ended;
8228
8413
  } else {
8229
8414
  status = "ongoing";
8230
- label = "Ongoing";
8415
+ label = labels.ongoing;
8231
8416
  }
8232
8417
  return {
8233
8418
  status,
@@ -8247,6 +8432,7 @@ function getHasRanking(winnerRewards) {
8247
8432
  }
8248
8433
  function QuestWidget(props) {
8249
8434
  const { widgetId, themeMode } = props;
8435
+ const { t } = useQuestLocale();
8250
8436
  const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
8251
8437
  const mergedConfig = useMemo(() => {
8252
8438
  return mergeQuestConfig(
@@ -8275,7 +8461,9 @@ function QuestWidget(props) {
8275
8461
  cloudTheme,
8276
8462
  themeMode,
8277
8463
  className: "taskon-quest",
8278
- errorMessage: configError ?? (!mergedConfig.campaignId ? "Campaign ID is required. Please provide campaignId via props or widgetId." : void 0),
8464
+ errorMessage: configError ?? (!mergedConfig.campaignId ? t(
8465
+ "campaign_id_required_please_provide_campaignid_via_props_widgetid"
8466
+ ) : void 0),
8279
8467
  children: /* @__PURE__ */ jsx(
8280
8468
  QuestWidgetInner,
8281
8469
  {
@@ -8298,6 +8486,7 @@ function QuestWidget(props) {
8298
8486
  }
8299
8487
  function QuestWidgetInner(props) {
8300
8488
  var _a, _b, _c, _d, _e;
8489
+ const { t } = useQuestLocale();
8301
8490
  const {
8302
8491
  campaignId,
8303
8492
  channel,
@@ -8323,8 +8512,20 @@ function QuestWidgetInner(props) {
8323
8512
  rewardDisplayMode,
8324
8513
  rewardRedirectUrl
8325
8514
  } = props;
8326
- const { client, chains, isLoggedIn, userInfo, requestLogin, communityInfo } = useTaskOnContext();
8515
+ const {
8516
+ client,
8517
+ chains,
8518
+ isLoggedIn,
8519
+ userInfo,
8520
+ userToken,
8521
+ requestLogin,
8522
+ communityInfo
8523
+ } = useTaskOnContext();
8327
8524
  const { toast } = useToast();
8525
+ const questNftClaimMessages = useMemo(
8526
+ () => createQuestNftClaimMessages(t),
8527
+ [t]
8528
+ );
8328
8529
  const chainMap = useMemo(() => {
8329
8530
  if (!chains || chains.length === 0) return {};
8330
8531
  return Object.fromEntries(
@@ -8371,7 +8572,8 @@ function QuestWidgetInner(props) {
8371
8572
  campaignId,
8372
8573
  channel,
8373
8574
  kolHandle,
8374
- enabled: !isPreview
8575
+ enabled: !isPreview,
8576
+ authToken: userToken
8375
8577
  });
8376
8578
  const {
8377
8579
  data: questStatus,
@@ -8392,13 +8594,13 @@ function QuestWidgetInner(props) {
8392
8594
  } = useNftClaimFlow({
8393
8595
  campaignId,
8394
8596
  targetType: (campaign == null ? void 0 : campaign.campaign_type) === CampaignType.Event ? "event" : "campaign",
8395
- messages: QUEST_NFT_CLAIM_MESSAGES,
8597
+ messages: questNftClaimMessages,
8396
8598
  onClaimSuccess: async () => {
8397
8599
  refetchUserStatus();
8398
8600
  refetchStatus();
8399
8601
  },
8400
8602
  onClaimError: (error2) => {
8401
- toast.error(error2.message || "Failed to claim NFT");
8603
+ toast.error(error2.message || t("failed_claim_nft"));
8402
8604
  },
8403
8605
  onWalletError: (errorMessage) => {
8404
8606
  toast.error(errorMessage);
@@ -8443,9 +8645,14 @@ function QuestWidgetInner(props) {
8443
8645
  campaign.campaign_status,
8444
8646
  campaign.start_time,
8445
8647
  campaign.end_time,
8446
- campaign.is_end
8648
+ campaign.is_end,
8649
+ {
8650
+ upcoming: t("upcoming"),
8651
+ ended: t("ended"),
8652
+ ongoing: t("ongoing")
8653
+ }
8447
8654
  );
8448
- }, [campaign]);
8655
+ }, [campaign, t]);
8449
8656
  const isTaskDisabled = useMemo(() => {
8450
8657
  if (!statusDisplay) return true;
8451
8658
  return !statusDisplay.isActive;
@@ -8468,6 +8675,17 @@ function QuestWidgetInner(props) {
8468
8675
  const [blindBoxEmptyReward, setBlindBoxEmptyReward] = useState();
8469
8676
  const [blindBoxTokenPrice, setBlindBoxTokenPrice] = useState();
8470
8677
  const [isClaimingBlindBox, setIsClaimingBlindBox] = useState(false);
8678
+ const [hasCompletedBlindBoxClaim, setHasCompletedBlindBoxClaim] = useState(false);
8679
+ const closeBlindBoxModal = useCallback(() => {
8680
+ setBlindBoxDialogVisible(false);
8681
+ setBlindBoxRewardVisible(false);
8682
+ }, []);
8683
+ const handleBlindBoxDialogOpenChange = useCallback((open) => {
8684
+ setBlindBoxDialogVisible(open);
8685
+ if (!open) {
8686
+ setBlindBoxRewardVisible(false);
8687
+ }
8688
+ }, []);
8471
8689
  const buildBlindBoxRewardValue = useCallback(
8472
8690
  (amount) => {
8473
8691
  if (!blindBoxTokenReward) {
@@ -8502,8 +8720,8 @@ function QuestWidgetInner(props) {
8502
8720
  [blindBoxTokenReward]
8503
8721
  );
8504
8722
  const handleOpenBlindBox = useCallback(() => {
8505
- setBlindBoxRewardVisible(false);
8506
8723
  setBlindBoxDialogVisible(true);
8724
+ setBlindBoxRewardVisible(false);
8507
8725
  }, []);
8508
8726
  const handleBlindBoxOpened = useCallback(async () => {
8509
8727
  var _a2;
@@ -8526,11 +8744,11 @@ function QuestWidgetInner(props) {
8526
8744
  }
8527
8745
  refetchUserStatus();
8528
8746
  refetchStatus();
8529
- setBlindBoxDialogVisible(false);
8747
+ setHasCompletedBlindBoxClaim(true);
8530
8748
  setBlindBoxRewardVisible(true);
8531
8749
  } catch (error2) {
8532
8750
  console.error("Claim blind box error:", error2);
8533
- const errorMessage = error2 instanceof Error ? error2.message : "Network error, please try again";
8751
+ const errorMessage = error2 instanceof Error ? error2.message : t("network_error_please_try_again");
8534
8752
  toast.error(errorMessage);
8535
8753
  (_a2 = blindBoxDialogRef.current) == null ? void 0 : _a2.resetToUnopened();
8536
8754
  } finally {
@@ -8543,18 +8761,23 @@ function QuestWidgetInner(props) {
8543
8761
  buildBlindBoxRewardValue,
8544
8762
  refetchUserStatus,
8545
8763
  refetchStatus,
8764
+ t,
8546
8765
  toast
8547
8766
  ]);
8548
8767
  useEffect(() => {
8549
- if (userBlindBoxStatus === "wait-claim" && !isBlindBoxDialogVisible && !isBlindBoxRewardVisible) {
8768
+ if (userBlindBoxStatus === "wait-claim" && !isBlindBoxDialogVisible && !isBlindBoxRewardVisible && !hasCompletedBlindBoxClaim) {
8550
8769
  handleOpenBlindBox();
8551
8770
  }
8552
8771
  }, [
8553
8772
  userBlindBoxStatus,
8554
8773
  isBlindBoxDialogVisible,
8555
8774
  isBlindBoxRewardVisible,
8775
+ hasCompletedBlindBoxClaim,
8556
8776
  handleOpenBlindBox
8557
8777
  ]);
8778
+ useEffect(() => {
8779
+ setHasCompletedBlindBoxClaim(false);
8780
+ }, [campaignId]);
8558
8781
  const isLoading = isDetailLoading || isUserStatusLoading || isStatusLoading;
8559
8782
  const error = detailError || userStatusError || statusError;
8560
8783
  useEffect(() => {
@@ -8575,7 +8798,7 @@ function QuestWidgetInner(props) {
8575
8798
  const handleTaskCompleted = (taskId, result) => {
8576
8799
  var _a2;
8577
8800
  const successTaskIds = (result == null ? void 0 : result.success_tasks) ?? [taskId];
8578
- const task = (_a2 = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _a2.find((t) => t.id === taskId);
8801
+ const task = (_a2 = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _a2.find((t2) => t2.id === taskId);
8579
8802
  const isSwapDex = (task == null ? void 0 : task.template_id) === "SwapDexContractInteractive";
8580
8803
  const isSuccess = successTaskIds.includes(taskId);
8581
8804
  if (isSuccess) {
@@ -8737,13 +8960,13 @@ function QuestWidgetInner(props) {
8737
8960
  refetchUserStatus();
8738
8961
  refetchStatus();
8739
8962
  },
8740
- children: "Retry"
8963
+ children: t("retry")
8741
8964
  }
8742
8965
  )
8743
8966
  ] }) });
8744
8967
  }
8745
8968
  if (!campaign) {
8746
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-empty", children: "Quest not found" }) });
8969
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-empty", children: t("quest_found") }) });
8747
8970
  }
8748
8971
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest", children: [
8749
8972
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-layout", children: [
@@ -8771,13 +8994,14 @@ function QuestWidgetInner(props) {
8771
8994
  ),
8772
8995
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-content-divider" }),
8773
8996
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-tasks", children: [
8774
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-tasks-header", children: /* @__PURE__ */ jsx("h2", { className: "taskon-quest-tasks-title", children: "Task" }) }),
8997
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-tasks-header", children: /* @__PURE__ */ jsx("h2", { className: "taskon-quest-tasks-title", children: t("task") }) }),
8775
8998
  mandatoryTasks.length > 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx(
8776
8999
  CompletedCount,
8777
9000
  {
8778
9001
  className: "taskon-quest-tasks-progress",
8779
9002
  current: mandatoryCompleted + optionalCompleted,
8780
- total: mandatoryTotal + optionalTotal
9003
+ total: mandatoryTotal + optionalTotal,
9004
+ completedLabel: t("completed")
8781
9005
  }
8782
9006
  ),
8783
9007
  /* @__PURE__ */ jsx(
@@ -8832,7 +9056,7 @@ function QuestWidgetInner(props) {
8832
9056
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-divider" }),
8833
9057
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-sidebar", children: [
8834
9058
  (statusDisplay == null ? void 0 : statusDisplay.isEnded) && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winners-section", children: [
8835
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-winners-section-title", children: "Winners" }),
9059
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-winners-section-title", children: t("winners") }),
8836
9060
  /* @__PURE__ */ jsx(
8837
9061
  WinnersStatus,
8838
9062
  {
@@ -8845,7 +9069,7 @@ function QuestWidgetInner(props) {
8845
9069
  )
8846
9070
  ] }),
8847
9071
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-section", children: [
8848
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-rewards-section-title", children: "Quest Rewards" }),
9072
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-rewards-section-title", children: t("quest_rewards") }),
8849
9073
  /* @__PURE__ */ jsx(
8850
9074
  QuestRewards,
8851
9075
  {
@@ -8869,7 +9093,7 @@ function QuestWidgetInner(props) {
8869
9093
  )
8870
9094
  ] }),
8871
9095
  hasEligibility && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-eligs-section", children: [
8872
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-eligs-section-header", children: /* @__PURE__ */ jsx("h3", { className: "taskon-quest-eligs-section-title", children: "Quest Eligibility" }) }),
9096
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-eligs-section-header", children: /* @__PURE__ */ jsx("h3", { className: "taskon-quest-eligs-section-title", children: t("quest_eligibility") }) }),
8873
9097
  /* @__PURE__ */ jsx(
8874
9098
  EligibilityInfo,
8875
9099
  {
@@ -8898,38 +9122,27 @@ function QuestWidgetInner(props) {
8898
9122
  Dialog,
8899
9123
  {
8900
9124
  open: isBlindBoxDialogVisible,
8901
- onOpenChange: setBlindBoxDialogVisible,
8902
- title: "Open Blind Box",
8903
- showCloseButton: false,
8904
- closeOnOverlayClick: false,
8905
- closeOnEscapeKey: false,
8906
- contentClassName: "taskon-quest-blindbox-dialog-wrapper",
8907
- children: /* @__PURE__ */ jsx(
8908
- BlindBoxDialog,
8909
- {
8910
- ref: blindBoxDialogRef,
8911
- onClose: () => setBlindBoxDialogVisible(false),
8912
- onOpened: handleBlindBoxOpened
8913
- }
8914
- )
8915
- }
8916
- ),
8917
- /* @__PURE__ */ jsx(
8918
- Dialog,
8919
- {
8920
- open: isBlindBoxRewardVisible,
8921
- onOpenChange: setBlindBoxRewardVisible,
8922
- title: "Blind Box Reward",
8923
- showCloseButton: true,
8924
- contentClassName: "taskon-quest-blindbox-reward-wrapper",
8925
- children: /* @__PURE__ */ jsx(
9125
+ onOpenChange: handleBlindBoxDialogOpenChange,
9126
+ title: isBlindBoxRewardVisible ? t("blind_box_reward") : t("open_blind_box"),
9127
+ showCloseButton: isBlindBoxRewardVisible,
9128
+ closeOnOverlayClick: isBlindBoxRewardVisible,
9129
+ closeOnEscapeKey: isBlindBoxRewardVisible,
9130
+ contentClassName: `taskon-quest-blindbox-dialog-wrapper${isBlindBoxRewardVisible ? " taskon-quest-blindbox-dialog-wrapper--result" : ""}`,
9131
+ children: isBlindBoxRewardVisible ? /* @__PURE__ */ jsx(
8926
9132
  BlindBoxRewardDialog,
8927
9133
  {
8928
9134
  rewards: blindBoxWinnerRewards,
8929
9135
  emptyReward: blindBoxEmptyReward,
8930
9136
  tokenPrice: blindBoxTokenPrice,
8931
9137
  loading: isClaimingBlindBox,
8932
- onClose: () => setBlindBoxRewardVisible(false)
9138
+ onClose: closeBlindBoxModal
9139
+ }
9140
+ ) : /* @__PURE__ */ jsx(
9141
+ BlindBoxDialog,
9142
+ {
9143
+ ref: blindBoxDialogRef,
9144
+ onClose: closeBlindBoxModal,
9145
+ onOpened: handleBlindBoxOpened
8933
9146
  }
8934
9147
  )
8935
9148
  }
@@ -9023,8 +9236,5 @@ function QuestWidgetInner(props) {
9023
9236
  ] });
9024
9237
  }
9025
9238
  export {
9026
- QuestWidget as Q,
9027
- useQuestUserStatus as a,
9028
- useQuestStatus as b,
9029
- useQuestDetail as u
9239
+ QuestWidget as Q
9030
9240
  };