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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/CommunityTaskList.css +110 -110
  2. package/dist/EligibilityInfo.css +69 -69
  3. package/dist/Quest.css +241 -241
  4. package/dist/chunks/{CommunityTaskList-C9Gv8KOF.js → CommunityTaskList-CrMvOB8w.js} +725 -441
  5. package/dist/chunks/{EligibilityInfo-D-Fuy9GE.js → EligibilityInfo-Beww12QX.js} +1569 -597
  6. package/dist/chunks/{LeaderboardWidget-BV2D2q1N.js → LeaderboardWidget-DwuSpVl0.js} +2 -2
  7. package/dist/chunks/{PageBuilder-DQoU4Mwf.js → PageBuilder-DsX6Tv0N.js} +5 -5
  8. package/dist/chunks/{Quest-B5NyVr3o.js → Quest-CuD2LElS.js} +661 -473
  9. package/dist/chunks/{TaskOnProvider-93UxARFo.js → TaskOnProvider-xUeP2Nro.js} +78 -65
  10. package/dist/chunks/{ThemeProvider-CPI_roeh.js → ThemeProvider-Bt4UZ33y.js} +30 -6
  11. package/dist/chunks/{UserCenterWidget-BRtigY_S.js → UserCenterWidget-CB0hnj-L.js} +67 -30
  12. package/dist/chunks/{UserCenterWidget-cADBSVg7.js → UserCenterWidget-CvU6K4AC.js} +2 -2
  13. package/dist/chunks/communitytask-es-1zawvXEX.js +311 -0
  14. package/dist/chunks/communitytask-ja-CmW6nP-L.js +311 -0
  15. package/dist/chunks/communitytask-ko-BD0hzQSi.js +311 -0
  16. package/dist/chunks/communitytask-ru-DhySaZL8.js +311 -0
  17. package/dist/chunks/createLocaleLoader-BameiEhU.js +65 -0
  18. package/dist/chunks/{dynamic-import-helper-DwXlQC0S.js → dynamic-import-helper-WmIF58Sb.js} +1 -1
  19. package/dist/chunks/quest-es-D-b5xcme.js +948 -0
  20. package/dist/chunks/quest-ja-Dxd2vqBF.js +948 -0
  21. package/dist/chunks/quest-ko-CSmRWgK_.js +948 -0
  22. package/dist/chunks/quest-ru-CkEKv1_F.js +948 -0
  23. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  24. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  25. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  26. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  27. package/dist/community-task.js +1 -1
  28. package/dist/core.d.ts +17 -5
  29. package/dist/core.js +8 -7
  30. package/dist/index.d.ts +56 -5
  31. package/dist/index.js +18 -16
  32. package/dist/leaderboard.js +2 -2
  33. package/dist/page-builder.js +1 -1
  34. package/dist/quest.d.ts +682 -0
  35. package/dist/quest.js +3 -1
  36. package/dist/user-center.d.ts +3 -1
  37. package/dist/user-center.js +5 -5
  38. package/package.json +4 -1
@@ -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 { t as useTaskOnPortalContainer, d as useTaskOnContext } from "./ThemeProvider-Bt4UZ33y.js";
5
+ import { f as useTaskWidgetLocale, d as TaskItem, u as useQuestLocale, I as I18nT, g as EligibilityList, h as getDefaultExportFromCjs, s as sanitizeHtml, R as RewardModuleDialog, C as ConfirmNoticeDialog, a as useBindWallet, c as useNftClaimFlow, E as EligibilityInfo, B as BlindBoxDialog } from "./EligibilityInfo-Beww12QX.js";
6
+ import { D as Dialog, B as Button, T as Table, P as Pagination, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-WmIF58Sb.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, o as Trigger, p as Portal, q as Content2, v as InfoIcon, r as Arrow2, s as TipPopover, g as useBindSocialAccount } from "./UserCenterWidget-CvU6K4AC.js";
9
9
  import '../Quest.css';function ButtonTabs({
10
10
  items,
11
11
  activeKey,
@@ -209,6 +209,8 @@ function TaskList({
209
209
  onCooldownComplete,
210
210
  className
211
211
  }) {
212
+ const { t } = useTaskWidgetLocale();
213
+ const countPlaceholder = "__COUNT__";
212
214
  const completionStatus = useCompletionStatus(
213
215
  mandatoryTasks,
214
216
  optionalTasks,
@@ -218,7 +220,7 @@ function TaskList({
218
220
  return /* @__PURE__ */ jsxs("div", { className: `taskon-task-list ${className || ""}`, children: [
219
221
  mandatoryTasks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section taskon-task-list-section--mandatory", children: [
220
222
  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" }) }),
223
+ /* @__PURE__ */ jsx("div", { className: "taskon-task-list-section-label", children: /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: t("mandatory_tasks") }) }),
222
224
  /* @__PURE__ */ jsx(
223
225
  CompletedCount,
224
226
  {
@@ -251,21 +253,29 @@ function TaskList({
251
253
  optionalTasks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section taskon-task-list-section--optional", children: [
252
254
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-list-section-header", children: [
253
255
  /* @__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
- ] })
256
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-title", children: t("optional_tasks") }),
257
+ minOptionalTasks !== void 0 && minOptionalTasks > 0 && /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint", children: (() => {
258
+ const text = t("min_required", {
259
+ count: countPlaceholder
260
+ });
261
+ const [before, after] = text.split(countPlaceholder);
262
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
263
+ before,
264
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalTasks }),
265
+ after
266
+ ] });
267
+ })() }),
268
+ !minOptionalTasks && minOptionalPoints !== void 0 && minOptionalPoints > 0 && /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint", children: (() => {
269
+ const text = t("min_points_required", {
270
+ count: countPlaceholder
271
+ });
272
+ const [before, after] = text.split(countPlaceholder);
273
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
274
+ before,
275
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-list-section-hint-em", children: minOptionalPoints }),
276
+ after
277
+ ] });
278
+ })() })
269
279
  ] }),
270
280
  /* @__PURE__ */ jsx(
271
281
  CompletedCount,
@@ -296,7 +306,7 @@ function TaskList({
296
306
  task.id
297
307
  )) })
298
308
  ] }),
299
- mandatoryTasks.length === 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-task-list-empty", children: /* @__PURE__ */ jsx("p", { children: "No tasks available" }) })
309
+ mandatoryTasks.length === 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx("div", { className: "taskon-task-list-empty", children: /* @__PURE__ */ jsx("p", { children: t("no_tasks_available") }) })
300
310
  ] });
301
311
  }
302
312
  function formatAmount(amount) {
@@ -327,12 +337,13 @@ function RewardCard$2({
327
337
  reward,
328
338
  tokenPrice
329
339
  }) {
340
+ const { t } = useQuestLocale();
330
341
  if (reward.reward_type !== RewardType.Token) {
331
342
  return null;
332
343
  }
333
344
  const tokenValue = reward.reward_value;
334
345
  const amount = tokenValue.amount || "0";
335
- const tokenName = tokenValue.token_name || "Token";
346
+ const tokenName = tokenValue.token_name || t("token_name");
336
347
  const tokenLogo = tokenValue.token_logo;
337
348
  const usdValue = formatUsdValue(amount, tokenPrice);
338
349
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-blindbox-reward-card", children: [
@@ -354,10 +365,11 @@ function RewardCard$2({
354
365
  ] });
355
366
  }
356
367
  function BlindBoxRewardDialog(props) {
368
+ const { t } = useQuestLocale();
357
369
  const { rewards, emptyReward, tokenPrice, loading, onClose } = props;
358
370
  const hasRewards = rewards.length > 0;
359
- const title = hasRewards ? "Congratulations!" : "Oops! Better Luck Next Time!";
360
- const subtitle = hasRewards ? "You Have Won" : "Rewards Missed";
371
+ const title = hasRewards ? t("congratulations") : t("oops_better_luck_next_time");
372
+ const subtitle = hasRewards ? t("won") : t("rewards_missed");
361
373
  const displayRewards = useMemo(() => {
362
374
  if (hasRewards) {
363
375
  return rewards;
@@ -381,7 +393,7 @@ function BlindBoxRewardDialog(props) {
381
393
  className: "taskon-quest-blindbox-reward-btn",
382
394
  disabled: loading,
383
395
  onClick: onClose,
384
- children: loading ? "Loading..." : "Back"
396
+ children: loading ? t("loading") : t("close")
385
397
  }
386
398
  ) })
387
399
  ] });
@@ -463,6 +475,7 @@ function EligsNotPassDialog({
463
475
  onRefresh,
464
476
  isRefreshing = false
465
477
  }) {
478
+ const { t } = useQuestLocale();
466
479
  const [isExpanded, setIsExpanded] = useState(true);
467
480
  const [currentDetails, setCurrentDetails] = useState(details);
468
481
  const isEligible = useMemo(() => {
@@ -479,7 +492,7 @@ function EligsNotPassDialog({
479
492
  const eligibleDetails = useMemo(() => {
480
493
  return currentDetails.map((d) => d.is_pass);
481
494
  }, [currentDetails]);
482
- const expressLabel = eligibilityExpress === "and" ? "all" : "any";
495
+ const expressLabel = eligibilityExpress === "and" ? t("all") : t("any");
483
496
  const handleRefresh = async () => {
484
497
  if (onRefresh) {
485
498
  await onRefresh();
@@ -493,7 +506,7 @@ function EligsNotPassDialog({
493
506
  {
494
507
  open,
495
508
  onOpenChange: (isOpen) => !isOpen && onClose(),
496
- title: isEligible ? "Congratulations" : "Oops",
509
+ title: isEligible ? t("congratulations") : t("oops"),
497
510
  showCloseButton: true,
498
511
  maxWidth: 400,
499
512
  contentClassName: "taskon-eligs-dialog",
@@ -507,17 +520,22 @@ function EligsNotPassDialog({
507
520
  className: "taskon-eligs-dialog-icon"
508
521
  }
509
522
  ),
510
- /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-dialog-title", children: isEligible ? "Congratulations" : "Oops" })
523
+ /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-dialog-title", children: isEligible ? t("congratulations") : t("oops") })
511
524
  ] }),
512
525
  /* @__PURE__ */ jsx(
513
526
  "p",
514
527
  {
515
528
  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
- ] })
529
+ children: isEligible ? t("awesome_already_meet_requirements") : /* @__PURE__ */ jsx(
530
+ I18nT,
531
+ {
532
+ t,
533
+ i18nKey: "before_join_please_meet_express_following_eligibilities",
534
+ components: {
535
+ express: /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-highlight", children: expressLabel })
536
+ }
537
+ }
538
+ )
521
539
  }
522
540
  ),
523
541
  /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-dialog-eligs", children: [
@@ -536,7 +554,7 @@ function EligsNotPassDialog({
536
554
  className: "taskon-eligs-dialog-eligs-icon"
537
555
  }
538
556
  ),
539
- /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-eligs-label", children: "Meet Eligibilities Below" }),
557
+ /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-eligs-label", children: t("meet_eligibilities_below") }),
540
558
  /* @__PURE__ */ jsx(ArrowIcon$1, { expanded: isExpanded })
541
559
  ]
542
560
  }
@@ -563,8 +581,8 @@ function EligsNotPassDialog({
563
581
  disabled: isRefreshing,
564
582
  children: isRefreshing ? /* @__PURE__ */ jsxs("span", { className: "taskon-eligs-dialog-loading", children: [
565
583
  /* @__PURE__ */ jsx("span", { className: "taskon-eligs-dialog-spinner" }),
566
- "Refreshing..."
567
- ] }) : isEligible || !onRefresh ? "OK" : "Refresh"
584
+ t("refreshing")
585
+ ] }) : isEligible || !onRefresh ? t("ok") : t("refresh")
568
586
  }
569
587
  )
570
588
  ] })
@@ -572,7 +590,7 @@ function EligsNotPassDialog({
572
590
  );
573
591
  }
574
592
  const CHAIN_TYPE_LABELS$1 = {
575
- evm: "EVM Chain",
593
+ evm: "evm_chain",
576
594
  btc: "Bitcoin",
577
595
  starknet: "Starknet",
578
596
  solana: "Solana",
@@ -584,12 +602,15 @@ const CHAIN_TYPE_LABELS$1 = {
584
602
  ton: "TON"
585
603
  };
586
604
  const SNS_TYPE_LABELS = {
587
- twitter: "X (Twitter)",
588
- discord: "Discord",
605
+ twitter: "x_twitter",
606
+ discord: "discord",
589
607
  telegram: "Telegram"
590
608
  };
591
609
  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;
610
+ const { t } = useQuestLocale();
611
+ const chainLabelKey = CHAIN_TYPE_LABELS$1[bindType.toLowerCase()];
612
+ const snsLabelKey = SNS_TYPE_LABELS[bindType.toLowerCase()];
613
+ const label = type === "chain" ? chainLabelKey ? t(chainLabelKey) : bindType : snsLabelKey ? t(snsLabelKey) : bindType;
593
614
  return /* @__PURE__ */ jsxs("div", { className: `taskon-eligs-bind-item ${isBound ? "taskon-eligs-bind-item--bound" : ""}`, children: [
594
615
  /* @__PURE__ */ jsx("span", { className: "taskon-eligs-bind-item-label", children: label }),
595
616
  isBound ? /* @__PURE__ */ jsxs("span", { className: "taskon-eligs-bind-item-status", children: [
@@ -603,7 +624,7 @@ function BindItem$1({ type, bindType, isBinding, isBound, onBind }) {
603
624
  strokeLinejoin: "round"
604
625
  }
605
626
  ) }),
606
- "Bound"
627
+ t("bound")
607
628
  ] }) : /* @__PURE__ */ jsx(
608
629
  "button",
609
630
  {
@@ -612,8 +633,8 @@ function BindItem$1({ type, bindType, isBinding, isBound, onBind }) {
612
633
  disabled: isBinding,
613
634
  children: isBinding ? /* @__PURE__ */ jsxs(Fragment, { children: [
614
635
  /* @__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"
636
+ t("binding")
637
+ ] }) : t("bind")
617
638
  }
618
639
  )
619
640
  ] });
@@ -628,6 +649,7 @@ function EligsBindDialog({
628
649
  onBindChain,
629
650
  onBindSns
630
651
  }) {
652
+ const { t } = useQuestLocale();
631
653
  const [notBoundChains, setNotBoundChains] = useState(chainTypes);
632
654
  const [notBoundSns, setNotBoundSns] = useState(snsTypes);
633
655
  const [bindingType, setBindingType] = useState(null);
@@ -650,7 +672,7 @@ function EligsBindDialog({
650
672
  try {
651
673
  const success = await onBindChain(chainType);
652
674
  if (success) {
653
- setNotBoundChains((prev) => prev.filter((t) => t !== chainType));
675
+ setNotBoundChains((prev) => prev.filter((t2) => t2 !== chainType));
654
676
  }
655
677
  } finally {
656
678
  setBindingType(null);
@@ -661,7 +683,7 @@ function EligsBindDialog({
661
683
  try {
662
684
  const success = await onBindSns(snsType);
663
685
  if (success) {
664
- setNotBoundSns((prev) => prev.filter((t) => t !== snsType));
686
+ setNotBoundSns((prev) => prev.filter((t2) => t2 !== snsType));
665
687
  }
666
688
  } finally {
667
689
  setBindingType(null);
@@ -679,12 +701,12 @@ function EligsBindDialog({
679
701
  handleClose();
680
702
  }
681
703
  },
682
- title: "Bind Required Accounts",
704
+ title: t("bind_required_accounts"),
683
705
  showCloseButton: true,
684
706
  maxWidth: 560,
685
707
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-eligs-bind-dialog", children: [
686
708
  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" }),
709
+ /* @__PURE__ */ jsx("h3", { className: "taskon-eligs-bind-section-title", children: t("quest_eligibility") }),
688
710
  /* @__PURE__ */ jsx(
689
711
  EligibilityList,
690
712
  {
@@ -698,9 +720,9 @@ function EligsBindDialog({
698
720
  }
699
721
  )
700
722
  ] }),
701
- /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: "Please bind the following accounts to verify eligibility." }),
723
+ /* @__PURE__ */ jsx("p", { className: "taskon-eligs-bind-tip", children: t("please_bind_following_accounts_verify_eligibility") }),
702
724
  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" }),
725
+ /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: t("wallet_address") }),
704
726
  /* @__PURE__ */ jsx("div", { className: "taskon-eligs-bind-list", children: chainTypes.map((chainType) => /* @__PURE__ */ jsx(
705
727
  BindItem$1,
706
728
  {
@@ -714,7 +736,7 @@ function EligsBindDialog({
714
736
  )) })
715
737
  ] }),
716
738
  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" }),
739
+ /* @__PURE__ */ jsx("h4", { className: "taskon-eligs-bind-section-subtitle", children: t("social_accounts") }),
718
740
  /* @__PURE__ */ jsx("div", { className: "taskon-eligs-bind-list", children: snsTypes.map((snsType) => /* @__PURE__ */ jsx(
719
741
  BindItem$1,
720
742
  {
@@ -732,6 +754,7 @@ function EligsBindDialog({
732
754
  );
733
755
  }
734
756
  function useQuestDetail(options) {
757
+ const { t } = useQuestLocale();
735
758
  const {
736
759
  api,
737
760
  campaignId,
@@ -761,14 +784,14 @@ function useQuestDetail(options) {
761
784
  const result = await api.getCampaignInfo(params);
762
785
  setData(result);
763
786
  } catch (err) {
764
- const errorMessage = err instanceof Error ? err.message : "Failed to load quest detail";
787
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_quest_detail");
765
788
  setError(errorMessage);
766
789
  setData(null);
767
790
  console.error("[useQuestDetail] Error:", err);
768
791
  } finally {
769
792
  setIsLoading(false);
770
793
  }
771
- }, [enabled, api, campaignId, channel, kolHandle, inviteCode, boostId]);
794
+ }, [enabled, api, campaignId, channel, kolHandle, inviteCode, boostId, t]);
772
795
  useEffect(() => {
773
796
  fetchDetail();
774
797
  }, [fetchDetail]);
@@ -780,6 +803,7 @@ function useQuestDetail(options) {
780
803
  };
781
804
  }
782
805
  function useQuestUserStatus(options) {
806
+ const { t } = useQuestLocale();
783
807
  const { api, campaignId, channel, kolHandle, enabled = true } = options;
784
808
  const [data, setData] = useState(null);
785
809
  const [isLoading, setIsLoading] = useState(false);
@@ -799,14 +823,14 @@ function useQuestUserStatus(options) {
799
823
  const result = await api.getUserCampaignStatus(params);
800
824
  setData(result);
801
825
  } catch (err) {
802
- const errorMessage = err instanceof Error ? err.message : "Failed to load user status";
826
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_user_status");
803
827
  setError(errorMessage);
804
828
  setData(null);
805
829
  console.error("[useQuestUserStatus] Error:", err);
806
830
  } finally {
807
831
  setIsLoading(false);
808
832
  }
809
- }, [enabled, api, campaignId, channel, kolHandle]);
833
+ }, [enabled, api, campaignId, channel, kolHandle, t]);
810
834
  const updateTaskStatus = useCallback(
811
835
  (taskId, isAsync = false) => {
812
836
  setData((prev) => {
@@ -845,6 +869,7 @@ function useQuestUserStatus(options) {
845
869
  };
846
870
  }
847
871
  function useQuestStatus(options) {
872
+ const { t } = useQuestLocale();
848
873
  const { api, campaignId, channel, kolHandle, enabled = true } = options;
849
874
  const [data, setData] = useState(null);
850
875
  const [isLoading, setIsLoading] = useState(false);
@@ -864,14 +889,14 @@ function useQuestStatus(options) {
864
889
  const result = await api.getCampaignStatusInfo(params);
865
890
  setData(result);
866
891
  } catch (err) {
867
- const errorMessage = err instanceof Error ? err.message : "Failed to load quest status";
892
+ const errorMessage = err instanceof Error ? err.message : t("failed_load_quest_status");
868
893
  setError(errorMessage);
869
894
  setData(null);
870
895
  console.error("[useQuestStatus] Error:", err);
871
896
  } finally {
872
897
  setIsLoading(false);
873
898
  }
874
- }, [enabled, api, campaignId, channel, kolHandle]);
899
+ }, [enabled, api, campaignId, channel, kolHandle, t]);
875
900
  useEffect(() => {
876
901
  fetchStatus();
877
902
  }, [fetchStatus]);
@@ -1229,7 +1254,7 @@ function getNeedBindChainTypeList(requiredChainTypes, userProfile) {
1229
1254
  (chainType) => requiredChainTypes.includes(chainType) && !boundChainTypes.includes(chainType)
1230
1255
  );
1231
1256
  }
1232
- function validateTaskCompletion(campaign, userStatus) {
1257
+ function validateTaskCompletion(campaign, userStatus, t) {
1233
1258
  const { tasks, min_finished_optional_task_num, min_finished_optional_task_points } = campaign;
1234
1259
  const { task_status_details } = userStatus;
1235
1260
  const notCompletedMandatory = tasks.find(
@@ -1241,7 +1266,7 @@ function validateTaskCompletion(campaign, userStatus) {
1241
1266
  if (notCompletedMandatory) {
1242
1267
  return {
1243
1268
  type: "mandatory",
1244
- message: "Please complete all mandatory tasks"
1269
+ message: t("please_complete_mandatory_tasks")
1245
1270
  };
1246
1271
  }
1247
1272
  if (min_finished_optional_task_num && min_finished_optional_task_num > 0) {
@@ -1255,7 +1280,7 @@ function validateTaskCompletion(campaign, userStatus) {
1255
1280
  if (completedCount < min_finished_optional_task_num) {
1256
1281
  return {
1257
1282
  type: "optional_count",
1258
- message: "Please complete more optional tasks",
1283
+ message: t("please_complete_optional_tasks"),
1259
1284
  required: min_finished_optional_task_num,
1260
1285
  current: completedCount
1261
1286
  };
@@ -1272,7 +1297,12 @@ function validateTaskCompletion(campaign, userStatus) {
1272
1297
  if (totalPoints < min_finished_optional_task_points) {
1273
1298
  return {
1274
1299
  type: "optional_points",
1275
- message: `Please earn at least ${min_finished_optional_task_points} points from optional tasks`,
1300
+ message: t(
1301
+ "please_earn_least_count_points_optional_tasks",
1302
+ {
1303
+ count: min_finished_optional_task_points
1304
+ }
1305
+ ),
1276
1306
  required: min_finished_optional_task_points,
1277
1307
  current: totalPoints
1278
1308
  };
@@ -1317,6 +1347,7 @@ function isDiscordBound(userProfile) {
1317
1347
  return (userProfile == null ? void 0 : userProfile.sns.some((item) => item.sns_type === SnsType.Discord)) || false;
1318
1348
  }
1319
1349
  function useCompleteValidation(options) {
1350
+ const { t } = useQuestLocale();
1320
1351
  const {
1321
1352
  api,
1322
1353
  campaign,
@@ -1407,7 +1438,11 @@ function useCompleteValidation(options) {
1407
1438
  onLogin == null ? void 0 : onLogin();
1408
1439
  return false;
1409
1440
  }
1410
- const taskError = validateTaskCompletion(campaign, userStatus);
1441
+ const taskError = validateTaskCompletion(
1442
+ campaign,
1443
+ userStatus,
1444
+ t
1445
+ );
1411
1446
  if (taskError) {
1412
1447
  setTaskValidationError(taskError);
1413
1448
  return false;
@@ -1493,7 +1528,8 @@ function useCompleteValidation(options) {
1493
1528
  userProfile,
1494
1529
  isLoggedIn,
1495
1530
  onLogin,
1496
- onEligibilityFailed
1531
+ onEligibilityFailed,
1532
+ t
1497
1533
  ]);
1498
1534
  return {
1499
1535
  validateBeforeComplete,
@@ -1571,16 +1607,17 @@ function formatLongNumber$1(input, symbol = true) {
1571
1607
  }
1572
1608
  return String(Math.round(num * 100) / 100);
1573
1609
  }
1574
- function getRewardSymbol(info) {
1610
+ function getRewardSymbol(info, t) {
1575
1611
  var _a;
1612
+ const translate = t ?? ((key) => key);
1576
1613
  if (info.reward_type === RewardType.Points) {
1577
- return "Points";
1614
+ return translate("points");
1578
1615
  }
1579
1616
  if (info.reward_type === RewardType.GTCPoints) {
1580
- return ((_a = info.points_info) == null ? void 0 : _a.points_name) || "Points";
1617
+ return ((_a = info.points_info) == null ? void 0 : _a.points_name) || translate("points");
1581
1618
  }
1582
1619
  if (info.reward_type === RewardType.Whitelist) {
1583
- return "WL";
1620
+ return translate("whitelist");
1584
1621
  }
1585
1622
  if (info.reward_type === RewardType.Token) {
1586
1623
  return info.reward_symbol || "";
@@ -1595,23 +1632,26 @@ function getRewardSymbol(info) {
1595
1632
  return "EXP";
1596
1633
  }
1597
1634
  if (info.reward_type === RewardType.DiscordRole) {
1598
- return "Discord Role";
1635
+ return translate("discord_role");
1599
1636
  }
1600
1637
  return "";
1601
1638
  }
1602
- function formatRewardLabel(info) {
1639
+ function formatRewardLabel(info, t) {
1640
+ const translate = t ?? ((key) => key);
1603
1641
  if (info.reward_type === RewardType.Points || info.reward_type === RewardType.GTCPoints) {
1604
1642
  const amount = info.reward_amount ? formatLongNumber$1(info.reward_amount) : "?";
1605
- return `${amount} ${getRewardSymbol(info)}`;
1643
+ return `${amount} ${getRewardSymbol(info, translate)}`;
1606
1644
  }
1607
1645
  if (info.reward_type === RewardType.Token) {
1608
1646
  if (info.is_usdt_equal) {
1609
- return `$${info.reward_amount || ""} USD in ${info.reward_symbol}`;
1647
+ return `${info.reward_amount || ""} ${translate("usd_token_name", {
1648
+ token_name: info.reward_symbol || ""
1649
+ })}`.trim();
1610
1650
  }
1611
1651
  const amount = info.reward_amount ? formatLongNumber$1(info.reward_amount) : "?";
1612
- return `${amount} ${getRewardSymbol(info)}`;
1652
+ return `${amount} ${getRewardSymbol(info, translate)}`;
1613
1653
  }
1614
- return getRewardSymbol(info);
1654
+ return getRewardSymbol(info, translate);
1615
1655
  }
1616
1656
  function addUrlParam(url, key, value) {
1617
1657
  try {
@@ -1623,7 +1663,7 @@ function addUrlParam(url, key, value) {
1623
1663
  }
1624
1664
  }
1625
1665
  function getDefaultShareText(campaignName) {
1626
- return `Join the ${campaignName || "Quest"} with me 🙌`;
1666
+ return `Join the ${campaignName || "quest"} with me 🙌`;
1627
1667
  }
1628
1668
  function buildFinalShareText(shareUrl, shareText, shareAutoAppendLink, campaignName) {
1629
1669
  const baseText = shareText || getDefaultShareText(campaignName);
@@ -3848,6 +3888,7 @@ function QrCodeDialog({
3848
3888
  endTime,
3849
3889
  winnerRewardsSimple
3850
3890
  }) {
3891
+ const { t } = useQuestLocale();
3851
3892
  const [qrCodeUrl, setQrCodeUrl] = useState("");
3852
3893
  const posterRef = useRef(null);
3853
3894
  useEffect(() => {
@@ -3880,7 +3921,7 @@ function QrCodeDialog({
3880
3921
  link.href = dataUrl;
3881
3922
  link.click();
3882
3923
  } catch (error) {
3883
- console.error("Failed to download poster:", error);
3924
+ console.error("failed_download_poster", error);
3884
3925
  }
3885
3926
  };
3886
3927
  return /* @__PURE__ */ jsx(
@@ -3890,7 +3931,7 @@ function QrCodeDialog({
3890
3931
  onOpenChange: (isOpen) => !isOpen && onClose(),
3891
3932
  showCloseButton: true,
3892
3933
  contentClassName: "taskon-quest-qr-dialog-content",
3893
- title: "Share QR Code",
3934
+ title: t("share_qr_code"),
3894
3935
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-dialog", children: [
3895
3936
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-poster-outer", children: /* @__PURE__ */ jsxs("div", { ref: posterRef, className: "taskon-quest-qr-poster", children: [
3896
3937
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-poster-header", children: [
@@ -3920,13 +3961,16 @@ function QrCodeDialog({
3920
3961
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-poster-footer", children: [
3921
3962
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-info", children: [
3922
3963
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-reward-title", children: [
3923
- "Reward",
3964
+ t("reward"),
3924
3965
  /* @__PURE__ */ jsx(ArrowRightIcon, {})
3925
3966
  ] }),
3926
3967
  winnerRewardsSimple && winnerRewardsSimple.length > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-qr-rewards-list", children: [
3927
3968
  "🎁",
3928
3969
  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) }),
3970
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-qr-reward-label", children: formatRewardLabel(
3971
+ reward,
3972
+ t
3973
+ ) }),
3930
3974
  reward.chain_icon && /* @__PURE__ */ jsx(
3931
3975
  "img",
3932
3976
  {
@@ -3944,12 +3988,12 @@ function QrCodeDialog({
3944
3988
  /* @__PURE__ */ jsx("span", { children: timeRangeText })
3945
3989
  ] })
3946
3990
  ] }),
3947
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-code", children: qrCodeUrl && /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: "QR Code" }) })
3991
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-qr-code", children: qrCodeUrl && /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: t("qr_code") }) })
3948
3992
  ] })
3949
3993
  ] }) }),
3950
3994
  /* @__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" })
3995
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: t("close") }),
3996
+ /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleDownload, children: t("save") })
3953
3997
  ] })
3954
3998
  ] })
3955
3999
  }
@@ -4071,20 +4115,29 @@ function ShareDropdown({
4071
4115
  endTime,
4072
4116
  winnerRewardsSimple
4073
4117
  }) {
4118
+ const { t } = useQuestLocale();
4074
4119
  const portalContainer = useTaskOnPortalContainer();
4075
4120
  const { toast } = useToast();
4076
4121
  const [qrDialogOpen, setQrDialogOpen] = useState(false);
4077
4122
  const [popoverOpen, setPopoverOpen] = useState(false);
4078
4123
  const resolvedUrl = shareUrl || window.location.href;
4079
4124
  const handleShareTwitter = () => {
4080
- const text = buildFinalShareText(resolvedUrl, shareText, shareAutoAppendLink, campaignName);
4125
+ const resolvedShareText = shareText || t("join_campaignname_me", {
4126
+ campaignName: campaignName || t("quest")
4127
+ });
4128
+ const text = buildFinalShareText(
4129
+ resolvedUrl,
4130
+ resolvedShareText,
4131
+ shareAutoAppendLink,
4132
+ campaignName
4133
+ );
4081
4134
  shareToTwitter(text);
4082
4135
  setPopoverOpen(false);
4083
4136
  };
4084
4137
  const handleCopyLink = async () => {
4085
4138
  const success = await copyToClipboard$3(resolvedUrl);
4086
4139
  if (success) {
4087
- toast.success("Link copied!");
4140
+ toast.success(t("link_copied"));
4088
4141
  }
4089
4142
  setPopoverOpen(false);
4090
4143
  };
@@ -4094,7 +4147,7 @@ function ShareDropdown({
4094
4147
  };
4095
4148
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4096
4149
  /* @__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, {}) }) }),
4150
+ /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "taskon-quest-share-trigger", "aria-label": t("share"), children: /* @__PURE__ */ jsx(ShareIcon, {}) }) }),
4098
4151
  /* @__PURE__ */ jsx(Portal, { container: portalContainer ?? void 0, children: /* @__PURE__ */ jsxs(Content2, { className: "taskon-quest-share-menu", sideOffset: 8, children: [
4099
4152
  /* @__PURE__ */ jsxs(
4100
4153
  "button",
@@ -4103,7 +4156,7 @@ function ShareDropdown({
4103
4156
  onClick: handleShareTwitter,
4104
4157
  children: [
4105
4158
  /* @__PURE__ */ jsx(TwitterIcon, {}),
4106
- /* @__PURE__ */ jsx("span", { children: "Twitter" })
4159
+ /* @__PURE__ */ jsx("span", { children: t("twitter") })
4107
4160
  ]
4108
4161
  }
4109
4162
  ),
@@ -4114,7 +4167,7 @@ function ShareDropdown({
4114
4167
  onClick: handleCopyLink,
4115
4168
  children: [
4116
4169
  /* @__PURE__ */ jsx(CopyLinkIcon, {}),
4117
- /* @__PURE__ */ jsx("span", { children: "Copy Link" })
4170
+ /* @__PURE__ */ jsx("span", { children: t("copy_link") })
4118
4171
  ]
4119
4172
  }
4120
4173
  ),
@@ -4125,7 +4178,7 @@ function ShareDropdown({
4125
4178
  onClick: handleShowQrCode,
4126
4179
  children: [
4127
4180
  /* @__PURE__ */ jsx(QrCodeIcon, {}),
4128
- /* @__PURE__ */ jsx("span", { children: "QR Code" })
4181
+ /* @__PURE__ */ jsx("span", { children: t("qr_code") })
4129
4182
  ]
4130
4183
  }
4131
4184
  )
@@ -4188,6 +4241,7 @@ function QuestTitle({
4188
4241
  communityAvatar,
4189
4242
  winnerRewardsSimple
4190
4243
  }) {
4244
+ const { t } = useQuestLocale();
4191
4245
  const countdownTarget = !isStarted ? startTime : isActive ? endTime : void 0;
4192
4246
  const countdown = useCountdown(countdownTarget);
4193
4247
  const startDate = new Date(startTime);
@@ -4202,7 +4256,7 @@ function QuestTitle({
4202
4256
  };
4203
4257
  const offset = -startDate.getTimezoneOffset() / 60;
4204
4258
  const offsetString = offset >= 0 ? `+${offset}` : String(offset);
4205
- const countdownLabel = isEnded ? "ENDED" : !isStarted ? "Starts In" : "Ends In";
4259
+ const countdownLabel = isEnded ? t("ended") : !isStarted ? t("starts") : t("ends");
4206
4260
  const hasValidCountdown = !isEnded && countdown && countdown.totalSeconds > 0;
4207
4261
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-header-title-section", children: [
4208
4262
  show && /* @__PURE__ */ jsx("h1", { className: "taskon-quest-title", children: title }),
@@ -4253,6 +4307,7 @@ function QuestDescription({
4253
4307
  description,
4254
4308
  show = true
4255
4309
  }) {
4310
+ const { t } = useQuestLocale();
4256
4311
  const [isExpanded, setIsExpanded] = useState(false);
4257
4312
  const sanitizedHtml = useMemo(() => {
4258
4313
  if (!description) return "";
@@ -4274,7 +4329,7 @@ function QuestDescription({
4274
4329
  {
4275
4330
  className: "taskon-quest-desc-more",
4276
4331
  onClick: () => setIsExpanded(!isExpanded),
4277
- children: isExpanded ? "Show less" : "Read more"
4332
+ children: isExpanded ? t("show_less") : t("read")
4278
4333
  }
4279
4334
  )
4280
4335
  ] });
@@ -4365,6 +4420,7 @@ function ParticipantsInfo({
4365
4420
  participantCount,
4366
4421
  className
4367
4422
  }) {
4423
+ const { t } = useQuestLocale();
4368
4424
  const [isDialogOpen, setIsDialogOpen] = useState(false);
4369
4425
  if (participantCount === 0) {
4370
4426
  return null;
@@ -4377,15 +4433,15 @@ function ParticipantsInfo({
4377
4433
  type: "button",
4378
4434
  className: "taskon-quest-participants-info-header",
4379
4435
  onClick: () => setIsDialogOpen(true),
4380
- "aria-label": "View participants info details",
4436
+ "aria-label": t("view_participants_info_details"),
4381
4437
  children: [
4382
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-participants-info-title", children: "Participants Info" }),
4438
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-participants-info-title", children: t("participants_info") }),
4383
4439
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-icon", children: /* @__PURE__ */ jsx(InfoIcon, {}) })
4384
4440
  ]
4385
4441
  }
4386
4442
  ),
4387
4443
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-info-row", children: [
4388
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-label", children: "Participants" }),
4444
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-label", children: t("participants_2") }),
4389
4445
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-value", children: formattedParticipantCount })
4390
4446
  ] }),
4391
4447
  /* @__PURE__ */ jsx(
@@ -4393,36 +4449,48 @@ function ParticipantsInfo({
4393
4449
  {
4394
4450
  open: isDialogOpen,
4395
4451
  onOpenChange: setIsDialogOpen,
4396
- title: "Participants",
4452
+ title: t("participants_2"),
4397
4453
  maxWidth: 480,
4398
4454
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog", children: [
4399
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-participants-dialog-title", children: "Participants" }),
4455
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-participants-dialog-title", children: t("participants_2") }),
4400
4456
  /* @__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." })
4457
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: t("what_participants") }),
4458
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: t("participants_any_user_who_complete_least_1_task_quest") })
4403
4459
  ] }),
4404
4460
  /* @__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." })
4461
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: t("how_winner_selected") }),
4462
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-desc", children: t("winner_generated_following_chart") })
4407
4463
  ] }),
4408
4464
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-chart", children: [
4409
4465
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-arrow-wrap", children: /* @__PURE__ */ jsx(ArrowDownIcon, {}) }),
4410
4466
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-cards", children: [
4411
4467
  /* @__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." })
4468
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("participants_2") }),
4469
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4470
+ "*",
4471
+ t("who_completes_least_1_task")
4472
+ ] })
4414
4473
  ] }),
4415
4474
  /* @__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." })
4475
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("submitters") }),
4476
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4477
+ "*",
4478
+ t("who_completes_quest")
4479
+ ] })
4418
4480
  ] }),
4419
4481
  /* @__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." })
4482
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("qualifiers") }),
4483
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4484
+ "*",
4485
+ t("tasks_quest_verified_valid_some_tasks_may_verified_quest")
4486
+ ] })
4422
4487
  ] }),
4423
4488
  /* @__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." })
4489
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: t("winners_2") }),
4490
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card-desc", children: [
4491
+ "*",
4492
+ t("qualifier_selected_winner_select_method_depends_settings_fcfs")
4493
+ ] })
4426
4494
  ] })
4427
4495
  ] })
4428
4496
  ] }),
@@ -4433,7 +4501,7 @@ function ParticipantsInfo({
4433
4501
  size: "large",
4434
4502
  className: "taskon-quest-participants-dialog-btn",
4435
4503
  onClick: () => setIsDialogOpen(false),
4436
- children: "Confirm"
4504
+ children: t("confirm")
4437
4505
  }
4438
4506
  )
4439
4507
  ] })
@@ -4441,14 +4509,14 @@ function ParticipantsInfo({
4441
4509
  )
4442
4510
  ] });
4443
4511
  }
4444
- function getRewardTypeLabel$1(rewardType, pointName) {
4512
+ function getRewardTypeLabel$1(rewardType, pointName, t) {
4445
4513
  if ([RewardType.BMintedNft, RewardType.Cap, RewardType.Nft].includes(
4446
4514
  rewardType
4447
4515
  )) {
4448
4516
  return "NFT:";
4449
4517
  }
4450
4518
  if (rewardType === String(RewardType.DiscordRole)) {
4451
- return "Discord Role:";
4519
+ return `${t("discord_role")}:`;
4452
4520
  }
4453
4521
  if (rewardType === String(RewardType.Exp)) {
4454
4522
  return "EXP:";
@@ -4460,14 +4528,14 @@ function getRewardTypeLabel$1(rewardType, pointName) {
4460
4528
  return `${pointName}:`;
4461
4529
  }
4462
4530
  if (rewardType === String(RewardType.Token)) {
4463
- return "Token:";
4531
+ return `${t("token_name")}:`;
4464
4532
  }
4465
4533
  if (rewardType === String(RewardType.Whitelist)) {
4466
- return "Whitelist";
4534
+ return t("whitelist");
4467
4535
  }
4468
4536
  return String(rewardType);
4469
4537
  }
4470
- function getRewardLabel$1(data) {
4538
+ function getRewardLabel$1(data, t) {
4471
4539
  const { reward_type, reward_symbol, amount, chain_label, is_usdt_equal } = data;
4472
4540
  if ([
4473
4541
  RewardType.BMintedNft,
@@ -4485,7 +4553,9 @@ function getRewardLabel$1(data) {
4485
4553
  }
4486
4554
  if (reward_type === String(RewardType.Token)) {
4487
4555
  if (is_usdt_equal) {
4488
- return `$${amount || ""} in ${reward_symbol}`;
4556
+ return `${amount || ""} ${t("usd_token_name", {
4557
+ token_name: reward_symbol || ""
4558
+ })}`.trim();
4489
4559
  }
4490
4560
  return `${amount || ""} ${reward_symbol} ${chain_label || ""}`.trim();
4491
4561
  }
@@ -4496,13 +4566,21 @@ function getRewardLabel$1(data) {
4496
4566
  }
4497
4567
  function WinnerRewardLabel({
4498
4568
  data,
4499
- pointName = "Points"
4569
+ pointName
4500
4570
  }) {
4571
+ const { t } = useQuestLocale();
4572
+ const resolvedPointName = pointName || t("points");
4501
4573
  const typeLabel = useMemo(
4502
- () => getRewardTypeLabel$1(data.reward_type, pointName),
4503
- [data.reward_type, pointName]
4574
+ () => getRewardTypeLabel$1(data.reward_type, resolvedPointName, t),
4575
+ [data.reward_type, resolvedPointName, t]
4576
+ );
4577
+ const valueLabel = useMemo(
4578
+ () => getRewardLabel$1(
4579
+ data,
4580
+ t
4581
+ ),
4582
+ [data, t]
4504
4583
  );
4505
- const valueLabel = useMemo(() => getRewardLabel$1(data), [data]);
4506
4584
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-reward-label", children: [
4507
4585
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-type", children: typeLabel }),
4508
4586
  valueLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-value", children: valueLabel })
@@ -4528,32 +4606,32 @@ function getHowToSelectWinner$1(group) {
4528
4606
  }
4529
4607
  function getWinnerSelectionLabel$1(howToSelect) {
4530
4608
  const labels = {
4531
- FCFS: "FCFS",
4532
- LuckyDraw: "Lucky Draw",
4533
- PointRanking: "Ranking",
4534
- ManualUpload: "Manually Upload",
4535
- OpenToAll: "Open to All"
4609
+ FCFS: "fcfs",
4610
+ LuckyDraw: "lucky_draw",
4611
+ PointRanking: "ranking_2",
4612
+ ManualUpload: "manually_upload",
4613
+ OpenToAll: "open"
4536
4614
  };
4537
4615
  return labels[howToSelect];
4538
4616
  }
4539
- function formatRankingLabel(ranking) {
4617
+ function formatRankingLabel(ranking, t) {
4540
4618
  if (ranking.range_type === QuestWinnerRangeType.Number) {
4541
4619
  if (ranking.from < 2) {
4542
- return `Top ${ranking.to}`;
4620
+ return t("top_2", { to: ranking.to });
4543
4621
  }
4544
- return `Top ${ranking.from}-${ranking.to}`;
4622
+ return t("top", { from: ranking.from, to: ranking.to });
4545
4623
  } else {
4546
4624
  if (ranking.from === 0) {
4547
- return `Top ${ranking.to}%`;
4625
+ return t("top_percent_2", { to: ranking.to });
4548
4626
  }
4549
- return `Top ${ranking.from}%-${ranking.to}%`;
4627
+ return t("top_percent", { from: ranking.from, to: ranking.to });
4550
4628
  }
4551
4629
  }
4552
- function getTierLabel(layerIndex, isCurrentLayer) {
4630
+ function getTierLabel(layerIndex, isCurrentLayer, t) {
4553
4631
  if (isCurrentLayer) {
4554
- return "You are here";
4632
+ return t("here");
4555
4633
  }
4556
- return `Tier ${layerIndex + 1}`;
4634
+ return t("tier_index", { index: layerIndex + 1 });
4557
4635
  }
4558
4636
  function calculateFcfsAvailable(rewardLayer, currentWinner) {
4559
4637
  var _a;
@@ -4635,9 +4713,11 @@ function WinnerListModal({
4635
4713
  onClose,
4636
4714
  campaignId,
4637
4715
  winnerRewards,
4638
- pointsName = "Points"
4716
+ pointsName
4639
4717
  }) {
4718
+ const { t } = useQuestLocale();
4640
4719
  const { client } = useTaskOnContext();
4720
+ const resolvedPointsName = pointsName || t("points");
4641
4721
  const api = useMemo(() => {
4642
4722
  if (!client) return null;
4643
4723
  return createQuestApi(client);
@@ -4652,13 +4732,14 @@ function WinnerListModal({
4652
4732
  const tabItems = useMemo(() => {
4653
4733
  return winnerRewards.map((item, index) => {
4654
4734
  const howToSelect = getHowToSelectWinner$1(item);
4735
+ const label = getWinnerSelectionLabel$1(howToSelect);
4655
4736
  return {
4656
4737
  key: index,
4657
- label: getWinnerSelectionLabel$1(howToSelect),
4738
+ label: t(label),
4658
4739
  type: howToSelect
4659
4740
  };
4660
4741
  });
4661
- }, [winnerRewards]);
4742
+ }, [winnerRewards, t]);
4662
4743
  const currentType = useMemo(() => {
4663
4744
  var _a;
4664
4745
  return ((_a = tabItems[currentIndex]) == null ? void 0 : _a.type) || "FCFS";
@@ -4688,7 +4769,7 @@ function WinnerListModal({
4688
4769
  }
4689
4770
  setPage(pageNo);
4690
4771
  } catch (err) {
4691
- setError(err instanceof Error ? err.message : "Failed to load winners");
4772
+ setError(err instanceof Error ? err.message : t("failed_load_winners"));
4692
4773
  if (!append) {
4693
4774
  setTotal(0);
4694
4775
  setList([]);
@@ -4697,7 +4778,7 @@ function WinnerListModal({
4697
4778
  setLoading(false);
4698
4779
  }
4699
4780
  },
4700
- [api, campaignId, currentIndex, loading]
4781
+ [api, campaignId, currentIndex, loading, t]
4701
4782
  );
4702
4783
  useEffect(() => {
4703
4784
  if (isOpen && api) {
@@ -4743,13 +4824,14 @@ function WinnerListModal({
4743
4824
  onOpenChange: (open) => {
4744
4825
  if (!open) onClose();
4745
4826
  },
4746
- title: "Winners",
4827
+ title: t("winners"),
4747
4828
  showCloseButton: true,
4748
4829
  contentClassName: "taskon-quest-winner-modal",
4749
4830
  maxWidth: 600,
4750
4831
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-content", children: [
4751
4832
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-header", children: /* @__PURE__ */ jsxs("h2", { className: "taskon-quest-winner-title", children: [
4752
- "Winners (",
4833
+ t("winners"),
4834
+ " (",
4753
4835
  total.toLocaleString(),
4754
4836
  ")"
4755
4837
  ] }) }),
@@ -4770,16 +4852,16 @@ function WinnerListModal({
4770
4852
  variant: "primary",
4771
4853
  size: "small",
4772
4854
  onClick: () => loadPage(0, false),
4773
- children: "Retry"
4855
+ children: t("retry")
4774
4856
  }
4775
4857
  )
4776
4858
  ] }),
4777
4859
  !error && /* @__PURE__ */ jsxs("div", { ref: scrollRef, className: "taskon-quest-winner-list", children: [
4778
4860
  /* @__PURE__ */ jsxs("table", { className: "taskon-quest-winner-table", children: [
4779
4861
  /* @__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" })
4862
+ showPosition && /* @__PURE__ */ jsx("th", { children: t("position") }),
4863
+ /* @__PURE__ */ jsx("th", { children: t("user") }),
4864
+ /* @__PURE__ */ jsx("th", { children: t("rewards") })
4783
4865
  ] }) }),
4784
4866
  /* @__PURE__ */ jsxs("tbody", { children: [
4785
4867
  list.map((item, index) => {
@@ -4793,7 +4875,7 @@ function WinnerListModal({
4793
4875
  WinnerRewardLabel,
4794
4876
  {
4795
4877
  data: reward,
4796
- pointName: pointsName
4878
+ pointName: resolvedPointsName
4797
4879
  },
4798
4880
  `${reward.reward_type}-${rewardIndex}`
4799
4881
  )) }) })
@@ -4804,14 +4886,14 @@ function WinnerListModal({
4804
4886
  {
4805
4887
  colSpan: showPosition ? 3 : 2,
4806
4888
  className: "taskon-quest-winner-empty",
4807
- children: "No winners yet"
4889
+ children: t("no_winners")
4808
4890
  }
4809
4891
  ) })
4810
4892
  ] })
4811
4893
  ] }),
4812
4894
  loading && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-loading", children: [
4813
4895
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-loading-spinner" }),
4814
- /* @__PURE__ */ jsx("span", { children: "Loading..." })
4896
+ /* @__PURE__ */ jsx("span", { children: t("loading") })
4815
4897
  ] })
4816
4898
  ] })
4817
4899
  ] })
@@ -4906,6 +4988,7 @@ function getIsBrc20(chain, tokenAddress, chains) {
4906
4988
  return (chainInfo == null ? void 0 : chainInfo.chain_type) === "btc" && tokenAddress !== BTC_CONTRACT;
4907
4989
  }
4908
4990
  function TokenInfo({ rewardInfo, chains }) {
4991
+ const { t } = useQuestLocale();
4909
4992
  const portalContainer = useTaskOnPortalContainer();
4910
4993
  const params = rewardInfo.reward_params;
4911
4994
  const distributeType = rewardInfo.reward_distribute_type;
@@ -4916,7 +4999,7 @@ function TokenInfo({ rewardInfo, chains }) {
4916
4999
  const isBrc20 = getIsBrc20(params.chain, params.token_address, chains);
4917
5000
  const totalAmount = formatTokenAmount(params.total_amount);
4918
5001
  const perAmount = params.per_amount;
4919
- const tokenNameDisplay = params.is_usdt_equal_amount ? `USD in ${params.token_name}` : params.token_name;
5002
+ const tokenNameDisplay = params.is_usdt_equal_amount ? t("usd_token_name", { token_name: params.token_name }) : params.token_name;
4920
5003
  const handleMouseEnter = () => {
4921
5004
  if (timeoutRef.current) {
4922
5005
  clearTimeout(timeoutRef.current);
@@ -4941,9 +5024,9 @@ function TokenInfo({ rewardInfo, chains }) {
4941
5024
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token", children: [
4942
5025
  isBlindBox && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token-blindbox", children: [
4943
5026
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-blindbox-icon", children: "✨" }),
4944
- /* @__PURE__ */ jsx("span", { children: "Smart Blind Box" })
5027
+ /* @__PURE__ */ jsx("span", { children: t("smart_blind_box") })
4945
5028
  ] }),
4946
- /* @__PURE__ */ jsx(BaseRow, { label: "Total Rewards Pool", children: /* @__PURE__ */ jsxs(Root2, { open, onOpenChange: setOpen, children: [
5029
+ /* @__PURE__ */ jsx(BaseRow, { label: t("total_rewards_pool"), children: /* @__PURE__ */ jsxs(Root2, { open, onOpenChange: setOpen, children: [
4947
5030
  /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
4948
5031
  "div",
4949
5032
  {
@@ -4976,12 +5059,11 @@ function TokenInfo({ rewardInfo, chains }) {
4976
5059
  onMouseEnter: handleMouseEnter,
4977
5060
  onMouseLeave: handleMouseLeave,
4978
5061
  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
- ] }),
5062
+ params.is_usdt_equal_amount && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: t("equivalent_amounts_token_name", {
5063
+ token_name: params.token_name
5064
+ }) }),
4983
5065
  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" }),
5066
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
4985
5067
  /* @__PURE__ */ jsxs(
4986
5068
  "button",
4987
5069
  {
@@ -5001,8 +5083,8 @@ function TokenInfo({ rewardInfo, chains }) {
5001
5083
  ) })
5002
5084
  ] }) }),
5003
5085
  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}` })
5086
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-label", children: t("rewards_per_winner") }),
5087
+ /* @__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
5088
  ] })
5007
5089
  ] });
5008
5090
  }
@@ -5015,6 +5097,7 @@ async function copyToClipboard$1(text) {
5015
5097
  }
5016
5098
  }
5017
5099
  function NftInfo({ rewardInfo, chains }) {
5100
+ const { t } = useQuestLocale();
5018
5101
  const portalContainer = useTaskOnPortalContainer();
5019
5102
  const params = rewardInfo.reward_params;
5020
5103
  const [open, setOpen] = useState(false);
@@ -5074,7 +5157,7 @@ function NftInfo({ rewardInfo, chains }) {
5074
5157
  children: [
5075
5158
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5076
5159
  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" }),
5160
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
5078
5161
  /* @__PURE__ */ jsxs(
5079
5162
  "button",
5080
5163
  {
@@ -5103,6 +5186,7 @@ async function copyToClipboard(text) {
5103
5186
  }
5104
5187
  }
5105
5188
  function MintedNftInfo({ rewardInfo, chains }) {
5189
+ const { t } = useQuestLocale();
5106
5190
  const portalContainer = useTaskOnPortalContainer();
5107
5191
  const params = rewardInfo.reward_params;
5108
5192
  const [open, setOpen] = useState(false);
@@ -5162,7 +5246,7 @@ function MintedNftInfo({ rewardInfo, chains }) {
5162
5246
  children: [
5163
5247
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5164
5248
  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" }),
5249
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-address-title", children: t("contract_address") }),
5166
5250
  /* @__PURE__ */ jsxs(
5167
5251
  "button",
5168
5252
  {
@@ -5195,8 +5279,9 @@ function CapInfo({ rewardInfo, chains }) {
5195
5279
  ) }) });
5196
5280
  }
5197
5281
  function WhitelistInfo({ rewardInfo, chains }) {
5282
+ const { t } = useQuestLocale();
5198
5283
  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(
5284
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-whitelist", children: /* @__PURE__ */ jsx(BaseRow, { label: t("whitelist"), children: params.chain && /* @__PURE__ */ jsx(
5200
5285
  ChainIcon,
5201
5286
  {
5202
5287
  chain: params.chain,
@@ -5207,9 +5292,10 @@ function WhitelistInfo({ rewardInfo, chains }) {
5207
5292
  ) }) });
5208
5293
  }
5209
5294
  function PointsInfo({ rewardInfo }) {
5295
+ const { t } = useQuestLocale();
5210
5296
  const params = rewardInfo.reward_params;
5211
5297
  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: [
5298
+ 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
5299
  params.points_icon && /* @__PURE__ */ jsx(
5214
5300
  "img",
5215
5301
  {
@@ -5223,21 +5309,23 @@ function PointsInfo({ rewardInfo }) {
5223
5309
  ] }) }) });
5224
5310
  }
5225
5311
  function ExpInfo({ rewardInfo }) {
5312
+ const { t } = useQuestLocale();
5226
5313
  const params = rewardInfo.reward_params;
5227
5314
  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: [
5315
+ 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
5316
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-amount", children: formattedAmount }),
5230
5317
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-label", children: "EXP" })
5231
5318
  ] }) }) });
5232
5319
  }
5233
5320
  function DiscordRoleInfo({ rewardInfo }) {
5321
+ const { t } = useQuestLocale();
5234
5322
  const params = rewardInfo.reward_params;
5235
5323
  const handleClick = () => {
5236
5324
  if (params.discord_server_url) {
5237
5325
  window.open(params.discord_server_url, "_blank", "noopener,noreferrer");
5238
5326
  }
5239
5327
  };
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: [
5328
+ 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
5329
  /* @__PURE__ */ jsx(
5242
5330
  "span",
5243
5331
  {
@@ -5247,7 +5335,7 @@ function DiscordRoleInfo({ rewardInfo }) {
5247
5335
  children: params.role_name
5248
5336
  }
5249
5337
  ),
5250
- params.not_official_discord && /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-discord-role-warning", children: "⚠️ Not Official" })
5338
+ params.not_official_discord && /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-discord-role-warning", children: t("official") })
5251
5339
  ] }) }) });
5252
5340
  }
5253
5341
  function TheReward({ rewardInfo, chains }) {
@@ -5281,6 +5369,7 @@ function WinnerCount({
5281
5369
  currentWinner,
5282
5370
  rankingLabel
5283
5371
  }) {
5372
+ const { t } = useQuestLocale();
5284
5373
  const maxWinners = rewardLayer.max_winners;
5285
5374
  if (howToSelectWinner === "OpenToAll") {
5286
5375
  return null;
@@ -5295,7 +5384,7 @@ function WinnerCount({
5295
5384
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-separator", children: "/" }),
5296
5385
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-total", children: maxWinners })
5297
5386
  ] }),
5298
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: "Available" })
5387
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: t("available") })
5299
5388
  ] });
5300
5389
  }
5301
5390
  case "PointRanking":
@@ -5306,11 +5395,12 @@ function WinnerCount({
5306
5395
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-count", children: maxWinners });
5307
5396
  }
5308
5397
  };
5309
- return /* @__PURE__ */ jsx(BaseRow, { label: "Winners", children: renderContent() });
5398
+ return /* @__PURE__ */ jsx(BaseRow, { label: t("winners"), children: renderContent() });
5310
5399
  }
5311
5400
  function GasStationProgress({
5312
5401
  gasStation
5313
5402
  }) {
5403
+ const { t } = useQuestLocale();
5314
5404
  if (!gasStation.gas_covered) {
5315
5405
  return null;
5316
5406
  }
@@ -5319,7 +5409,7 @@ function GasStationProgress({
5319
5409
  gasStation.used_gas_amount
5320
5410
  );
5321
5411
  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!" }),
5412
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-label", children: t("limited_spots_gas_free_claiming") }),
5323
5413
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-bar", children: /* @__PURE__ */ jsx(
5324
5414
  "div",
5325
5415
  {
@@ -5333,8 +5423,10 @@ function GasStationProgress({
5333
5423
  function NftPreview({
5334
5424
  imageUrl,
5335
5425
  mediaType = "Image",
5336
- alt = "NFT Preview"
5426
+ alt
5337
5427
  }) {
5428
+ const { t } = useQuestLocale();
5429
+ const previewAlt = alt || t("nft_preview");
5338
5430
  if (!imageUrl) {
5339
5431
  return null;
5340
5432
  }
@@ -5352,7 +5444,7 @@ function NftPreview({
5352
5444
  "img",
5353
5445
  {
5354
5446
  src: imageUrl,
5355
- alt,
5447
+ alt: previewAlt,
5356
5448
  className: "taskon-quest-rewards-preview-image",
5357
5449
  loading: "lazy"
5358
5450
  }
@@ -5368,18 +5460,19 @@ function EstimatedRewards({
5368
5460
  isEnded,
5369
5461
  finalReward
5370
5462
  }) {
5463
+ const { t } = useQuestLocale();
5371
5464
  const rewardLabel = useMemo(() => {
5372
5465
  if (!isEnded) {
5373
- return "Your Estimated Rewards";
5466
+ return t("estimated_rewards");
5374
5467
  }
5375
5468
  if (!isCompleted) {
5376
5469
  return "";
5377
5470
  }
5378
5471
  if (finalReward) {
5379
- return "Your Final Rewards";
5472
+ return t("final_rewards");
5380
5473
  }
5381
- return "Your Estimated Rewards";
5382
- }, [isEnded, isCompleted, finalReward]);
5474
+ return t("estimated_rewards");
5475
+ }, [isEnded, isCompleted, finalReward, t]);
5383
5476
  if (!rewardLabel) {
5384
5477
  return null;
5385
5478
  }
@@ -5409,24 +5502,15 @@ function EstimatedRewards({
5409
5502
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-symbol", children: rewardSymbol })
5410
5503
  ] })
5411
5504
  ] }),
5412
- /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-formula", children: [
5413
- "= Total Rewards Pool * Your ",
5414
- pointName,
5415
- " / Total ",
5505
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-formula", children: t("eq_total_rewards_pool_pointname_total_pointname", {
5416
5506
  pointName
5417
- ] }),
5507
+ }) }),
5418
5508
  /* @__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
- ] }),
5509
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-label", children: t("pointname", { pointName }) }),
5423
5510
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-points", children: formattedUserPoints })
5424
5511
  ] }),
5425
5512
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-total", children: [
5426
- /* @__PURE__ */ jsxs("span", { children: [
5427
- "Total ",
5428
- pointName
5429
- ] }),
5513
+ /* @__PURE__ */ jsx("span", { children: t("total_pointname", { pointName }) }),
5430
5514
  /* @__PURE__ */ jsx("span", { children: formattedTotalPoints })
5431
5515
  ] }),
5432
5516
  !isCompleted && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-mask", children: [
@@ -5438,29 +5522,31 @@ function EstimatedRewards({
5438
5522
  alt: ""
5439
5523
  }
5440
5524
  ),
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!" })
5525
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-title", children: t("complete_qualify_rewards") }),
5526
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-subtitle", children: t("once_qualified_every_point_counts_toward_better_rewards") })
5443
5527
  ] })
5444
5528
  ] });
5445
5529
  }
5446
5530
  function RankingPoint({
5447
5531
  userStatus,
5448
- pointsName = "Points"
5532
+ pointsName
5449
5533
  }) {
5450
5534
  var _a, _b;
5535
+ const { t } = useQuestLocale();
5536
+ const resolvedPointsName = pointsName || t("points");
5451
5537
  const ranking = userStatus.ranking;
5452
5538
  const tier = userStatus.tier;
5453
5539
  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;
5540
+ const displayPointsName = ((_b = userStatus.current_point) == null ? void 0 : _b.points_name) || resolvedPointsName;
5455
5541
  const hasValidRanking = ranking >= 0;
5456
5542
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point", children: [
5457
5543
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-row", children: [
5458
5544
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-label", children: [
5459
- "Your Ranking",
5545
+ t("ranking"),
5460
5546
  /* @__PURE__ */ jsx(
5461
5547
  TipPopover,
5462
5548
  {
5463
- content: "You will be ranked only after completing all mandatory tasks in this quest.",
5549
+ content: t("ranked_after_completing_mandatory_tasks_quest"),
5464
5550
  side: "top",
5465
5551
  className: "taskon-quest-rewards-ranking-point-tip-icon"
5466
5552
  }
@@ -5468,21 +5554,20 @@ function RankingPoint({
5468
5554
  ] }),
5469
5555
  hasValidRanking ? /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-value", children: [
5470
5556
  /* @__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
- ] })
5557
+ tier > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-tier", children: t("tier_index", { index: tier }) })
5558
+ ] }) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-tip", children: /* @__PURE__ */ jsx(
5559
+ I18nT,
5560
+ {
5561
+ t,
5562
+ i18nKey: "complete_required_tasks_secure_valid_ranking",
5563
+ components: {
5564
+ required: /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-tip-highlight", children: t("required") })
5565
+ }
5566
+ }
5567
+ ) })
5480
5568
  ] }),
5481
5569
  /* @__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
- ] }),
5570
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-label", children: t("pointname", { pointName: displayPointsName }) }),
5486
5571
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-amount", children: points })
5487
5572
  ] })
5488
5573
  ] });
@@ -5490,8 +5575,10 @@ function RankingPoint({
5490
5575
  function RewardBonus({
5491
5576
  extraBonus,
5492
5577
  qualifierRewards,
5493
- pointName = "Points"
5578
+ pointName
5494
5579
  }) {
5580
+ const { t } = useQuestLocale();
5581
+ const resolvedPointName = pointName || t("points");
5495
5582
  const qualifierPointParams = useMemo(() => {
5496
5583
  const pointsReward = qualifierRewards == null ? void 0 : qualifierRewards.find(
5497
5584
  (item) => item.reward_type === QuestRewardType.Points || item.reward_type === QuestRewardType.GTCPoints
@@ -5503,13 +5590,16 @@ function RewardBonus({
5503
5590
  return null;
5504
5591
  }
5505
5592
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus", children: [
5506
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: "Bonus" }),
5593
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: t("bonus") }),
5507
5594
  /* @__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: [
5595
+ extraBonus && /* @__PURE__ */ jsx(BaseRow, { label: t("winner_bonus"), children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-desc", children: extraBonus }) }),
5596
+ qualifierPointParams && /* @__PURE__ */ jsx(BaseRow, { label: t("qualifier_point"), children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus-value", children: [
5510
5597
  /* @__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" })
5598
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-name", children: qualifierPointParams.points_name || resolvedPointName }),
5599
+ /* @__PURE__ */ jsxs("span", { className: "taskon-quest-rewards-bonus-unit", children: [
5600
+ "/",
5601
+ t("qualifiers")
5602
+ ] })
5513
5603
  ] }) })
5514
5604
  ] })
5515
5605
  ] });
@@ -5718,10 +5808,7 @@ function formatLongStr$1(str, separator = "...", prefixLen = 6, suffixLen = 6) {
5718
5808
  if (str.length <= prefixLen + suffixLen + 2) return str;
5719
5809
  return `${str.slice(0, prefixLen)}${separator}${str.slice(-suffixLen)}`;
5720
5810
  }
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) {
5811
+ function getRewardTypeLabel(rewardType, pointsName, t) {
5725
5812
  if (!rewardType) return "";
5726
5813
  switch (rewardType) {
5727
5814
  case RewardType.Nft:
@@ -5729,21 +5816,21 @@ function getRewardTypeLabel(rewardType, pointsName) {
5729
5816
  case RewardType.Cap:
5730
5817
  return "NFT:";
5731
5818
  case RewardType.DiscordRole:
5732
- return "Discord Role:";
5819
+ return `${t("discord_role")}:`;
5733
5820
  case RewardType.Exp:
5734
5821
  return "EXP:";
5735
5822
  case RewardType.GTCPoints:
5736
5823
  case RewardType.Points:
5737
5824
  return `${pointsName}:`;
5738
5825
  case RewardType.Token:
5739
- return "Token:";
5826
+ return `${t("token_name")}:`;
5740
5827
  case RewardType.Whitelist:
5741
- return "Whitelist";
5828
+ return t("whitelist");
5742
5829
  default:
5743
5830
  return "";
5744
5831
  }
5745
5832
  }
5746
- function getRewardLabel(row) {
5833
+ function getRewardLabel(row, t) {
5747
5834
  const { rewardType, rewardSymbol, rewardAmount, chainLabel, isUsdtEqual } = row;
5748
5835
  if (!rewardType) {
5749
5836
  return rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : "";
@@ -5761,7 +5848,9 @@ function getRewardLabel(row) {
5761
5848
  return rewardAmount || "";
5762
5849
  case RewardType.Token:
5763
5850
  if (isUsdtEqual) {
5764
- return `${rewardAmount} USD in ${rewardSymbol}`;
5851
+ return `${rewardAmount || ""} ${t("usd_token_name", {
5852
+ token_name: rewardSymbol || ""
5853
+ })}`.trim();
5765
5854
  }
5766
5855
  return `${rewardAmount} ${rewardSymbol}${chainLabel ? ` ${chainLabel}` : ""}`;
5767
5856
  case RewardType.Whitelist:
@@ -5771,25 +5860,44 @@ function getRewardLabel(row) {
5771
5860
  }
5772
5861
  }
5773
5862
  function RewardCell({ row }) {
5863
+ const { t } = useQuestLocale();
5864
+ const translate = t;
5774
5865
  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" }) }) });
5866
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-reward-cell", children: /* @__PURE__ */ jsx(
5867
+ TipPopover,
5868
+ {
5869
+ content: t("qualified_rewards_tier"),
5870
+ side: "top",
5871
+ children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-not-qualified", children: t("qualified") })
5872
+ }
5873
+ ) });
5776
5874
  }
5777
5875
  if (!row.rewardAmount) {
5778
5876
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-no-reward", children: "--" });
5779
5877
  }
5780
- const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName);
5781
- const rewardLabel = getRewardLabel(row);
5878
+ const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName, translate);
5879
+ const rewardLabel = getRewardLabel(row, translate);
5782
5880
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-reward-cell", children: [
5783
5881
  typeLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward-type", children: typeLabel }),
5784
5882
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward", children: rewardLabel })
5785
5883
  ] });
5786
5884
  }
5787
5885
  function RankBadge({ rank }) {
5886
+ const { t } = useQuestLocale();
5788
5887
  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" }) }) });
5888
+ return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank taskon-quest-leaderboard-rank--unranked", children: /* @__PURE__ */ jsx(
5889
+ TipPopover,
5890
+ {
5891
+ content: t(
5892
+ "ranked_after_completing_mandatory_tasks_quest"
5893
+ ),
5894
+ side: "top",
5895
+ children: /* @__PURE__ */ jsx("span", { children: t("na") })
5896
+ }
5897
+ ) });
5790
5898
  }
5791
5899
  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" }) }) });
5900
+ 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
5901
  }
5794
5902
  if (rank === 1) {
5795
5903
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank", children: /* @__PURE__ */ jsx(Rank1Icon, { size: 24 }) });
@@ -5806,8 +5914,9 @@ function UserCell({
5806
5914
  userName,
5807
5915
  isCurrentUser
5808
5916
  }) {
5917
+ const { t } = useQuestLocale();
5809
5918
  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" }) });
5919
+ 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
5920
  }
5812
5921
  return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-user", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-user-name", children: formatLongStr$1(userName) }) });
5813
5922
  }
@@ -5834,10 +5943,12 @@ function LeaderboardModal({
5834
5943
  isOpen,
5835
5944
  onClose,
5836
5945
  campaignId,
5837
- pointsName = "Points",
5946
+ pointsName,
5838
5947
  className = ""
5839
5948
  }) {
5949
+ const { t } = useQuestLocale();
5840
5950
  const { client, userId } = useTaskOnContext();
5951
+ const resolvedPointsName = pointsName || t("points");
5841
5952
  const [data, setData] = useState(null);
5842
5953
  const [loading, setLoading] = useState(false);
5843
5954
  const [error, setError] = useState(null);
@@ -5856,11 +5967,11 @@ function LeaderboardModal({
5856
5967
  });
5857
5968
  setData(result);
5858
5969
  } catch (err) {
5859
- setError(err instanceof Error ? err.message : "Failed to load leaderboard");
5970
+ setError(err instanceof Error ? err.message : t("failed_load_leaderboard"));
5860
5971
  } finally {
5861
5972
  setLoading(false);
5862
5973
  }
5863
- }, [client, isOpen, campaignId, page]);
5974
+ }, [client, isOpen, campaignId, page, t]);
5864
5975
  useEffect(() => {
5865
5976
  if (isOpen) {
5866
5977
  fetchData();
@@ -5880,15 +5991,21 @@ function LeaderboardModal({
5880
5991
  if (!data) return 0;
5881
5992
  return Math.ceil(data.total / PAGE_SIZE);
5882
5993
  }, [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.`;
5994
+ const positionTip = t(
5995
+ "rankings_based_total_pointsname_earned_tasks_within_quest_instances",
5996
+ { pointsName: resolvedPointsName }
5997
+ );
5998
+ const tierTip = t("ranked_after_completing_mandatory_tasks_quest");
5999
+ const pointsTip = t(
6000
+ "pointsname_collected_tasks_completed_during_quest",
6001
+ { pointsName: resolvedPointsName }
6002
+ );
5886
6003
  const columns = useMemo(
5887
6004
  () => [
5888
6005
  {
5889
6006
  key: "rank",
5890
6007
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5891
- /* @__PURE__ */ jsx("span", { children: "Position" }),
6008
+ /* @__PURE__ */ jsx("span", { children: t("position") }),
5892
6009
  /* @__PURE__ */ jsx(TipPopover, { content: positionTip, side: "top" })
5893
6010
  ] }),
5894
6011
  width: 100,
@@ -5897,15 +6014,15 @@ function LeaderboardModal({
5897
6014
  {
5898
6015
  key: "tier",
5899
6016
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5900
- /* @__PURE__ */ jsx("span", { children: "Tier" }),
6017
+ /* @__PURE__ */ jsx("span", { children: t("tier") }),
5901
6018
  /* @__PURE__ */ jsx(TipPopover, { content: tierTip, side: "top" })
5902
6019
  ] }),
5903
6020
  width: 80,
5904
- render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-tier", children: row.tier !== void 0 && row.tier > 0 ? row.tier : "--" })
6021
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-tier", children: row.tier !== void 0 && row.tier > 0 ? row.tier : t("na") })
5905
6022
  },
5906
6023
  {
5907
6024
  key: "user",
5908
- title: "User",
6025
+ title: t("user"),
5909
6026
  minWidth: 120,
5910
6027
  render: (_, row) => /* @__PURE__ */ jsx(
5911
6028
  UserCell,
@@ -5918,21 +6035,21 @@ function LeaderboardModal({
5918
6035
  {
5919
6036
  key: "points",
5920
6037
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5921
- /* @__PURE__ */ jsx("span", { children: pointsName }),
6038
+ /* @__PURE__ */ jsx("span", { children: resolvedPointsName }),
5922
6039
  /* @__PURE__ */ jsx(TipPopover, { content: pointsTip, side: "top" })
5923
6040
  ] }),
5924
6041
  width: 100,
5925
- render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-points", children: row.points > 0 ? row.points.toLocaleString() : "--" })
6042
+ render: (_, row) => /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-points", children: row.points > 0 ? row.points.toLocaleString() : t("na") })
5926
6043
  },
5927
6044
  {
5928
6045
  key: "rewards",
5929
- title: "Rewards",
6046
+ title: t("rewards"),
5930
6047
  width: 150,
5931
6048
  align: "right",
5932
6049
  render: (_, row) => /* @__PURE__ */ jsx(RewardCell, { row })
5933
6050
  }
5934
6051
  ],
5935
- [pointsName, positionTip, pointsTip, tierTip, userId]
6052
+ [positionTip, pointsTip, resolvedPointsName, t, tierTip, userId]
5936
6053
  );
5937
6054
  const rowConfig = useMemo(
5938
6055
  () => ({
@@ -5961,19 +6078,20 @@ function LeaderboardModal({
5961
6078
  onOpenChange: (open) => {
5962
6079
  if (!open) onClose();
5963
6080
  },
5964
- title: "Leaderboard",
6081
+ title: t("leaderboard"),
5965
6082
  showCloseButton: true,
5966
6083
  className,
5967
6084
  maxWidth: 600,
5968
6085
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-content", children: [
5969
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: "Leaderboard" }),
6086
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: t("leaderboard") }),
5970
6087
  data && /* @__PURE__ */ jsxs("p", { className: "taskon-quest-leaderboard-subtitle", children: [
5971
6088
  data.total_user.toLocaleString(),
5972
- " participants"
6089
+ " ",
6090
+ t("participants_2")
5973
6091
  ] }),
5974
6092
  error && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-error", children: [
5975
6093
  /* @__PURE__ */ jsx("p", { children: error }),
5976
- /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: "Retry" })
6094
+ /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: t("retry") })
5977
6095
  ] }),
5978
6096
  !error && /* @__PURE__ */ jsx(
5979
6097
  Table,
@@ -5982,10 +6100,10 @@ function LeaderboardModal({
5982
6100
  data: tableData,
5983
6101
  rowConfig,
5984
6102
  loading,
5985
- loadingText: "Loading...",
6103
+ loadingText: t("loading"),
5986
6104
  empty: {
5987
- title: "No Data",
5988
- description: "No participants yet"
6105
+ title: t("no_data"),
6106
+ description: t("no_participants")
5989
6107
  },
5990
6108
  striped: true,
5991
6109
  className: "taskon-quest-leaderboard-table"
@@ -6041,14 +6159,19 @@ function RewardCard$1({
6041
6159
  chains
6042
6160
  }) {
6043
6161
  var _a, _b, _c;
6162
+ const { t } = useQuestLocale();
6044
6163
  const [isDescOpen, setIsDescOpen] = useState(false);
6045
6164
  const isPointRanking = howToSelectWinner === "PointRanking";
6046
6165
  const ranking = (_a = rewardLayer.winner_layer) == null ? void 0 : _a.winner_rank_range;
6047
6166
  const rankingLabel = useMemo(() => {
6048
6167
  if (!ranking) return "";
6049
- return formatRankingLabel(ranking);
6050
- }, [ranking]);
6051
- const tierLabel = getTierLabel(layerIndex, isCurrentLayer);
6168
+ return formatRankingLabel(ranking, t);
6169
+ }, [ranking, t]);
6170
+ const tierLabel = getTierLabel(
6171
+ layerIndex,
6172
+ isCurrentLayer,
6173
+ t
6174
+ );
6052
6175
  const showEstimatedRewards = useMemo(() => {
6053
6176
  return rewardInfo.reward_distribute_type === QuestRewardsDistributeType.PointProportionally && totalPoints !== -1;
6054
6177
  }, [rewardInfo.reward_distribute_type, totalPoints]);
@@ -6139,7 +6262,7 @@ function RewardCard$1({
6139
6262
  className: "taskon-quest-rewards-whitelist-desc-trigger",
6140
6263
  onClick: () => setIsDescOpen(!isDescOpen),
6141
6264
  type: "button",
6142
- children: /* @__PURE__ */ jsx(BaseRow, { label: "Whitelist Description", children: /* @__PURE__ */ jsx(
6265
+ children: /* @__PURE__ */ jsx(BaseRow, { label: t("whitelist_description"), children: /* @__PURE__ */ jsx(
6143
6266
  UnfoldIcon,
6144
6267
  {
6145
6268
  className: `taskon-quest-rewards-whitelist-desc-icon ${isDescOpen ? "taskon-quest-rewards-whitelist-desc-icon--open" : ""}`
@@ -6179,12 +6302,13 @@ function WinnerGroup({
6179
6302
  groupIndex,
6180
6303
  chains
6181
6304
  }) {
6305
+ const { t } = useQuestLocale();
6182
6306
  const howToSelectWinner = useMemo(() => {
6183
6307
  return getHowToSelectWinner$1(group);
6184
6308
  }, [group]);
6185
6309
  const winnerSelectionLabel = useMemo(() => {
6186
- return getWinnerSelectionLabel$1(howToSelectWinner);
6187
- }, [howToSelectWinner]);
6310
+ return t(getWinnerSelectionLabel$1(howToSelectWinner));
6311
+ }, [howToSelectWinner, t]);
6188
6312
  const getTotalPoints = (layerIndex) => {
6189
6313
  if (group.automatically_winner_draw_type !== QuestAutomaticallyWinnerDrawType.PointRank) {
6190
6314
  return (userStatus == null ? void 0 : userStatus.open_to_all_total_points) || 0;
@@ -6230,12 +6354,14 @@ function QuestRewards({
6230
6354
  winnerRewards,
6231
6355
  campaignStatus,
6232
6356
  userStatus,
6233
- pointName = "Points",
6357
+ pointName,
6234
6358
  isEnded,
6235
6359
  isOngoingOrEnded = false,
6236
6360
  chains
6237
6361
  }) {
6238
6362
  var _a;
6363
+ const { t } = useQuestLocale();
6364
+ const resolvedPointName = pointName || t("points");
6239
6365
  const [isLeaderboardOpen, setIsLeaderboardOpen] = useState(false);
6240
6366
  if (!winnerRewards || winnerRewards.length === 0) {
6241
6367
  return null;
@@ -6252,7 +6378,7 @@ function QuestRewards({
6252
6378
  };
6253
6379
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards", children: [
6254
6380
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-container", children: [
6255
- showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: pointName }),
6381
+ showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: resolvedPointName }),
6256
6382
  showViewLeaderboard && /* @__PURE__ */ jsxs(
6257
6383
  "button",
6258
6384
  {
@@ -6260,7 +6386,7 @@ function QuestRewards({
6260
6386
  className: "taskon-quest-rewards-view-leaderboard",
6261
6387
  onClick: handleOpenLeaderboard,
6262
6388
  children: [
6263
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-text", children: "View Leaderboard" }),
6389
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-text", children: t("view_leaderboard") }),
6264
6390
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-arrow", children: "→" })
6265
6391
  ]
6266
6392
  }
@@ -6270,7 +6396,7 @@ function QuestRewards({
6270
6396
  {
6271
6397
  group,
6272
6398
  currentWinners,
6273
- pointName,
6399
+ pointName: resolvedPointName,
6274
6400
  isEnded,
6275
6401
  userStatus,
6276
6402
  groupIndex,
@@ -6285,7 +6411,7 @@ function QuestRewards({
6285
6411
  isOpen: isLeaderboardOpen,
6286
6412
  onClose: handleCloseLeaderboard,
6287
6413
  campaignId,
6288
- pointsName: pointName
6414
+ pointsName: resolvedPointName
6289
6415
  }
6290
6416
  )
6291
6417
  ] });
@@ -6365,26 +6491,29 @@ function getHowToSelectWinner(winnerReward) {
6365
6491
  function getWinnerSelectionLabel(howToSelectWinner) {
6366
6492
  switch (howToSelectWinner) {
6367
6493
  case 1:
6368
- return { label: "Lucky Draw", desc: "Winners are randomly selected" };
6494
+ return { label: "lucky_draw", desc: "winners_randomly_selected" };
6369
6495
  case 0:
6370
6496
  return {
6371
- label: "FCFS",
6372
- desc: "First to complete gets the reward"
6497
+ label: "fcfs",
6498
+ desc: "first_complete_gets_reward"
6373
6499
  };
6374
6500
  case 4:
6375
6501
  return {
6376
- label: "Open to All",
6377
- desc: "All qualified users receive reward"
6502
+ label: "open",
6503
+ desc: "qualified_users_receive_reward"
6378
6504
  };
6379
6505
  case 3:
6380
- return { label: "Ranking", desc: "Top ranked users win" };
6506
+ return { label: "ranking_2", desc: "top_ranked_users_win" };
6381
6507
  case 2:
6382
6508
  return {
6383
- label: "Manually Upload",
6384
- desc: "Project owner selects winners"
6509
+ label: "manually_upload",
6510
+ desc: "project_owner_selects_winners"
6385
6511
  };
6386
6512
  default:
6387
- return { label: "", desc: "" };
6513
+ return {
6514
+ label: "fcfs",
6515
+ desc: "first_complete_gets_reward"
6516
+ };
6388
6517
  }
6389
6518
  }
6390
6519
  function getEarnedWinnerSelectionList(winnerRewards, userStatus, campaignStatus) {
@@ -6530,52 +6659,52 @@ function getStatusCardConfig(status, params) {
6530
6659
  case "winner":
6531
6660
  return {
6532
6661
  badgeType: "winner",
6533
- title: "Congratulations!"
6662
+ title: "congratulations"
6534
6663
  };
6535
6664
  case "blind-box-failed":
6536
6665
  case "qualifier-failed":
6537
6666
  return {
6538
6667
  badgeType: "qualifier",
6539
- title: "Oops! Better Luck Next Time!",
6540
- description: "You have won multiple rewards!"
6668
+ title: "oops_better_luck_next_time",
6669
+ description: "won_multiple_rewards"
6541
6670
  // Will be overridden if has rewards
6542
6671
  };
6543
6672
  case "qualifier-wait":
6544
6673
  if (params == null ? void 0 : params.hasLegacyManual) {
6545
6674
  return {
6546
6675
  badgeType: "qualifier",
6547
- title: "Successfully Entered!",
6548
- description: "Waiting for project owner to upload the winner list. Stay tuned to see if you win!"
6676
+ title: "successfully_entered",
6677
+ description: "waiting_project_owner_upload_winner_list_stay_tuned_see_2"
6549
6678
  };
6550
6679
  }
6551
6680
  if (params == null ? void 0 : params.hasPointRanking) {
6552
6681
  return {
6553
6682
  badgeType: "qualifier",
6554
- title: "Successfully Entered!",
6555
- description: "Waiting for final ranking. Stay tuned to see if you win!"
6683
+ title: "successfully_entered",
6684
+ description: "waiting_final_ranking_stay_tuned_see_win_2"
6556
6685
  };
6557
6686
  }
6558
6687
  return {
6559
6688
  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!"
6689
+ title: "waiting_drawing_winners",
6690
+ description: "please_keep_participating_tasks_e_g_keep_following_x"
6562
6691
  };
6563
6692
  case "submitter-failed":
6564
6693
  return {
6565
6694
  badgeType: "submitter",
6566
- title: "Oops!",
6567
- description: "Not all tasks are successfully verified, better luck next time!"
6695
+ title: "oops",
6696
+ description: "tasks_successfully_verified_better_luck_next_time"
6568
6697
  };
6569
6698
  case "submitter-wait":
6570
6699
  return {
6571
6700
  badgeType: "submitter",
6572
- title: "Waiting For Task Verification",
6573
- description: "Stay tuned! Only verified users are eligible to compete for rewards."
6701
+ title: "waiting_task_verification",
6702
+ description: "stay_tuned_verified_users_eligible_compete_rewards"
6574
6703
  };
6575
6704
  case "too-late":
6576
6705
  return {
6577
- title: "Oops!",
6578
- description: "Sorry you are late."
6706
+ title: "oops",
6707
+ description: "sorry_late"
6579
6708
  };
6580
6709
  case "can-complete":
6581
6710
  return null;
@@ -6616,6 +6745,7 @@ function RewardToken({
6616
6745
  rewardDisplayMode = "popup",
6617
6746
  rewardRedirectUrl
6618
6747
  }) {
6748
+ const { t } = useQuestLocale();
6619
6749
  const [popupOpen, setPopupOpen] = useState(false);
6620
6750
  const params = reward.reward_value;
6621
6751
  const chainInfo = useMemo(() => {
@@ -6639,10 +6769,10 @@ function RewardToken({
6639
6769
  }, [params.amount]);
6640
6770
  const typeText = useMemo(() => {
6641
6771
  if (params.is_usdt_equal_amount) {
6642
- return `USD in ${params.token_name}`;
6772
+ return t("usd_token_name", { token_name: params.token_name });
6643
6773
  }
6644
6774
  return params.token_name;
6645
- }, [params.is_usdt_equal_amount, params.token_name]);
6775
+ }, [params.is_usdt_equal_amount, params.token_name, t]);
6646
6776
  const showAmountNotRevealed = !params.amount;
6647
6777
  const showWithdraw = isDeposited && params.amount;
6648
6778
  const handleWithdraw = useCallback(() => {
@@ -6667,9 +6797,9 @@ function RewardToken({
6667
6797
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: formattedAmount })
6668
6798
  ] }),
6669
6799
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: typeText }),
6670
- showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: "Withdraw" })
6800
+ showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: t("withdraw") })
6671
6801
  ] }),
6672
- showAmountNotRevealed && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "Reward amount will be revealed once quest ends." })
6802
+ showAmountNotRevealed && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("reward_amount_revealed_once_quest_ends") })
6673
6803
  ] }),
6674
6804
  /* @__PURE__ */ jsx(
6675
6805
  RewardModuleDialog,
@@ -6745,6 +6875,7 @@ function RewardNft({
6745
6875
  onRefresh,
6746
6876
  onClaimNft
6747
6877
  }) {
6878
+ const { t } = useQuestLocale();
6748
6879
  const [loading, setLoading] = useState(false);
6749
6880
  const params = reward.reward_value;
6750
6881
  const chainInfo = useMemo(() => {
@@ -6786,10 +6917,10 @@ function RewardNft({
6786
6917
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6787
6918
  ] }),
6788
6919
  /* @__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" })
6920
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6790
6921
  ] }),
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:" }),
6922
+ 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: [
6923
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: t("txn_hash") }),
6793
6924
  /* @__PURE__ */ jsx(
6794
6925
  "a",
6795
6926
  {
@@ -6810,6 +6941,7 @@ function RewardMintedNft({
6810
6941
  onRefresh,
6811
6942
  onClaimNft
6812
6943
  }) {
6944
+ const { t } = useQuestLocale();
6813
6945
  const [loading, setLoading] = useState(false);
6814
6946
  const params = reward.reward_value;
6815
6947
  const chainInfo = useMemo(() => {
@@ -6854,10 +6986,10 @@ function RewardMintedNft({
6854
6986
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6855
6987
  ] }),
6856
6988
  /* @__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" })
6989
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6858
6990
  ] }),
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:" }),
6991
+ 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: [
6992
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-reward-tx-label", children: t("txn_hash") }),
6861
6993
  /* @__PURE__ */ jsx(
6862
6994
  "a",
6863
6995
  {
@@ -6869,7 +7001,7 @@ function RewardMintedNft({
6869
7001
  }
6870
7002
  )
6871
7003
  ] }),
6872
- isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: "NFT will be airdropped soon..." })
7004
+ isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("nft_airdropped_soon") })
6873
7005
  ] });
6874
7006
  }
6875
7007
  function RewardCap({
@@ -6879,6 +7011,7 @@ function RewardCap({
6879
7011
  onRefresh,
6880
7012
  onClaimNft
6881
7013
  }) {
7014
+ const { t } = useQuestLocale();
6882
7015
  const [loading, setLoading] = useState(false);
6883
7016
  const params = reward.reward_value;
6884
7017
  const chainInfo = useMemo(() => {
@@ -6917,18 +7050,19 @@ function RewardCap({
6917
7050
  className: "taskon-quest-footer-earned-single-icon"
6918
7051
  }
6919
7052
  ),
6920
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Cap" })
7053
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "CAP" })
6921
7054
  ] }),
6922
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
7055
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6923
7056
  ] }),
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..." })
7057
+ elementLink && /* @__PURE__ */ jsx(ActionButton, { href: elementLink, children: t("check_cap_element") }),
7058
+ isGasStationDropping && /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-reward-dropping", children: t("cap_airdropped_soon") })
6926
7059
  ] });
6927
7060
  }
6928
7061
  function RewardWhitelist({
6929
7062
  reward,
6930
7063
  chains
6931
7064
  }) {
7065
+ const { t } = useQuestLocale();
6932
7066
  const params = reward.reward_value;
6933
7067
  const chainInfo = useMemo(() => {
6934
7068
  if (!chains || !params.chain) return null;
@@ -6943,7 +7077,7 @@ function RewardWhitelist({
6943
7077
  className: "taskon-quest-footer-earned-single-icon"
6944
7078
  }
6945
7079
  ),
6946
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "Whitelist" })
7080
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: t("whitelist") })
6947
7081
  ] }) }) });
6948
7082
  }
6949
7083
  function RewardPoint({
@@ -6951,14 +7085,15 @@ function RewardPoint({
6951
7085
  rewardDisplayMode = "popup",
6952
7086
  rewardRedirectUrl
6953
7087
  }) {
7088
+ const { t } = useQuestLocale();
6954
7089
  const [popupOpen, setPopupOpen] = useState(false);
6955
7090
  const params = reward.reward_value;
6956
7091
  const pointName = useMemo(() => {
6957
7092
  if (reward.reward_type === RewardType.GTCPoints) {
6958
- return params.points_name || "Points";
7093
+ return params.points_name || t("points");
6959
7094
  }
6960
- return "Points";
6961
- }, [reward.reward_type, params.points_name]);
7095
+ return t("points");
7096
+ }, [reward.reward_type, params.points_name, t]);
6962
7097
  const handlePointsHistory = useCallback(() => {
6963
7098
  if (rewardDisplayMode === "redirect" && rewardRedirectUrl) {
6964
7099
  window.open(rewardRedirectUrl, "_blank", "noopener,noreferrer");
@@ -6973,7 +7108,7 @@ function RewardPoint({
6973
7108
  /* @__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
7109
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: pointName })
6975
7110
  ] }),
6976
- /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: "Points History" })
7111
+ /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: t("points_history") })
6977
7112
  ] }),
6978
7113
  /* @__PURE__ */ jsx(
6979
7114
  RewardModuleDialog,
@@ -6992,6 +7127,7 @@ function RewardDiscordRole({
6992
7127
  onRefresh,
6993
7128
  onClaimDiscordRole
6994
7129
  }) {
7130
+ const { t } = useQuestLocale();
6995
7131
  const [loading, setLoading] = useState(false);
6996
7132
  const params = reward.reward_value;
6997
7133
  const isClaimable = useMemo(() => {
@@ -7013,9 +7149,9 @@ function RewardDiscordRole({
7013
7149
  }
7014
7150
  }, [onClaimDiscordRole, reward, layer, onRefresh]);
7015
7151
  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" }) }),
7152
+ /* @__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
7153
  /* @__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" })
7154
+ isClaimable ? /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") }) : /* @__PURE__ */ jsx(ClaimButton, { disabled: true, children: t("claimed") })
7019
7155
  ] }) });
7020
7156
  }
7021
7157
  const REWARD_COMPONENT_MAP = {
@@ -7039,24 +7175,24 @@ function RewardItem(props) {
7039
7175
  }
7040
7176
  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
7177
  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) {
7178
+ function getFailedLabel(status, t) {
7043
7179
  if (status === "join-earlier") {
7044
- return "Join the quest earlier next time!";
7180
+ return t("join_quest_earlier_next_time");
7045
7181
  }
7046
7182
  if (status === "better-luck") {
7047
- return "Oops, Better Luck Next Time!";
7183
+ return t("oops_better_luck_next_time_2");
7048
7184
  }
7049
7185
  return "";
7050
7186
  }
7051
- function getWaitLabel(status) {
7187
+ function getWaitLabel(status, t) {
7052
7188
  if (status === "wait-draw") {
7053
- return "Waiting for drawing winners, Stay tuned to see if you win!";
7189
+ return t("waiting_drawing_winners_stay_tuned_see_win");
7054
7190
  }
7055
7191
  if (status === "wait-upload") {
7056
- return "Waiting for project owner to upload the winner list, Stay tuned to see if you win!";
7192
+ return t("waiting_project_owner_upload_winner_list_stay_tuned_see");
7057
7193
  }
7058
7194
  if (status === "wait-ranking") {
7059
- return "Waiting For Final Ranking, Stay tuned to see if you win!";
7195
+ return t("waiting_final_ranking_stay_tuned_see_win");
7060
7196
  }
7061
7197
  return "";
7062
7198
  }
@@ -7072,12 +7208,14 @@ function SelectionItem({
7072
7208
  rewardDisplayMode,
7073
7209
  rewardRedirectUrl
7074
7210
  }) {
7211
+ const { t } = useQuestLocale();
7075
7212
  const { howToSelectWinner, status, rewards } = selection;
7076
7213
  const label = getWinnerSelectionLabel(howToSelectWinner);
7077
- const failedLabel = getFailedLabel(status);
7078
- const waitLabel = getWaitLabel(status);
7214
+ const translate = t;
7215
+ const failedLabel = getFailedLabel(status, translate);
7216
+ const waitLabel = getWaitLabel(status, translate);
7079
7217
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-item", children: [
7080
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-selection-label", children: label.label }),
7218
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-selection-label", children: t(label.label) }),
7081
7219
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-rewards", children: [
7082
7220
  status === "winner" && rewards.map((layer) => /* @__PURE__ */ jsx(React__default.Fragment, { children: layer.reward.map((reward) => /* @__PURE__ */ jsx(
7083
7221
  RewardItem,
@@ -7136,6 +7274,7 @@ function DetailPanelDialog({
7136
7274
  rewardDisplayMode,
7137
7275
  rewardRedirectUrl
7138
7276
  }) {
7277
+ const { t } = useQuestLocale();
7139
7278
  const winnerSelectionList = useMemo(() => {
7140
7279
  return getEarnedWinnerSelectionList(
7141
7280
  campaign.winner_rewards,
@@ -7147,7 +7286,7 @@ function DetailPanelDialog({
7147
7286
  const qualifierRewards = campaign.qualifier_rewards;
7148
7287
  if (!qualifierRewards) return null;
7149
7288
  const reward = qualifierRewards.find(
7150
- (item) => item.reward_type === "Points" || item.reward_type === "GTCPoints"
7289
+ (item) => item.reward_type === "points" || item.reward_type === "GTCPoints"
7151
7290
  );
7152
7291
  if (!reward) return null;
7153
7292
  return reward.reward_params;
@@ -7157,12 +7296,12 @@ function DetailPanelDialog({
7157
7296
  {
7158
7297
  open,
7159
7298
  onOpenChange,
7160
- title: "Multiple Rewards Detail",
7299
+ title: t("multiple_rewards_detail"),
7161
7300
  showCloseButton: true,
7162
7301
  maxWidth: 480,
7163
7302
  contentClassName: "taskon-quest-footer-detail-dialog",
7164
7303
  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" }),
7304
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-footer-detail-title", children: t("multiple_rewards_detail") }),
7166
7305
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-content", children: winnerSelectionList.map((item, index) => /* @__PURE__ */ jsx(
7167
7306
  SelectionItem,
7168
7307
  {
@@ -7180,13 +7319,11 @@ function DetailPanelDialog({
7180
7319
  index
7181
7320
  )) }),
7182
7321
  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
- ] }) })
7322
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-label", children: t("bonus") }),
7323
+ /* @__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", {
7324
+ amount: qualifierPointParams.amount,
7325
+ pointsName: qualifierPointParams.points_name || t("points")
7326
+ }) }) })
7190
7327
  ] })
7191
7328
  ] })
7192
7329
  }
@@ -7206,6 +7343,7 @@ function EarnedRewards({
7206
7343
  rewardDisplayMode = "popup",
7207
7344
  rewardRedirectUrl
7208
7345
  }) {
7346
+ const { t } = useQuestLocale();
7209
7347
  const [dialogOpen, setDialogOpen] = useState(false);
7210
7348
  const rewardCount = useMemo(() => {
7211
7349
  return earnedRewards.reduce(
@@ -7234,8 +7372,8 @@ function EarnedRewards({
7234
7372
  hasMultiReward ? (
7235
7373
  // Multiple rewards: show text + button
7236
7374
  /* @__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" })
7375
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-multi-text", children: t("won_multiple_rewards") }),
7376
+ /* @__PURE__ */ jsx(ClaimButton, { onClick: handleOpenDialog, children: t("check_claim") })
7239
7377
  ] })
7240
7378
  ) : (
7241
7379
  // Single reward: show detailed card
@@ -7277,7 +7415,13 @@ function EarnedRewards({
7277
7415
  ] });
7278
7416
  }
7279
7417
  function StatusBadge({ type }) {
7280
- const badgeText = type.toUpperCase();
7418
+ const { t } = useQuestLocale();
7419
+ const badgeTextMap = {
7420
+ winner: t("winners"),
7421
+ qualifier: t("qualifiers"),
7422
+ submitter: t("submitters")
7423
+ };
7424
+ const badgeText = badgeTextMap[type];
7281
7425
  return /* @__PURE__ */ jsx("div", { className: `taskon-quest-footer-badge taskon-quest-footer-badge--${type}`, children: badgeText });
7282
7426
  }
7283
7427
  function StatusCard(props) {
@@ -7329,19 +7473,21 @@ function StatusCard(props) {
7329
7473
  ) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-card-message", children: description }) })
7330
7474
  ] });
7331
7475
  }
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) {
7476
+ function normalizeCompleteSubmitError(error, t) {
7335
7477
  if (error instanceof ApiError) {
7336
7478
  if (error.code === ErrorCode.RUSER_REPEAT_SUBMIT) {
7337
- return new ApiError(error.code, REPEAT_SUBMIT_ERROR_MESSAGE, error.data);
7479
+ return new ApiError(
7480
+ error.code,
7481
+ t("oops_seems_like_already_finished_quest_2"),
7482
+ error.data
7483
+ );
7338
7484
  }
7339
7485
  return error;
7340
7486
  }
7341
7487
  if (error instanceof Error) {
7342
7488
  return error;
7343
7489
  }
7344
- return new Error(DEFAULT_COMPLETE_ERROR_MESSAGE);
7490
+ return new Error(t("failed_complete_quest"));
7345
7491
  }
7346
7492
  function CompleteButton({
7347
7493
  campaignId,
@@ -7354,13 +7500,14 @@ function CompleteButton({
7354
7500
  className,
7355
7501
  onBeforeComplete
7356
7502
  }) {
7503
+ const { t } = useQuestLocale();
7357
7504
  const [isLoading, setIsLoading] = useState(false);
7358
7505
  const { client } = useTaskOnContext();
7359
7506
  const api = useMemo(() => {
7360
7507
  if (!client) return null;
7361
7508
  return createQuestApi(client);
7362
7509
  }, [client]);
7363
- const buttonText = hasPointProportionally2 ? "Complete to qualify for rewards!" : "Complete";
7510
+ const buttonText = hasPointProportionally2 ? t("complete_qualify_rewards") : t("complete_2");
7364
7511
  const handleComplete = useCallback(async () => {
7365
7512
  if (!api || isLoading || disabled) {
7366
7513
  return;
@@ -7379,7 +7526,7 @@ function CompleteButton({
7379
7526
  }
7380
7527
  }
7381
7528
  if (requiresRecaptcha && !captchaToken) {
7382
- onError == null ? void 0 : onError(new Error("reCAPTCHA verification required"));
7529
+ onError == null ? void 0 : onError(new Error(t("recaptcha_verification_required")));
7383
7530
  return;
7384
7531
  }
7385
7532
  try {
@@ -7391,7 +7538,10 @@ function CompleteButton({
7391
7538
  });
7392
7539
  onComplete == null ? void 0 : onComplete();
7393
7540
  } catch (error) {
7394
- const normalizedError = normalizeCompleteSubmitError(error);
7541
+ const normalizedError = normalizeCompleteSubmitError(
7542
+ error,
7543
+ t
7544
+ );
7395
7545
  onError == null ? void 0 : onError(normalizedError);
7396
7546
  }
7397
7547
  } finally {
@@ -7406,7 +7556,8 @@ function CompleteButton({
7406
7556
  onBeforeComplete,
7407
7557
  onComplete,
7408
7558
  onError,
7409
- requiresRecaptcha
7559
+ requiresRecaptcha,
7560
+ t
7410
7561
  ]);
7411
7562
  return /* @__PURE__ */ jsx(
7412
7563
  "button",
@@ -7417,15 +7568,13 @@ function CompleteButton({
7417
7568
  disabled: disabled || isLoading || !api,
7418
7569
  children: isLoading ? /* @__PURE__ */ jsxs("span", { className: "taskon-quest-footer-complete-btn-loading", children: [
7419
7570
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-complete-btn-spinner" }),
7420
- "Completing..."
7571
+ t("completing")
7421
7572
  ] }) : buttonText
7422
7573
  }
7423
7574
  );
7424
7575
  }
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
7576
  function OperateFooter(props) {
7577
+ const { t } = useQuestLocale();
7429
7578
  const {
7430
7579
  campaign,
7431
7580
  userStatus,
@@ -7486,12 +7635,22 @@ function OperateFooter(props) {
7486
7635
  hasPointRanking: hasRanking
7487
7636
  });
7488
7637
  }, [participationStatus, hasLegacyManual, hasRanking]);
7638
+ const localizedCardConfig = useMemo(() => {
7639
+ if (!cardConfig) {
7640
+ return null;
7641
+ }
7642
+ return {
7643
+ ...cardConfig,
7644
+ title: t(cardConfig.title),
7645
+ description: cardConfig.description ? t(cardConfig.description) : void 0
7646
+ };
7647
+ }, [cardConfig, t]);
7489
7648
  const renderConnectWallet = () => /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-connect", children: /* @__PURE__ */ jsx(
7490
7649
  "button",
7491
7650
  {
7492
7651
  className: "taskon-quest-footer-connect-btn",
7493
7652
  onClick: onConnectWallet,
7494
- children: "Connect Wallet to Participate"
7653
+ children: t("connect_wallet_participate")
7495
7654
  }
7496
7655
  ) });
7497
7656
  const handleCompleteError = useCallback(
@@ -7517,13 +7676,13 @@ function OperateFooter(props) {
7517
7676
  }
7518
7677
  );
7519
7678
  const renderStatusCard = () => {
7520
- if (!cardConfig) return null;
7679
+ if (!localizedCardConfig) return null;
7521
7680
  return /* @__PURE__ */ jsx(
7522
7681
  StatusCard,
7523
7682
  {
7524
- title: cardConfig.title,
7525
- badgeType: cardConfig.badgeType,
7526
- description: cardConfig.description,
7683
+ title: localizedCardConfig.title,
7684
+ badgeType: localizedCardConfig.badgeType,
7685
+ description: localizedCardConfig.description,
7527
7686
  campaign,
7528
7687
  userStatus: userStatus || void 0,
7529
7688
  campaignStatus: campaignStatus || void 0,
@@ -7545,12 +7704,16 @@ function OperateFooter(props) {
7545
7704
  open: isRepeatSubmitDialogVisible,
7546
7705
  onOpenChange: setIsRepeatSubmitDialogVisible,
7547
7706
  type: "warn",
7548
- title: REPEAT_SUBMIT_NOTICE_TITLE,
7549
- desc: REPEAT_SUBMIT_NOTICE_DESC,
7550
- confirmButton: REPEAT_SUBMIT_NOTICE_CONFIRM,
7707
+ title: t("oops_seems_like_already_finished_quest"),
7708
+ desc: t(
7709
+ "ensure_fair_experience_submissions_identical_wallet_addresses_x_discord"
7710
+ ),
7711
+ confirmButton: t("confirm"),
7551
7712
  onConfirm: () => setIsRepeatSubmitDialogVisible(false),
7552
- accessibilityTitle: REPEAT_SUBMIT_NOTICE_TITLE,
7553
- accessibilityDescription: REPEAT_SUBMIT_NOTICE_DESC
7713
+ accessibilityTitle: t("oops_seems_like_already_finished_quest"),
7714
+ accessibilityDescription: t(
7715
+ "ensure_fair_experience_submissions_identical_wallet_addresses_x_discord"
7716
+ )
7554
7717
  }
7555
7718
  );
7556
7719
  let footerContent = null;
@@ -7558,7 +7721,7 @@ function OperateFooter(props) {
7558
7721
  footerContent = renderConnectWallet();
7559
7722
  } else if (participationStatus === "can-complete") {
7560
7723
  footerContent = renderCompleteButton();
7561
- } else if (participationStatus !== "none" && cardConfig) {
7724
+ } else if (participationStatus !== "none" && localizedCardConfig) {
7562
7725
  footerContent = renderStatusCard();
7563
7726
  }
7564
7727
  if (!footerContent && !isRepeatSubmitDialogVisible) {
@@ -7569,16 +7732,16 @@ function OperateFooter(props) {
7569
7732
  renderRepeatSubmitNoticeDialog()
7570
7733
  ] });
7571
7734
  }
7572
- function getDialogTitle(errorType) {
7735
+ function getDialogTitle(errorType, t) {
7573
7736
  switch (errorType) {
7574
7737
  case "mandatory":
7575
- return "Tasks Incomplete";
7738
+ return t("tasks_incomplete");
7576
7739
  case "optional_count":
7577
- return "More Tasks Required";
7740
+ return t("tasks_required");
7578
7741
  case "optional_points":
7579
- return "More Points Required";
7742
+ return t("points_required");
7580
7743
  default:
7581
- return "Validation Failed";
7744
+ return t("validation_failed");
7582
7745
  }
7583
7746
  }
7584
7747
  function getDialogIcon(errorType) {
@@ -7612,6 +7775,7 @@ function TaskValidationDialog({
7612
7775
  error,
7613
7776
  onClose
7614
7777
  }) {
7778
+ const { t } = useQuestLocale();
7615
7779
  return /* @__PURE__ */ jsx(
7616
7780
  Dialog,
7617
7781
  {
@@ -7621,32 +7785,29 @@ function TaskValidationDialog({
7621
7785
  onClose();
7622
7786
  }
7623
7787
  },
7624
- title: getDialogTitle(error == null ? void 0 : error.type),
7788
+ title: getDialogTitle(
7789
+ error == null ? void 0 : error.type,
7790
+ t
7791
+ ),
7625
7792
  showCloseButton: true,
7626
7793
  maxWidth: 400,
7627
7794
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-task-validation-dialog", children: [
7628
7795
  /* @__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
- ] }),
7796
+ /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-message", children: (error == null ? void 0 : error.message) || t("please_complete_required_tasks_before_continuing") }),
7797
+ (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", {
7798
+ current: error.current,
7799
+ required: error.required
7800
+ }) }),
7801
+ (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", {
7802
+ current: error.current,
7803
+ required: error.required
7804
+ }) }),
7644
7805
  /* @__PURE__ */ jsx(
7645
7806
  "button",
7646
7807
  {
7647
7808
  className: "taskon-task-validation-dialog-btn",
7648
7809
  onClick: onClose,
7649
- children: "OK"
7810
+ children: t("ok")
7650
7811
  }
7651
7812
  )
7652
7813
  ] })
@@ -7654,7 +7815,7 @@ function TaskValidationDialog({
7654
7815
  );
7655
7816
  }
7656
7817
  const CHAIN_TYPE_LABELS = {
7657
- evm: "EVM Chain",
7818
+ evm: "evm_chain",
7658
7819
  btc: "Bitcoin",
7659
7820
  starknet: "Starknet",
7660
7821
  solana: "Solana",
@@ -7666,6 +7827,7 @@ const CHAIN_TYPE_LABELS = {
7666
7827
  ton: "TON"
7667
7828
  };
7668
7829
  function BindItem({ chainType, isBinding, isBound, onBind }) {
7830
+ const { t } = useQuestLocale();
7669
7831
  const label = CHAIN_TYPE_LABELS[chainType.toLowerCase()] || chainType;
7670
7832
  return /* @__PURE__ */ jsxs("div", { className: `taskon-reward-bind-item ${isBound ? "taskon-reward-bind-item--bound" : ""}`, children: [
7671
7833
  /* @__PURE__ */ jsx("span", { className: "taskon-reward-bind-item-label", children: label }),
@@ -7680,7 +7842,7 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7680
7842
  strokeLinejoin: "round"
7681
7843
  }
7682
7844
  ) }),
7683
- "Bound"
7845
+ t("bound")
7684
7846
  ] }) : /* @__PURE__ */ jsx(
7685
7847
  "button",
7686
7848
  {
@@ -7700,8 +7862,8 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7700
7862
  strokeDasharray: "31.4 31.4"
7701
7863
  }
7702
7864
  ) }),
7703
- "Binding..."
7704
- ] }) : "Bind"
7865
+ t("binding")
7866
+ ] }) : t("bind")
7705
7867
  }
7706
7868
  )
7707
7869
  ] });
@@ -7715,6 +7877,7 @@ function RewardBindDialog({
7715
7877
  onAllBind,
7716
7878
  onBindChain
7717
7879
  }) {
7880
+ const { t } = useQuestLocale();
7718
7881
  const [notBoundChains, setNotBoundChains] = useState(chainTypes);
7719
7882
  const [bindingType, setBindingType] = useState(null);
7720
7883
  React__default.useEffect(() => {
@@ -7733,7 +7896,7 @@ function RewardBindDialog({
7733
7896
  try {
7734
7897
  const success = await onBindChain(chainType);
7735
7898
  if (success) {
7736
- setNotBoundChains((prev) => prev.filter((t) => t !== chainType));
7899
+ setNotBoundChains((prev) => prev.filter((t2) => t2 !== chainType));
7737
7900
  }
7738
7901
  } finally {
7739
7902
  setBindingType(null);
@@ -7746,7 +7909,7 @@ function RewardBindDialog({
7746
7909
  onClose();
7747
7910
  }
7748
7911
  }, [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.";
7912
+ const tipText = skippable ? t("please_link_following_wallet_addresses_receive_rewards_skip_step") : t("please_link_following_wallet_addresses_receive_rewards_required_fcfs");
7750
7913
  return /* @__PURE__ */ jsx(
7751
7914
  Dialog,
7752
7915
  {
@@ -7756,7 +7919,7 @@ function RewardBindDialog({
7756
7919
  handleClose();
7757
7920
  }
7758
7921
  },
7759
- title: "Link Wallet Address",
7922
+ title: t("link_wallet_address"),
7760
7923
  showCloseButton: true,
7761
7924
  maxWidth: 480,
7762
7925
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-reward-bind-dialog", children: [
@@ -7776,7 +7939,7 @@ function RewardBindDialog({
7776
7939
  {
7777
7940
  className: "taskon-reward-bind-skip-btn",
7778
7941
  onClick: onSkip,
7779
- children: "Complete the Campaign"
7942
+ children: t("complete_campaign_2")
7780
7943
  }
7781
7944
  )
7782
7945
  ] })
@@ -7812,6 +7975,7 @@ function DiscordBindDialog({
7812
7975
  onLinkDiscord,
7813
7976
  onContinue
7814
7977
  }) {
7978
+ const { t } = useQuestLocale();
7815
7979
  return /* @__PURE__ */ jsx(
7816
7980
  Dialog,
7817
7981
  {
@@ -7821,19 +7985,23 @@ function DiscordBindDialog({
7821
7985
  onClose();
7822
7986
  }
7823
7987
  },
7824
- title: "Discord Account Not Linked",
7988
+ title: t("discord_account_linked"),
7825
7989
  showCloseButton: true,
7826
7990
  maxWidth: 440,
7827
7991
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog", children: [
7828
7992
  /* @__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." }),
7993
+ /* @__PURE__ */ jsxs("p", { className: "taskon-discord-bind-dialog-desc", children: [
7994
+ t("receive_discord_role_reward_need_link_discord_account"),
7995
+ " ",
7996
+ t("complete_campaign_without_linking_won_t_able_claim_discord")
7997
+ ] }),
7830
7998
  /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog-buttons", children: [
7831
7999
  /* @__PURE__ */ jsx(
7832
8000
  "button",
7833
8001
  {
7834
8002
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--secondary",
7835
8003
  onClick: onLinkDiscord,
7836
- children: "Link Discord Account"
8004
+ children: t("link_discord_account")
7837
8005
  }
7838
8006
  ),
7839
8007
  /* @__PURE__ */ jsx(
@@ -7841,7 +8009,7 @@ function DiscordBindDialog({
7841
8009
  {
7842
8010
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--primary",
7843
8011
  onClick: onContinue,
7844
- children: "Complete Campaign"
8012
+ children: t("complete_campaign")
7845
8013
  }
7846
8014
  )
7847
8015
  ] })
@@ -7915,11 +8083,13 @@ function ChevronRightIcon() {
7915
8083
  function WinnersRow({
7916
8084
  campaignId,
7917
8085
  winnerRewards,
7918
- pointsName = "Points",
8086
+ pointsName,
7919
8087
  onVisibleChange,
7920
8088
  className
7921
8089
  }) {
8090
+ const { t } = useQuestLocale();
7922
8091
  const { client } = useTaskOnContext();
8092
+ const resolvedPointsName = pointsName || t("points");
7923
8093
  const api = useMemo(() => {
7924
8094
  if (!client) return null;
7925
8095
  return createQuestApi(client);
@@ -7955,9 +8125,9 @@ function WinnersRow({
7955
8125
  type: "button",
7956
8126
  className: `taskon-quest-winners-row ${className || ""}`,
7957
8127
  onClick: () => setIsModalOpen(true),
7958
- "aria-label": "View winners list",
8128
+ "aria-label": t("view_winners_list"),
7959
8129
  children: [
7960
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: "Winners" }),
8130
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: t("winners") }),
7961
8131
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-count", children: total.toLocaleString() }),
7962
8132
  /* @__PURE__ */ jsx(ChevronRightIcon, {})
7963
8133
  ]
@@ -7970,7 +8140,7 @@ function WinnersRow({
7970
8140
  onClose: () => setIsModalOpen(false),
7971
8141
  campaignId,
7972
8142
  winnerRewards,
7973
- pointsName
8143
+ pointsName: resolvedPointsName
7974
8144
  }
7975
8145
  )
7976
8146
  ] });
@@ -8024,23 +8194,10 @@ function ArrowUpRightIcon() {
8024
8194
  }
8025
8195
  function formatDateShort(timestamp) {
8026
8196
  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}`;
8197
+ return new Intl.DateTimeFormat(void 0, {
8198
+ month: "short",
8199
+ day: "2-digit"
8200
+ }).format(date);
8044
8201
  }
8045
8202
  function WinnersStatus({
8046
8203
  campaign,
@@ -8051,6 +8208,7 @@ function WinnersStatus({
8051
8208
  className = ""
8052
8209
  }) {
8053
8210
  var _a, _b, _c;
8211
+ const { t } = useQuestLocale();
8054
8212
  const [hasWinners, setHasWinners] = useState(false);
8055
8213
  const endTime = campaign.end_time;
8056
8214
  const isWaitingReviewPow = useMemo(() => {
@@ -8096,29 +8254,35 @@ function WinnersStatus({
8096
8254
  className: "taskon-winners-alert",
8097
8255
  children: [
8098
8256
  /* @__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
- ] }),
8257
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: /* @__PURE__ */ jsx(
8258
+ I18nT,
8259
+ {
8260
+ t,
8261
+ i18nKey: "waiting_community_reviewed_tasks",
8262
+ components: {
8263
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name })
8264
+ }
8265
+ }
8266
+ ) }),
8106
8267
  /* @__PURE__ */ jsx(ArrowUpRightIcon, {})
8107
8268
  ]
8108
8269
  }
8109
8270
  ) : /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8110
8271
  /* @__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
- ] })
8272
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: /* @__PURE__ */ jsx(
8273
+ I18nT,
8274
+ {
8275
+ t,
8276
+ i18nKey: "waiting_community_reviewed_tasks",
8277
+ components: {
8278
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name })
8279
+ }
8280
+ }
8281
+ ) })
8118
8282
  ] })),
8119
8283
  !isWaitingReviewPow && isDrawingWinner && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8120
8284
  /* @__PURE__ */ jsx(TimerIcon, {}),
8121
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: "System is Drawing Winners..." })
8285
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-text", children: t("system_drawing_winners") })
8122
8286
  ] }),
8123
8287
  /* @__PURE__ */ jsxs(
8124
8288
  "div",
@@ -8127,22 +8291,26 @@ function WinnersStatus({
8127
8291
  style: { display: isShowContent ? "block" : "none" },
8128
8292
  children: [
8129
8293
  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."
8294
+ "*",
8295
+ /* @__PURE__ */ jsx(
8296
+ I18nT,
8297
+ {
8298
+ t,
8299
+ i18nKey: "quest_includes_proof_work_pow_tasks_which_community_review",
8300
+ components: {
8301
+ community: /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-community", children: campaign.community_name }),
8302
+ only: /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-only", children: t("only") })
8303
+ }
8304
+ }
8305
+ )
8138
8306
  ] }),
8139
8307
  /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card", children: [
8140
8308
  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" }),
8309
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: t("system_automatically_select_winners") }),
8142
8310
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value", children: reviewDeadlineText })
8143
8311
  ] }),
8144
8312
  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" }),
8313
+ /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-label", children: t("winners_announced") }),
8146
8314
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value--primary", children: drawWinnersDeadlineText })
8147
8315
  ] }),
8148
8316
  /* @__PURE__ */ jsx(
@@ -8183,34 +8351,40 @@ function mergeQuestConfig(props, cloud) {
8183
8351
  rewardRedirectUrl: props.rewardRedirectUrl ?? (cloud == null ? void 0 : cloud.rewardRedirectUrl) ?? ""
8184
8352
  };
8185
8353
  }
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) {
8354
+ function createQuestNftClaimMessages(t) {
8355
+ return {
8356
+ claimDialog: {
8357
+ claimNft: t("claim_nft"),
8358
+ claimingNft: t("claiming_nft"),
8359
+ claimConnectingWallet: t("connecting_wallet"),
8360
+ claimSwitchingNetwork: t("switching_network"),
8361
+ claimGettingSignature: t("getting_signature"),
8362
+ claimConfirmInWallet: t("please_confirm_wallet"),
8363
+ claimTransactionPending: t("transaction_pending"),
8364
+ claimSuccess: t("claim_successful"),
8365
+ claimFailed: t("claim_failed"),
8366
+ claimCanceled: t("transaction_rejected_user"),
8367
+ viewOnExplorer: t("view_explorer"),
8368
+ retry: t("retry"),
8369
+ close: t("close")
8370
+ },
8371
+ pendingDialog: {
8372
+ pendingTransaction: t("pending_transaction"),
8373
+ claimPendingTitle: t(
8374
+ "already_claimed_nft_please_wait_transaction_confirmed"
8375
+ ),
8376
+ claimPendingCheckExplorer: t("check_transaction_explorer"),
8377
+ claimPendingHashLabel: t("transaction_hash"),
8378
+ claimPendingClaimAgainWarn: t(
8379
+ "claim_again_send_new_transaction_recommended_when_sure_there"
8380
+ ),
8381
+ claimPendingReceiveAddressNoChange: t("receive_address_t_changed"),
8382
+ claimAgain: t("claim_again"),
8383
+ continueWaiting: t("continue_waiting")
8384
+ }
8385
+ };
8386
+ }
8387
+ function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd, labels) {
8214
8388
  const now = Date.now();
8215
8389
  const startMs = startTime;
8216
8390
  const endMs = endTime;
@@ -8221,13 +8395,13 @@ function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd) {
8221
8395
  let label;
8222
8396
  if (!isStarted) {
8223
8397
  status = "upcoming";
8224
- label = "Upcoming";
8398
+ label = labels.upcoming;
8225
8399
  } else if (isEnded) {
8226
8400
  status = "ended";
8227
- label = "Ended";
8401
+ label = labels.ended;
8228
8402
  } else {
8229
8403
  status = "ongoing";
8230
- label = "Ongoing";
8404
+ label = labels.ongoing;
8231
8405
  }
8232
8406
  return {
8233
8407
  status,
@@ -8247,6 +8421,7 @@ function getHasRanking(winnerRewards) {
8247
8421
  }
8248
8422
  function QuestWidget(props) {
8249
8423
  const { widgetId, themeMode } = props;
8424
+ const { t } = useQuestLocale();
8250
8425
  const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
8251
8426
  const mergedConfig = useMemo(() => {
8252
8427
  return mergeQuestConfig(
@@ -8275,7 +8450,9 @@ function QuestWidget(props) {
8275
8450
  cloudTheme,
8276
8451
  themeMode,
8277
8452
  className: "taskon-quest",
8278
- errorMessage: configError ?? (!mergedConfig.campaignId ? "Campaign ID is required. Please provide campaignId via props or widgetId." : void 0),
8453
+ errorMessage: configError ?? (!mergedConfig.campaignId ? t(
8454
+ "campaign_id_required_please_provide_campaignid_via_props_widgetid"
8455
+ ) : void 0),
8279
8456
  children: /* @__PURE__ */ jsx(
8280
8457
  QuestWidgetInner,
8281
8458
  {
@@ -8298,6 +8475,7 @@ function QuestWidget(props) {
8298
8475
  }
8299
8476
  function QuestWidgetInner(props) {
8300
8477
  var _a, _b, _c, _d, _e;
8478
+ const { t } = useQuestLocale();
8301
8479
  const {
8302
8480
  campaignId,
8303
8481
  channel,
@@ -8325,6 +8503,10 @@ function QuestWidgetInner(props) {
8325
8503
  } = props;
8326
8504
  const { client, chains, isLoggedIn, userInfo, requestLogin, communityInfo } = useTaskOnContext();
8327
8505
  const { toast } = useToast();
8506
+ const questNftClaimMessages = useMemo(
8507
+ () => createQuestNftClaimMessages(t),
8508
+ [t]
8509
+ );
8328
8510
  const chainMap = useMemo(() => {
8329
8511
  if (!chains || chains.length === 0) return {};
8330
8512
  return Object.fromEntries(
@@ -8392,13 +8574,13 @@ function QuestWidgetInner(props) {
8392
8574
  } = useNftClaimFlow({
8393
8575
  campaignId,
8394
8576
  targetType: (campaign == null ? void 0 : campaign.campaign_type) === CampaignType.Event ? "event" : "campaign",
8395
- messages: QUEST_NFT_CLAIM_MESSAGES,
8577
+ messages: questNftClaimMessages,
8396
8578
  onClaimSuccess: async () => {
8397
8579
  refetchUserStatus();
8398
8580
  refetchStatus();
8399
8581
  },
8400
8582
  onClaimError: (error2) => {
8401
- toast.error(error2.message || "Failed to claim NFT");
8583
+ toast.error(error2.message || t("failed_claim_nft"));
8402
8584
  },
8403
8585
  onWalletError: (errorMessage) => {
8404
8586
  toast.error(errorMessage);
@@ -8443,9 +8625,14 @@ function QuestWidgetInner(props) {
8443
8625
  campaign.campaign_status,
8444
8626
  campaign.start_time,
8445
8627
  campaign.end_time,
8446
- campaign.is_end
8628
+ campaign.is_end,
8629
+ {
8630
+ upcoming: t("upcoming"),
8631
+ ended: t("ended"),
8632
+ ongoing: t("ongoing")
8633
+ }
8447
8634
  );
8448
- }, [campaign]);
8635
+ }, [campaign, t]);
8449
8636
  const isTaskDisabled = useMemo(() => {
8450
8637
  if (!statusDisplay) return true;
8451
8638
  return !statusDisplay.isActive;
@@ -8530,7 +8717,7 @@ function QuestWidgetInner(props) {
8530
8717
  setBlindBoxRewardVisible(true);
8531
8718
  } catch (error2) {
8532
8719
  console.error("Claim blind box error:", error2);
8533
- const errorMessage = error2 instanceof Error ? error2.message : "Network error, please try again";
8720
+ const errorMessage = error2 instanceof Error ? error2.message : t("network_error_please_try_again");
8534
8721
  toast.error(errorMessage);
8535
8722
  (_a2 = blindBoxDialogRef.current) == null ? void 0 : _a2.resetToUnopened();
8536
8723
  } finally {
@@ -8543,6 +8730,7 @@ function QuestWidgetInner(props) {
8543
8730
  buildBlindBoxRewardValue,
8544
8731
  refetchUserStatus,
8545
8732
  refetchStatus,
8733
+ t,
8546
8734
  toast
8547
8735
  ]);
8548
8736
  useEffect(() => {
@@ -8575,7 +8763,7 @@ function QuestWidgetInner(props) {
8575
8763
  const handleTaskCompleted = (taskId, result) => {
8576
8764
  var _a2;
8577
8765
  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);
8766
+ const task = (_a2 = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _a2.find((t2) => t2.id === taskId);
8579
8767
  const isSwapDex = (task == null ? void 0 : task.template_id) === "SwapDexContractInteractive";
8580
8768
  const isSuccess = successTaskIds.includes(taskId);
8581
8769
  if (isSuccess) {
@@ -8737,13 +8925,13 @@ function QuestWidgetInner(props) {
8737
8925
  refetchUserStatus();
8738
8926
  refetchStatus();
8739
8927
  },
8740
- children: "Retry"
8928
+ children: t("retry")
8741
8929
  }
8742
8930
  )
8743
8931
  ] }) });
8744
8932
  }
8745
8933
  if (!campaign) {
8746
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-empty", children: "Quest not found" }) });
8934
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-empty", children: t("quest_found") }) });
8747
8935
  }
8748
8936
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest", children: [
8749
8937
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-layout", children: [
@@ -8771,7 +8959,7 @@ function QuestWidgetInner(props) {
8771
8959
  ),
8772
8960
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-content-divider" }),
8773
8961
  /* @__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" }) }),
8962
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-tasks-header", children: /* @__PURE__ */ jsx("h2", { className: "taskon-quest-tasks-title", children: t("task") }) }),
8775
8963
  mandatoryTasks.length > 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx(
8776
8964
  CompletedCount,
8777
8965
  {
@@ -8832,7 +9020,7 @@ function QuestWidgetInner(props) {
8832
9020
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-divider" }),
8833
9021
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-sidebar", children: [
8834
9022
  (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" }),
9023
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-winners-section-title", children: t("winners") }),
8836
9024
  /* @__PURE__ */ jsx(
8837
9025
  WinnersStatus,
8838
9026
  {
@@ -8845,7 +9033,7 @@ function QuestWidgetInner(props) {
8845
9033
  )
8846
9034
  ] }),
8847
9035
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-section", children: [
8848
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-rewards-section-title", children: "Quest Rewards" }),
9036
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-rewards-section-title", children: t("quest_rewards") }),
8849
9037
  /* @__PURE__ */ jsx(
8850
9038
  QuestRewards,
8851
9039
  {
@@ -8869,7 +9057,7 @@ function QuestWidgetInner(props) {
8869
9057
  )
8870
9058
  ] }),
8871
9059
  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" }) }),
9060
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-eligs-section-header", children: /* @__PURE__ */ jsx("h3", { className: "taskon-quest-eligs-section-title", children: t("quest_eligibility") }) }),
8873
9061
  /* @__PURE__ */ jsx(
8874
9062
  EligibilityInfo,
8875
9063
  {
@@ -8899,7 +9087,7 @@ function QuestWidgetInner(props) {
8899
9087
  {
8900
9088
  open: isBlindBoxDialogVisible,
8901
9089
  onOpenChange: setBlindBoxDialogVisible,
8902
- title: "Open Blind Box",
9090
+ title: t("open_blind_box"),
8903
9091
  showCloseButton: false,
8904
9092
  closeOnOverlayClick: false,
8905
9093
  closeOnEscapeKey: false,
@@ -8919,7 +9107,7 @@ function QuestWidgetInner(props) {
8919
9107
  {
8920
9108
  open: isBlindBoxRewardVisible,
8921
9109
  onOpenChange: setBlindBoxRewardVisible,
8922
- title: "Blind Box Reward",
9110
+ title: t("blind_box_reward"),
8923
9111
  showCloseButton: true,
8924
9112
  contentClassName: "taskon-quest-blindbox-reward-wrapper",
8925
9113
  children: /* @__PURE__ */ jsx(