@taskon/widget-react 0.0.1-beta.3 → 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 (44) hide show
  1. package/README.md +1 -1
  2. package/dist/CommunityTaskList.css +1340 -1292
  3. package/dist/EligibilityInfo.css +512 -332
  4. package/dist/LeaderboardWidget.css +355 -152
  5. package/dist/Quest.css +911 -629
  6. package/dist/TaskOnProvider.css +35 -16
  7. package/dist/UserCenterWidget.css +116 -71
  8. package/dist/UserCenterWidget2.css +1285 -748
  9. package/dist/chunks/{CommunityTaskList-C9mPl_31.js → CommunityTaskList-CrMvOB8w.js} +784 -452
  10. package/dist/chunks/{EligibilityInfo-DGBffKN8.js → EligibilityInfo-Beww12QX.js} +1569 -597
  11. package/dist/chunks/{LeaderboardWidget-DPOQVXkT.js → LeaderboardWidget-DwuSpVl0.js} +2 -2
  12. package/dist/chunks/{PageBuilder-WCZvxL2j.js → PageBuilder-DsX6Tv0N.js} +5 -5
  13. package/dist/chunks/{Quest-DjGH_8bx.js → Quest-CuD2LElS.js} +713 -484
  14. package/dist/chunks/{TaskOnProvider-iannERG1.js → TaskOnProvider-xUeP2Nro.js} +78 -65
  15. package/dist/chunks/{ThemeProvider-DNJqI2lD.js → ThemeProvider-Bt4UZ33y.js} +33 -9
  16. package/dist/chunks/{UserCenterWidget-CAhgp46j.js → UserCenterWidget-CB0hnj-L.js} +69 -31
  17. package/dist/chunks/{UserCenterWidget-B0O-f_xl.js → UserCenterWidget-CvU6K4AC.js} +21 -7
  18. package/dist/chunks/communitytask-es-1zawvXEX.js +311 -0
  19. package/dist/chunks/communitytask-ja-CmW6nP-L.js +311 -0
  20. package/dist/chunks/communitytask-ko-BD0hzQSi.js +311 -0
  21. package/dist/chunks/communitytask-ru-DhySaZL8.js +311 -0
  22. package/dist/chunks/createLocaleLoader-BameiEhU.js +65 -0
  23. package/dist/chunks/{dynamic-import-helper-B2j_dZ4V.js → dynamic-import-helper-WmIF58Sb.js} +1 -1
  24. package/dist/chunks/quest-es-D-b5xcme.js +948 -0
  25. package/dist/chunks/quest-ja-Dxd2vqBF.js +948 -0
  26. package/dist/chunks/quest-ko-CSmRWgK_.js +948 -0
  27. package/dist/chunks/quest-ru-CkEKv1_F.js +948 -0
  28. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  29. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  30. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  31. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  32. package/dist/community-task.js +1 -1
  33. package/dist/core.d.ts +17 -5
  34. package/dist/core.js +8 -7
  35. package/dist/dynamic-import-helper.css +424 -303
  36. package/dist/index.d.ts +56 -5
  37. package/dist/index.js +18 -16
  38. package/dist/leaderboard.js +2 -2
  39. package/dist/page-builder.js +1 -1
  40. package/dist/quest.d.ts +682 -0
  41. package/dist/quest.js +3 -1
  42. package/dist/user-center.d.ts +3 -1
  43. package/dist/user-center.js +5 -5
  44. package/package.json +7 -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-DNJqI2lD.js";
5
- import { D as Dialog, B as Button, T as Table, P as Pagination, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-B2j_dZ4V.js";
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-B0O-f_xl.js";
8
- import { c as TaskItem, e as EligibilityList, g as getDefaultExportFromCjs, s as sanitizeHtml, R as RewardModuleDialog, C as ConfirmNoticeDialog, u as useBindWallet, b as useNftClaimFlow, E as EligibilityInfo, B as BlindBoxDialog } from "./EligibilityInfo-DGBffKN8.js";
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,
@@ -131,7 +131,7 @@ function GreenCheckIcon() {
131
131
  "path",
132
132
  {
133
133
  d: "M1 4L4.5 7.5L11 1",
134
- stroke: "#22c55e",
134
+ stroke: "currentColor",
135
135
  strokeWidth: "2",
136
136
  strokeLinecap: "round",
137
137
  strokeLinejoin: "round"
@@ -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 }),
@@ -4220,12 +4274,16 @@ function QuestTitle({
4220
4274
  ] }),
4221
4275
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-countdown-divider" }),
4222
4276
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-time-range", children: [
4223
- "(UTC",
4224
- offsetString,
4225
- ") ",
4226
- formatDateTime(startDate),
4227
- " ~ ",
4228
- formatDateTime(endDate)
4277
+ /* @__PURE__ */ jsxs("span", { className: "taskon-quest-time-range-timezone", children: [
4278
+ "(UTC",
4279
+ offsetString,
4280
+ ")"
4281
+ ] }),
4282
+ /* @__PURE__ */ jsxs("span", { className: "taskon-quest-time-range-values", children: [
4283
+ /* @__PURE__ */ jsx("span", { children: formatDateTime(startDate) }),
4284
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-time-range-separator", "aria-hidden": "true", children: "~" }),
4285
+ /* @__PURE__ */ jsx("span", { children: formatDateTime(endDate) })
4286
+ ] })
4229
4287
  ] }),
4230
4288
  showShare && /* @__PURE__ */ jsx(
4231
4289
  ShareDropdown,
@@ -4249,6 +4307,7 @@ function QuestDescription({
4249
4307
  description,
4250
4308
  show = true
4251
4309
  }) {
4310
+ const { t } = useQuestLocale();
4252
4311
  const [isExpanded, setIsExpanded] = useState(false);
4253
4312
  const sanitizedHtml = useMemo(() => {
4254
4313
  if (!description) return "";
@@ -4270,7 +4329,7 @@ function QuestDescription({
4270
4329
  {
4271
4330
  className: "taskon-quest-desc-more",
4272
4331
  onClick: () => setIsExpanded(!isExpanded),
4273
- children: isExpanded ? "Show less" : "Read more"
4332
+ children: isExpanded ? t("show_less") : t("read")
4274
4333
  }
4275
4334
  )
4276
4335
  ] });
@@ -4361,6 +4420,7 @@ function ParticipantsInfo({
4361
4420
  participantCount,
4362
4421
  className
4363
4422
  }) {
4423
+ const { t } = useQuestLocale();
4364
4424
  const [isDialogOpen, setIsDialogOpen] = useState(false);
4365
4425
  if (participantCount === 0) {
4366
4426
  return null;
@@ -4373,15 +4433,15 @@ function ParticipantsInfo({
4373
4433
  type: "button",
4374
4434
  className: "taskon-quest-participants-info-header",
4375
4435
  onClick: () => setIsDialogOpen(true),
4376
- "aria-label": "View participants info details",
4436
+ "aria-label": t("view_participants_info_details"),
4377
4437
  children: [
4378
- /* @__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") }),
4379
4439
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-icon", children: /* @__PURE__ */ jsx(InfoIcon, {}) })
4380
4440
  ]
4381
4441
  }
4382
4442
  ),
4383
4443
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-info-row", children: [
4384
- /* @__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") }),
4385
4445
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-participants-info-value", children: formattedParticipantCount })
4386
4446
  ] }),
4387
4447
  /* @__PURE__ */ jsx(
@@ -4389,36 +4449,48 @@ function ParticipantsInfo({
4389
4449
  {
4390
4450
  open: isDialogOpen,
4391
4451
  onOpenChange: setIsDialogOpen,
4392
- title: "Participants",
4452
+ title: t("participants_2"),
4393
4453
  maxWidth: 480,
4394
4454
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog", children: [
4395
- /* @__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") }),
4396
4456
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-section", children: [
4397
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: "What is Participants?" }),
4398
- /* @__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") })
4399
4459
  ] }),
4400
4460
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-section", children: [
4401
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-subtitle", children: "How is winner be selected?" }),
4402
- /* @__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") })
4403
4463
  ] }),
4404
4464
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-chart", children: [
4405
4465
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-arrow-wrap", children: /* @__PURE__ */ jsx(ArrowDownIcon, {}) }),
4406
4466
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-cards", children: [
4407
4467
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level1", children: [
4408
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Participants" }),
4409
- /* @__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
+ ] })
4410
4473
  ] }),
4411
4474
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level2", children: [
4412
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Submitters" }),
4413
- /* @__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
+ ] })
4414
4480
  ] }),
4415
4481
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level3", children: [
4416
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "Qualifiers" }),
4417
- /* @__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
+ ] })
4418
4487
  ] }),
4419
4488
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-participants-dialog-card taskon-quest-participants-dialog-card--level4", children: [
4420
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-participants-dialog-card-title", children: "👑 Winners" }),
4421
- /* @__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
+ ] })
4422
4494
  ] })
4423
4495
  ] })
4424
4496
  ] }),
@@ -4429,7 +4501,7 @@ function ParticipantsInfo({
4429
4501
  size: "large",
4430
4502
  className: "taskon-quest-participants-dialog-btn",
4431
4503
  onClick: () => setIsDialogOpen(false),
4432
- children: "Confirm"
4504
+ children: t("confirm")
4433
4505
  }
4434
4506
  )
4435
4507
  ] })
@@ -4437,14 +4509,14 @@ function ParticipantsInfo({
4437
4509
  )
4438
4510
  ] });
4439
4511
  }
4440
- function getRewardTypeLabel$1(rewardType, pointName) {
4512
+ function getRewardTypeLabel$1(rewardType, pointName, t) {
4441
4513
  if ([RewardType.BMintedNft, RewardType.Cap, RewardType.Nft].includes(
4442
4514
  rewardType
4443
4515
  )) {
4444
4516
  return "NFT:";
4445
4517
  }
4446
4518
  if (rewardType === String(RewardType.DiscordRole)) {
4447
- return "Discord Role:";
4519
+ return `${t("discord_role")}:`;
4448
4520
  }
4449
4521
  if (rewardType === String(RewardType.Exp)) {
4450
4522
  return "EXP:";
@@ -4456,14 +4528,14 @@ function getRewardTypeLabel$1(rewardType, pointName) {
4456
4528
  return `${pointName}:`;
4457
4529
  }
4458
4530
  if (rewardType === String(RewardType.Token)) {
4459
- return "Token:";
4531
+ return `${t("token_name")}:`;
4460
4532
  }
4461
4533
  if (rewardType === String(RewardType.Whitelist)) {
4462
- return "Whitelist";
4534
+ return t("whitelist");
4463
4535
  }
4464
4536
  return String(rewardType);
4465
4537
  }
4466
- function getRewardLabel$1(data) {
4538
+ function getRewardLabel$1(data, t) {
4467
4539
  const { reward_type, reward_symbol, amount, chain_label, is_usdt_equal } = data;
4468
4540
  if ([
4469
4541
  RewardType.BMintedNft,
@@ -4481,7 +4553,9 @@ function getRewardLabel$1(data) {
4481
4553
  }
4482
4554
  if (reward_type === String(RewardType.Token)) {
4483
4555
  if (is_usdt_equal) {
4484
- return `$${amount || ""} in ${reward_symbol}`;
4556
+ return `${amount || ""} ${t("usd_token_name", {
4557
+ token_name: reward_symbol || ""
4558
+ })}`.trim();
4485
4559
  }
4486
4560
  return `${amount || ""} ${reward_symbol} ${chain_label || ""}`.trim();
4487
4561
  }
@@ -4492,13 +4566,21 @@ function getRewardLabel$1(data) {
4492
4566
  }
4493
4567
  function WinnerRewardLabel({
4494
4568
  data,
4495
- pointName = "Points"
4569
+ pointName
4496
4570
  }) {
4571
+ const { t } = useQuestLocale();
4572
+ const resolvedPointName = pointName || t("points");
4497
4573
  const typeLabel = useMemo(
4498
- () => getRewardTypeLabel$1(data.reward_type, pointName),
4499
- [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]
4500
4583
  );
4501
- const valueLabel = useMemo(() => getRewardLabel$1(data), [data]);
4502
4584
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-reward-label", children: [
4503
4585
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-type", children: typeLabel }),
4504
4586
  valueLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-winner-reward-label-value", children: valueLabel })
@@ -4524,32 +4606,32 @@ function getHowToSelectWinner$1(group) {
4524
4606
  }
4525
4607
  function getWinnerSelectionLabel$1(howToSelect) {
4526
4608
  const labels = {
4527
- FCFS: "FCFS",
4528
- LuckyDraw: "Lucky Draw",
4529
- PointRanking: "Ranking",
4530
- ManualUpload: "Manually Upload",
4531
- OpenToAll: "Open to All"
4609
+ FCFS: "fcfs",
4610
+ LuckyDraw: "lucky_draw",
4611
+ PointRanking: "ranking_2",
4612
+ ManualUpload: "manually_upload",
4613
+ OpenToAll: "open"
4532
4614
  };
4533
4615
  return labels[howToSelect];
4534
4616
  }
4535
- function formatRankingLabel(ranking) {
4617
+ function formatRankingLabel(ranking, t) {
4536
4618
  if (ranking.range_type === QuestWinnerRangeType.Number) {
4537
4619
  if (ranking.from < 2) {
4538
- return `Top ${ranking.to}`;
4620
+ return t("top_2", { to: ranking.to });
4539
4621
  }
4540
- return `Top ${ranking.from}-${ranking.to}`;
4622
+ return t("top", { from: ranking.from, to: ranking.to });
4541
4623
  } else {
4542
4624
  if (ranking.from === 0) {
4543
- return `Top ${ranking.to}%`;
4625
+ return t("top_percent_2", { to: ranking.to });
4544
4626
  }
4545
- return `Top ${ranking.from}%-${ranking.to}%`;
4627
+ return t("top_percent", { from: ranking.from, to: ranking.to });
4546
4628
  }
4547
4629
  }
4548
- function getTierLabel(layerIndex, isCurrentLayer) {
4630
+ function getTierLabel(layerIndex, isCurrentLayer, t) {
4549
4631
  if (isCurrentLayer) {
4550
- return "You are here";
4632
+ return t("here");
4551
4633
  }
4552
- return `Tier ${layerIndex + 1}`;
4634
+ return t("tier_index", { index: layerIndex + 1 });
4553
4635
  }
4554
4636
  function calculateFcfsAvailable(rewardLayer, currentWinner) {
4555
4637
  var _a;
@@ -4631,9 +4713,11 @@ function WinnerListModal({
4631
4713
  onClose,
4632
4714
  campaignId,
4633
4715
  winnerRewards,
4634
- pointsName = "Points"
4716
+ pointsName
4635
4717
  }) {
4718
+ const { t } = useQuestLocale();
4636
4719
  const { client } = useTaskOnContext();
4720
+ const resolvedPointsName = pointsName || t("points");
4637
4721
  const api = useMemo(() => {
4638
4722
  if (!client) return null;
4639
4723
  return createQuestApi(client);
@@ -4648,13 +4732,14 @@ function WinnerListModal({
4648
4732
  const tabItems = useMemo(() => {
4649
4733
  return winnerRewards.map((item, index) => {
4650
4734
  const howToSelect = getHowToSelectWinner$1(item);
4735
+ const label = getWinnerSelectionLabel$1(howToSelect);
4651
4736
  return {
4652
4737
  key: index,
4653
- label: getWinnerSelectionLabel$1(howToSelect),
4738
+ label: t(label),
4654
4739
  type: howToSelect
4655
4740
  };
4656
4741
  });
4657
- }, [winnerRewards]);
4742
+ }, [winnerRewards, t]);
4658
4743
  const currentType = useMemo(() => {
4659
4744
  var _a;
4660
4745
  return ((_a = tabItems[currentIndex]) == null ? void 0 : _a.type) || "FCFS";
@@ -4684,7 +4769,7 @@ function WinnerListModal({
4684
4769
  }
4685
4770
  setPage(pageNo);
4686
4771
  } catch (err) {
4687
- setError(err instanceof Error ? err.message : "Failed to load winners");
4772
+ setError(err instanceof Error ? err.message : t("failed_load_winners"));
4688
4773
  if (!append) {
4689
4774
  setTotal(0);
4690
4775
  setList([]);
@@ -4693,7 +4778,7 @@ function WinnerListModal({
4693
4778
  setLoading(false);
4694
4779
  }
4695
4780
  },
4696
- [api, campaignId, currentIndex, loading]
4781
+ [api, campaignId, currentIndex, loading, t]
4697
4782
  );
4698
4783
  useEffect(() => {
4699
4784
  if (isOpen && api) {
@@ -4739,13 +4824,14 @@ function WinnerListModal({
4739
4824
  onOpenChange: (open) => {
4740
4825
  if (!open) onClose();
4741
4826
  },
4742
- title: "Winners",
4827
+ title: t("winners"),
4743
4828
  showCloseButton: true,
4744
4829
  contentClassName: "taskon-quest-winner-modal",
4745
4830
  maxWidth: 600,
4746
4831
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-content", children: [
4747
4832
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-header", children: /* @__PURE__ */ jsxs("h2", { className: "taskon-quest-winner-title", children: [
4748
- "Winners (",
4833
+ t("winners"),
4834
+ " (",
4749
4835
  total.toLocaleString(),
4750
4836
  ")"
4751
4837
  ] }) }),
@@ -4766,16 +4852,16 @@ function WinnerListModal({
4766
4852
  variant: "primary",
4767
4853
  size: "small",
4768
4854
  onClick: () => loadPage(0, false),
4769
- children: "Retry"
4855
+ children: t("retry")
4770
4856
  }
4771
4857
  )
4772
4858
  ] }),
4773
4859
  !error && /* @__PURE__ */ jsxs("div", { ref: scrollRef, className: "taskon-quest-winner-list", children: [
4774
4860
  /* @__PURE__ */ jsxs("table", { className: "taskon-quest-winner-table", children: [
4775
4861
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
4776
- showPosition && /* @__PURE__ */ jsx("th", { children: "Position" }),
4777
- /* @__PURE__ */ jsx("th", { children: "User" }),
4778
- /* @__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") })
4779
4865
  ] }) }),
4780
4866
  /* @__PURE__ */ jsxs("tbody", { children: [
4781
4867
  list.map((item, index) => {
@@ -4789,7 +4875,7 @@ function WinnerListModal({
4789
4875
  WinnerRewardLabel,
4790
4876
  {
4791
4877
  data: reward,
4792
- pointName: pointsName
4878
+ pointName: resolvedPointsName
4793
4879
  },
4794
4880
  `${reward.reward_type}-${rewardIndex}`
4795
4881
  )) }) })
@@ -4800,14 +4886,14 @@ function WinnerListModal({
4800
4886
  {
4801
4887
  colSpan: showPosition ? 3 : 2,
4802
4888
  className: "taskon-quest-winner-empty",
4803
- children: "No winners yet"
4889
+ children: t("no_winners")
4804
4890
  }
4805
4891
  ) })
4806
4892
  ] })
4807
4893
  ] }),
4808
4894
  loading && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winner-loading", children: [
4809
4895
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-winner-loading-spinner" }),
4810
- /* @__PURE__ */ jsx("span", { children: "Loading..." })
4896
+ /* @__PURE__ */ jsx("span", { children: t("loading") })
4811
4897
  ] })
4812
4898
  ] })
4813
4899
  ] })
@@ -4902,6 +4988,7 @@ function getIsBrc20(chain, tokenAddress, chains) {
4902
4988
  return (chainInfo == null ? void 0 : chainInfo.chain_type) === "btc" && tokenAddress !== BTC_CONTRACT;
4903
4989
  }
4904
4990
  function TokenInfo({ rewardInfo, chains }) {
4991
+ const { t } = useQuestLocale();
4905
4992
  const portalContainer = useTaskOnPortalContainer();
4906
4993
  const params = rewardInfo.reward_params;
4907
4994
  const distributeType = rewardInfo.reward_distribute_type;
@@ -4912,7 +4999,7 @@ function TokenInfo({ rewardInfo, chains }) {
4912
4999
  const isBrc20 = getIsBrc20(params.chain, params.token_address, chains);
4913
5000
  const totalAmount = formatTokenAmount(params.total_amount);
4914
5001
  const perAmount = params.per_amount;
4915
- 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;
4916
5003
  const handleMouseEnter = () => {
4917
5004
  if (timeoutRef.current) {
4918
5005
  clearTimeout(timeoutRef.current);
@@ -4937,9 +5024,9 @@ function TokenInfo({ rewardInfo, chains }) {
4937
5024
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token", children: [
4938
5025
  isBlindBox && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-token-blindbox", children: [
4939
5026
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-blindbox-icon", children: "✨" }),
4940
- /* @__PURE__ */ jsx("span", { children: "Smart Blind Box" })
5027
+ /* @__PURE__ */ jsx("span", { children: t("smart_blind_box") })
4941
5028
  ] }),
4942
- /* @__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: [
4943
5030
  /* @__PURE__ */ jsx(Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
4944
5031
  "div",
4945
5032
  {
@@ -4972,12 +5059,11 @@ function TokenInfo({ rewardInfo, chains }) {
4972
5059
  onMouseEnter: handleMouseEnter,
4973
5060
  onMouseLeave: handleMouseLeave,
4974
5061
  children: [
4975
- params.is_usdt_equal_amount && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-name", children: [
4976
- "Equivalent amounts of ",
4977
- params.token_name
4978
- ] }),
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
+ }) }),
4979
5065
  params.token_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
4980
- /* @__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") }),
4981
5067
  /* @__PURE__ */ jsxs(
4982
5068
  "button",
4983
5069
  {
@@ -4997,8 +5083,8 @@ function TokenInfo({ rewardInfo, chains }) {
4997
5083
  ) })
4998
5084
  ] }) }),
4999
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: [
5000
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-token-per-label", children: "Rewards Per Winner" }),
5001
- /* @__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}` })
5002
5088
  ] })
5003
5089
  ] });
5004
5090
  }
@@ -5011,6 +5097,7 @@ async function copyToClipboard$1(text) {
5011
5097
  }
5012
5098
  }
5013
5099
  function NftInfo({ rewardInfo, chains }) {
5100
+ const { t } = useQuestLocale();
5014
5101
  const portalContainer = useTaskOnPortalContainer();
5015
5102
  const params = rewardInfo.reward_params;
5016
5103
  const [open, setOpen] = useState(false);
@@ -5070,7 +5157,7 @@ function NftInfo({ rewardInfo, chains }) {
5070
5157
  children: [
5071
5158
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5072
5159
  params.nft_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
5073
- /* @__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") }),
5074
5161
  /* @__PURE__ */ jsxs(
5075
5162
  "button",
5076
5163
  {
@@ -5099,6 +5186,7 @@ async function copyToClipboard(text) {
5099
5186
  }
5100
5187
  }
5101
5188
  function MintedNftInfo({ rewardInfo, chains }) {
5189
+ const { t } = useQuestLocale();
5102
5190
  const portalContainer = useTaskOnPortalContainer();
5103
5191
  const params = rewardInfo.reward_params;
5104
5192
  const [open, setOpen] = useState(false);
@@ -5158,7 +5246,7 @@ function MintedNftInfo({ rewardInfo, chains }) {
5158
5246
  children: [
5159
5247
  params.nft_collection_name && /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-popover-name", children: params.nft_collection_name }),
5160
5248
  params.nft_address && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-popover-address", children: [
5161
- /* @__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") }),
5162
5250
  /* @__PURE__ */ jsxs(
5163
5251
  "button",
5164
5252
  {
@@ -5191,8 +5279,9 @@ function CapInfo({ rewardInfo, chains }) {
5191
5279
  ) }) });
5192
5280
  }
5193
5281
  function WhitelistInfo({ rewardInfo, chains }) {
5282
+ const { t } = useQuestLocale();
5194
5283
  const params = rewardInfo.reward_params;
5195
- 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(
5196
5285
  ChainIcon,
5197
5286
  {
5198
5287
  chain: params.chain,
@@ -5203,9 +5292,10 @@ function WhitelistInfo({ rewardInfo, chains }) {
5203
5292
  ) }) });
5204
5293
  }
5205
5294
  function PointsInfo({ rewardInfo }) {
5295
+ const { t } = useQuestLocale();
5206
5296
  const params = rewardInfo.reward_params;
5207
5297
  const formattedAmount = formatLargeNumber(params.amount);
5208
- 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: [
5209
5299
  params.points_icon && /* @__PURE__ */ jsx(
5210
5300
  "img",
5211
5301
  {
@@ -5219,21 +5309,23 @@ function PointsInfo({ rewardInfo }) {
5219
5309
  ] }) }) });
5220
5310
  }
5221
5311
  function ExpInfo({ rewardInfo }) {
5312
+ const { t } = useQuestLocale();
5222
5313
  const params = rewardInfo.reward_params;
5223
5314
  const formattedAmount = formatLargeNumber(params.per_amount);
5224
- 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: [
5225
5316
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-amount", children: formattedAmount }),
5226
5317
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-exp-label", children: "EXP" })
5227
5318
  ] }) }) });
5228
5319
  }
5229
5320
  function DiscordRoleInfo({ rewardInfo }) {
5321
+ const { t } = useQuestLocale();
5230
5322
  const params = rewardInfo.reward_params;
5231
5323
  const handleClick = () => {
5232
5324
  if (params.discord_server_url) {
5233
5325
  window.open(params.discord_server_url, "_blank", "noopener,noreferrer");
5234
5326
  }
5235
5327
  };
5236
- 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: [
5237
5329
  /* @__PURE__ */ jsx(
5238
5330
  "span",
5239
5331
  {
@@ -5243,7 +5335,7 @@ function DiscordRoleInfo({ rewardInfo }) {
5243
5335
  children: params.role_name
5244
5336
  }
5245
5337
  ),
5246
- 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") })
5247
5339
  ] }) }) });
5248
5340
  }
5249
5341
  function TheReward({ rewardInfo, chains }) {
@@ -5277,6 +5369,7 @@ function WinnerCount({
5277
5369
  currentWinner,
5278
5370
  rankingLabel
5279
5371
  }) {
5372
+ const { t } = useQuestLocale();
5280
5373
  const maxWinners = rewardLayer.max_winners;
5281
5374
  if (howToSelectWinner === "OpenToAll") {
5282
5375
  return null;
@@ -5291,7 +5384,7 @@ function WinnerCount({
5291
5384
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-separator", children: "/" }),
5292
5385
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-total", children: maxWinners })
5293
5386
  ] }),
5294
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: "Available" })
5387
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-label", children: t("available") })
5295
5388
  ] });
5296
5389
  }
5297
5390
  case "PointRanking":
@@ -5302,11 +5395,12 @@ function WinnerCount({
5302
5395
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-winner-count", children: maxWinners });
5303
5396
  }
5304
5397
  };
5305
- return /* @__PURE__ */ jsx(BaseRow, { label: "Winners", children: renderContent() });
5398
+ return /* @__PURE__ */ jsx(BaseRow, { label: t("winners"), children: renderContent() });
5306
5399
  }
5307
5400
  function GasStationProgress({
5308
5401
  gasStation
5309
5402
  }) {
5403
+ const { t } = useQuestLocale();
5310
5404
  if (!gasStation.gas_covered) {
5311
5405
  return null;
5312
5406
  }
@@ -5315,7 +5409,7 @@ function GasStationProgress({
5315
5409
  gasStation.used_gas_amount
5316
5410
  );
5317
5411
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-gas", children: [
5318
- /* @__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") }),
5319
5413
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-gas-bar", children: /* @__PURE__ */ jsx(
5320
5414
  "div",
5321
5415
  {
@@ -5329,8 +5423,10 @@ function GasStationProgress({
5329
5423
  function NftPreview({
5330
5424
  imageUrl,
5331
5425
  mediaType = "Image",
5332
- alt = "NFT Preview"
5426
+ alt
5333
5427
  }) {
5428
+ const { t } = useQuestLocale();
5429
+ const previewAlt = alt || t("nft_preview");
5334
5430
  if (!imageUrl) {
5335
5431
  return null;
5336
5432
  }
@@ -5348,7 +5444,7 @@ function NftPreview({
5348
5444
  "img",
5349
5445
  {
5350
5446
  src: imageUrl,
5351
- alt,
5447
+ alt: previewAlt,
5352
5448
  className: "taskon-quest-rewards-preview-image",
5353
5449
  loading: "lazy"
5354
5450
  }
@@ -5364,18 +5460,19 @@ function EstimatedRewards({
5364
5460
  isEnded,
5365
5461
  finalReward
5366
5462
  }) {
5463
+ const { t } = useQuestLocale();
5367
5464
  const rewardLabel = useMemo(() => {
5368
5465
  if (!isEnded) {
5369
- return "Your Estimated Rewards";
5466
+ return t("estimated_rewards");
5370
5467
  }
5371
5468
  if (!isCompleted) {
5372
5469
  return "";
5373
5470
  }
5374
5471
  if (finalReward) {
5375
- return "Your Final Rewards";
5472
+ return t("final_rewards");
5376
5473
  }
5377
- return "Your Estimated Rewards";
5378
- }, [isEnded, isCompleted, finalReward]);
5474
+ return t("estimated_rewards");
5475
+ }, [isEnded, isCompleted, finalReward, t]);
5379
5476
  if (!rewardLabel) {
5380
5477
  return null;
5381
5478
  }
@@ -5405,24 +5502,15 @@ function EstimatedRewards({
5405
5502
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-symbol", children: rewardSymbol })
5406
5503
  ] })
5407
5504
  ] }),
5408
- /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-formula", children: [
5409
- "= Total Rewards Pool * Your ",
5410
- pointName,
5411
- " / Total ",
5505
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-formula", children: t("eq_total_rewards_pool_pointname_total_pointname", {
5412
5506
  pointName
5413
- ] }),
5507
+ }) }),
5414
5508
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-row", children: [
5415
- /* @__PURE__ */ jsxs("span", { className: "taskon-quest-rewards-estimated-label", children: [
5416
- "Your ",
5417
- pointName
5418
- ] }),
5509
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-label", children: t("pointname", { pointName }) }),
5419
5510
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-estimated-points", children: formattedUserPoints })
5420
5511
  ] }),
5421
5512
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-total", children: [
5422
- /* @__PURE__ */ jsxs("span", { children: [
5423
- "Total ",
5424
- pointName
5425
- ] }),
5513
+ /* @__PURE__ */ jsx("span", { children: t("total_pointname", { pointName }) }),
5426
5514
  /* @__PURE__ */ jsx("span", { children: formattedTotalPoints })
5427
5515
  ] }),
5428
5516
  !isCompleted && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-estimated-mask", children: [
@@ -5434,29 +5522,31 @@ function EstimatedRewards({
5434
5522
  alt: ""
5435
5523
  }
5436
5524
  ),
5437
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-estimated-mask-title", children: "Complete to qualify for rewards!" }),
5438
- /* @__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") })
5439
5527
  ] })
5440
5528
  ] });
5441
5529
  }
5442
5530
  function RankingPoint({
5443
5531
  userStatus,
5444
- pointsName = "Points"
5532
+ pointsName
5445
5533
  }) {
5446
5534
  var _a, _b;
5535
+ const { t } = useQuestLocale();
5536
+ const resolvedPointsName = pointsName || t("points");
5447
5537
  const ranking = userStatus.ranking;
5448
5538
  const tier = userStatus.tier;
5449
5539
  const points = ((_a = userStatus.current_point) == null ? void 0 : _a.amount) ?? 0;
5450
- 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;
5451
5541
  const hasValidRanking = ranking >= 0;
5452
5542
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point", children: [
5453
5543
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-row", children: [
5454
5544
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-label", children: [
5455
- "Your Ranking",
5545
+ t("ranking"),
5456
5546
  /* @__PURE__ */ jsx(
5457
5547
  TipPopover,
5458
5548
  {
5459
- content: "You will be ranked only after completing all mandatory tasks in this quest.",
5549
+ content: t("ranked_after_completing_mandatory_tasks_quest"),
5460
5550
  side: "top",
5461
5551
  className: "taskon-quest-rewards-ranking-point-tip-icon"
5462
5552
  }
@@ -5464,21 +5554,20 @@ function RankingPoint({
5464
5554
  ] }),
5465
5555
  hasValidRanking ? /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-value", children: [
5466
5556
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-number", children: ranking }),
5467
- tier > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-tier", children: [
5468
- "Tier ",
5469
- tier
5470
- ] })
5471
- ] }) : /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-tip", children: [
5472
- "Complete all ",
5473
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-ranking-point-tip-highlight", children: "REQUIRED" }),
5474
- " tasks to secure a valid ranking."
5475
- ] })
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
+ ) })
5476
5568
  ] }),
5477
5569
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-row taskon-quest-rewards-ranking-point-row--points", children: [
5478
- /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-ranking-point-label", children: [
5479
- "Your ",
5480
- displayPointsName
5481
- ] }),
5570
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-label", children: t("pointname", { pointName: displayPointsName }) }),
5482
5571
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-ranking-point-amount", children: points })
5483
5572
  ] })
5484
5573
  ] });
@@ -5486,8 +5575,10 @@ function RankingPoint({
5486
5575
  function RewardBonus({
5487
5576
  extraBonus,
5488
5577
  qualifierRewards,
5489
- pointName = "Points"
5578
+ pointName
5490
5579
  }) {
5580
+ const { t } = useQuestLocale();
5581
+ const resolvedPointName = pointName || t("points");
5491
5582
  const qualifierPointParams = useMemo(() => {
5492
5583
  const pointsReward = qualifierRewards == null ? void 0 : qualifierRewards.find(
5493
5584
  (item) => item.reward_type === QuestRewardType.Points || item.reward_type === QuestRewardType.GTCPoints
@@ -5499,13 +5590,16 @@ function RewardBonus({
5499
5590
  return null;
5500
5591
  }
5501
5592
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus", children: [
5502
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: "Bonus" }),
5593
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-title", children: t("bonus") }),
5503
5594
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-bonus-card", children: [
5504
- extraBonus && /* @__PURE__ */ jsx(BaseRow, { label: "Winner Bonus", children: /* @__PURE__ */ jsx("div", { className: "taskon-quest-rewards-bonus-desc", children: extraBonus }) }),
5505
- 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: [
5506
5597
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-amount", children: qualifierPointParams.amount }),
5507
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-bonus-name", children: qualifierPointParams.points_name || pointName }),
5508
- /* @__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
+ ] })
5509
5603
  ] }) })
5510
5604
  ] })
5511
5605
  ] });
@@ -5714,10 +5808,7 @@ function formatLongStr$1(str, separator = "...", prefixLen = 6, suffixLen = 6) {
5714
5808
  if (str.length <= prefixLen + suffixLen + 2) return str;
5715
5809
  return `${str.slice(0, prefixLen)}${separator}${str.slice(-suffixLen)}`;
5716
5810
  }
5717
- const NA_TIPS = "You will be ranked only after completing all mandatory tasks in this quest.";
5718
- const UNRANKED_TIP = "You are not ranked yet.";
5719
- const NOT_QUALIFIED_TIP = "You are not qualified for rewards in this tier.";
5720
- function getRewardTypeLabel(rewardType, pointsName) {
5811
+ function getRewardTypeLabel(rewardType, pointsName, t) {
5721
5812
  if (!rewardType) return "";
5722
5813
  switch (rewardType) {
5723
5814
  case RewardType.Nft:
@@ -5725,21 +5816,21 @@ function getRewardTypeLabel(rewardType, pointsName) {
5725
5816
  case RewardType.Cap:
5726
5817
  return "NFT:";
5727
5818
  case RewardType.DiscordRole:
5728
- return "Discord Role:";
5819
+ return `${t("discord_role")}:`;
5729
5820
  case RewardType.Exp:
5730
5821
  return "EXP:";
5731
5822
  case RewardType.GTCPoints:
5732
5823
  case RewardType.Points:
5733
5824
  return `${pointsName}:`;
5734
5825
  case RewardType.Token:
5735
- return "Token:";
5826
+ return `${t("token_name")}:`;
5736
5827
  case RewardType.Whitelist:
5737
- return "Whitelist";
5828
+ return t("whitelist");
5738
5829
  default:
5739
5830
  return "";
5740
5831
  }
5741
5832
  }
5742
- function getRewardLabel(row) {
5833
+ function getRewardLabel(row, t) {
5743
5834
  const { rewardType, rewardSymbol, rewardAmount, chainLabel, isUsdtEqual } = row;
5744
5835
  if (!rewardType) {
5745
5836
  return rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : "";
@@ -5757,7 +5848,9 @@ function getRewardLabel(row) {
5757
5848
  return rewardAmount || "";
5758
5849
  case RewardType.Token:
5759
5850
  if (isUsdtEqual) {
5760
- return `${rewardAmount} USD in ${rewardSymbol}`;
5851
+ return `${rewardAmount || ""} ${t("usd_token_name", {
5852
+ token_name: rewardSymbol || ""
5853
+ })}`.trim();
5761
5854
  }
5762
5855
  return `${rewardAmount} ${rewardSymbol}${chainLabel ? ` ${chainLabel}` : ""}`;
5763
5856
  case RewardType.Whitelist:
@@ -5767,25 +5860,44 @@ function getRewardLabel(row) {
5767
5860
  }
5768
5861
  }
5769
5862
  function RewardCell({ row }) {
5863
+ const { t } = useQuestLocale();
5864
+ const translate = t;
5770
5865
  if (row.winnerLayer !== void 0 && row.winnerLayer < 0) {
5771
- 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
+ ) });
5772
5874
  }
5773
5875
  if (!row.rewardAmount) {
5774
5876
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-no-reward", children: "--" });
5775
5877
  }
5776
- const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName);
5777
- const rewardLabel = getRewardLabel(row);
5878
+ const typeLabel = getRewardTypeLabel(row.rewardType, row.pointsName, translate);
5879
+ const rewardLabel = getRewardLabel(row, translate);
5778
5880
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-reward-cell", children: [
5779
5881
  typeLabel && /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward-type", children: typeLabel }),
5780
5882
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-reward", children: rewardLabel })
5781
5883
  ] });
5782
5884
  }
5783
5885
  function RankBadge({ rank }) {
5886
+ const { t } = useQuestLocale();
5784
5887
  if (rank < 0) {
5785
- 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
+ ) });
5786
5898
  }
5787
5899
  if (rank === 0) {
5788
- 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") }) }) });
5789
5901
  }
5790
5902
  if (rank === 1) {
5791
5903
  return /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-rank", children: /* @__PURE__ */ jsx(Rank1Icon, { size: 24 }) });
@@ -5802,8 +5914,9 @@ function UserCell({
5802
5914
  userName,
5803
5915
  isCurrentUser
5804
5916
  }) {
5917
+ const { t } = useQuestLocale();
5805
5918
  if (isCurrentUser) {
5806
- 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") }) });
5807
5920
  }
5808
5921
  return /* @__PURE__ */ jsx("div", { className: "taskon-quest-leaderboard-user", children: /* @__PURE__ */ jsx("span", { className: "taskon-quest-leaderboard-user-name", children: formatLongStr$1(userName) }) });
5809
5922
  }
@@ -5830,10 +5943,12 @@ function LeaderboardModal({
5830
5943
  isOpen,
5831
5944
  onClose,
5832
5945
  campaignId,
5833
- pointsName = "Points",
5946
+ pointsName,
5834
5947
  className = ""
5835
5948
  }) {
5949
+ const { t } = useQuestLocale();
5836
5950
  const { client, userId } = useTaskOnContext();
5951
+ const resolvedPointsName = pointsName || t("points");
5837
5952
  const [data, setData] = useState(null);
5838
5953
  const [loading, setLoading] = useState(false);
5839
5954
  const [error, setError] = useState(null);
@@ -5852,11 +5967,11 @@ function LeaderboardModal({
5852
5967
  });
5853
5968
  setData(result);
5854
5969
  } catch (err) {
5855
- setError(err instanceof Error ? err.message : "Failed to load leaderboard");
5970
+ setError(err instanceof Error ? err.message : t("failed_load_leaderboard"));
5856
5971
  } finally {
5857
5972
  setLoading(false);
5858
5973
  }
5859
- }, [client, isOpen, campaignId, page]);
5974
+ }, [client, isOpen, campaignId, page, t]);
5860
5975
  useEffect(() => {
5861
5976
  if (isOpen) {
5862
5977
  fetchData();
@@ -5876,15 +5991,21 @@ function LeaderboardModal({
5876
5991
  if (!data) return 0;
5877
5992
  return Math.ceil(data.total / PAGE_SIZE);
5878
5993
  }, [data]);
5879
- 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.`;
5880
- const tierTip = NA_TIPS;
5881
- 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
+ );
5882
6003
  const columns = useMemo(
5883
6004
  () => [
5884
6005
  {
5885
6006
  key: "rank",
5886
6007
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5887
- /* @__PURE__ */ jsx("span", { children: "Position" }),
6008
+ /* @__PURE__ */ jsx("span", { children: t("position") }),
5888
6009
  /* @__PURE__ */ jsx(TipPopover, { content: positionTip, side: "top" })
5889
6010
  ] }),
5890
6011
  width: 100,
@@ -5893,15 +6014,15 @@ function LeaderboardModal({
5893
6014
  {
5894
6015
  key: "tier",
5895
6016
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5896
- /* @__PURE__ */ jsx("span", { children: "Tier" }),
6017
+ /* @__PURE__ */ jsx("span", { children: t("tier") }),
5897
6018
  /* @__PURE__ */ jsx(TipPopover, { content: tierTip, side: "top" })
5898
6019
  ] }),
5899
6020
  width: 80,
5900
- 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") })
5901
6022
  },
5902
6023
  {
5903
6024
  key: "user",
5904
- title: "User",
6025
+ title: t("user"),
5905
6026
  minWidth: 120,
5906
6027
  render: (_, row) => /* @__PURE__ */ jsx(
5907
6028
  UserCell,
@@ -5914,21 +6035,21 @@ function LeaderboardModal({
5914
6035
  {
5915
6036
  key: "points",
5916
6037
  title: /* @__PURE__ */ jsxs("span", { className: "taskon-quest-leaderboard-header", children: [
5917
- /* @__PURE__ */ jsx("span", { children: pointsName }),
6038
+ /* @__PURE__ */ jsx("span", { children: resolvedPointsName }),
5918
6039
  /* @__PURE__ */ jsx(TipPopover, { content: pointsTip, side: "top" })
5919
6040
  ] }),
5920
6041
  width: 100,
5921
- 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") })
5922
6043
  },
5923
6044
  {
5924
6045
  key: "rewards",
5925
- title: "Rewards",
6046
+ title: t("rewards"),
5926
6047
  width: 150,
5927
6048
  align: "right",
5928
6049
  render: (_, row) => /* @__PURE__ */ jsx(RewardCell, { row })
5929
6050
  }
5930
6051
  ],
5931
- [pointsName, positionTip, pointsTip, tierTip, userId]
6052
+ [positionTip, pointsTip, resolvedPointsName, t, tierTip, userId]
5932
6053
  );
5933
6054
  const rowConfig = useMemo(
5934
6055
  () => ({
@@ -5957,19 +6078,20 @@ function LeaderboardModal({
5957
6078
  onOpenChange: (open) => {
5958
6079
  if (!open) onClose();
5959
6080
  },
5960
- title: "Leaderboard",
6081
+ title: t("leaderboard"),
5961
6082
  showCloseButton: true,
5962
6083
  className,
5963
6084
  maxWidth: 600,
5964
6085
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-content", children: [
5965
- /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: "Leaderboard" }),
6086
+ /* @__PURE__ */ jsx("h2", { className: "taskon-quest-leaderboard-title", children: t("leaderboard") }),
5966
6087
  data && /* @__PURE__ */ jsxs("p", { className: "taskon-quest-leaderboard-subtitle", children: [
5967
6088
  data.total_user.toLocaleString(),
5968
- " participants"
6089
+ " ",
6090
+ t("participants_2")
5969
6091
  ] }),
5970
6092
  error && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-leaderboard-error", children: [
5971
6093
  /* @__PURE__ */ jsx("p", { children: error }),
5972
- /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: "Retry" })
6094
+ /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: fetchData, children: t("retry") })
5973
6095
  ] }),
5974
6096
  !error && /* @__PURE__ */ jsx(
5975
6097
  Table,
@@ -5978,10 +6100,10 @@ function LeaderboardModal({
5978
6100
  data: tableData,
5979
6101
  rowConfig,
5980
6102
  loading,
5981
- loadingText: "Loading...",
6103
+ loadingText: t("loading"),
5982
6104
  empty: {
5983
- title: "No Data",
5984
- description: "No participants yet"
6105
+ title: t("no_data"),
6106
+ description: t("no_participants")
5985
6107
  },
5986
6108
  striped: true,
5987
6109
  className: "taskon-quest-leaderboard-table"
@@ -6037,14 +6159,19 @@ function RewardCard$1({
6037
6159
  chains
6038
6160
  }) {
6039
6161
  var _a, _b, _c;
6162
+ const { t } = useQuestLocale();
6040
6163
  const [isDescOpen, setIsDescOpen] = useState(false);
6041
6164
  const isPointRanking = howToSelectWinner === "PointRanking";
6042
6165
  const ranking = (_a = rewardLayer.winner_layer) == null ? void 0 : _a.winner_rank_range;
6043
6166
  const rankingLabel = useMemo(() => {
6044
6167
  if (!ranking) return "";
6045
- return formatRankingLabel(ranking);
6046
- }, [ranking]);
6047
- const tierLabel = getTierLabel(layerIndex, isCurrentLayer);
6168
+ return formatRankingLabel(ranking, t);
6169
+ }, [ranking, t]);
6170
+ const tierLabel = getTierLabel(
6171
+ layerIndex,
6172
+ isCurrentLayer,
6173
+ t
6174
+ );
6048
6175
  const showEstimatedRewards = useMemo(() => {
6049
6176
  return rewardInfo.reward_distribute_type === QuestRewardsDistributeType.PointProportionally && totalPoints !== -1;
6050
6177
  }, [rewardInfo.reward_distribute_type, totalPoints]);
@@ -6135,7 +6262,7 @@ function RewardCard$1({
6135
6262
  className: "taskon-quest-rewards-whitelist-desc-trigger",
6136
6263
  onClick: () => setIsDescOpen(!isDescOpen),
6137
6264
  type: "button",
6138
- children: /* @__PURE__ */ jsx(BaseRow, { label: "Whitelist Description", children: /* @__PURE__ */ jsx(
6265
+ children: /* @__PURE__ */ jsx(BaseRow, { label: t("whitelist_description"), children: /* @__PURE__ */ jsx(
6139
6266
  UnfoldIcon,
6140
6267
  {
6141
6268
  className: `taskon-quest-rewards-whitelist-desc-icon ${isDescOpen ? "taskon-quest-rewards-whitelist-desc-icon--open" : ""}`
@@ -6175,12 +6302,13 @@ function WinnerGroup({
6175
6302
  groupIndex,
6176
6303
  chains
6177
6304
  }) {
6305
+ const { t } = useQuestLocale();
6178
6306
  const howToSelectWinner = useMemo(() => {
6179
6307
  return getHowToSelectWinner$1(group);
6180
6308
  }, [group]);
6181
6309
  const winnerSelectionLabel = useMemo(() => {
6182
- return getWinnerSelectionLabel$1(howToSelectWinner);
6183
- }, [howToSelectWinner]);
6310
+ return t(getWinnerSelectionLabel$1(howToSelectWinner));
6311
+ }, [howToSelectWinner, t]);
6184
6312
  const getTotalPoints = (layerIndex) => {
6185
6313
  if (group.automatically_winner_draw_type !== QuestAutomaticallyWinnerDrawType.PointRank) {
6186
6314
  return (userStatus == null ? void 0 : userStatus.open_to_all_total_points) || 0;
@@ -6226,12 +6354,14 @@ function QuestRewards({
6226
6354
  winnerRewards,
6227
6355
  campaignStatus,
6228
6356
  userStatus,
6229
- pointName = "Points",
6357
+ pointName,
6230
6358
  isEnded,
6231
6359
  isOngoingOrEnded = false,
6232
6360
  chains
6233
6361
  }) {
6234
6362
  var _a;
6363
+ const { t } = useQuestLocale();
6364
+ const resolvedPointName = pointName || t("points");
6235
6365
  const [isLeaderboardOpen, setIsLeaderboardOpen] = useState(false);
6236
6366
  if (!winnerRewards || winnerRewards.length === 0) {
6237
6367
  return null;
@@ -6248,7 +6378,7 @@ function QuestRewards({
6248
6378
  };
6249
6379
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards", children: [
6250
6380
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-container", children: [
6251
- showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: pointName }),
6381
+ showUserRanking && /* @__PURE__ */ jsx(RankingPoint, { userStatus, pointsName: resolvedPointName }),
6252
6382
  showViewLeaderboard && /* @__PURE__ */ jsxs(
6253
6383
  "button",
6254
6384
  {
@@ -6256,7 +6386,7 @@ function QuestRewards({
6256
6386
  className: "taskon-quest-rewards-view-leaderboard",
6257
6387
  onClick: handleOpenLeaderboard,
6258
6388
  children: [
6259
- /* @__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") }),
6260
6390
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-rewards-view-leaderboard-arrow", children: "→" })
6261
6391
  ]
6262
6392
  }
@@ -6266,7 +6396,7 @@ function QuestRewards({
6266
6396
  {
6267
6397
  group,
6268
6398
  currentWinners,
6269
- pointName,
6399
+ pointName: resolvedPointName,
6270
6400
  isEnded,
6271
6401
  userStatus,
6272
6402
  groupIndex,
@@ -6281,7 +6411,7 @@ function QuestRewards({
6281
6411
  isOpen: isLeaderboardOpen,
6282
6412
  onClose: handleCloseLeaderboard,
6283
6413
  campaignId,
6284
- pointsName: pointName
6414
+ pointsName: resolvedPointName
6285
6415
  }
6286
6416
  )
6287
6417
  ] });
@@ -6361,26 +6491,29 @@ function getHowToSelectWinner(winnerReward) {
6361
6491
  function getWinnerSelectionLabel(howToSelectWinner) {
6362
6492
  switch (howToSelectWinner) {
6363
6493
  case 1:
6364
- return { label: "Lucky Draw", desc: "Winners are randomly selected" };
6494
+ return { label: "lucky_draw", desc: "winners_randomly_selected" };
6365
6495
  case 0:
6366
6496
  return {
6367
- label: "FCFS",
6368
- desc: "First to complete gets the reward"
6497
+ label: "fcfs",
6498
+ desc: "first_complete_gets_reward"
6369
6499
  };
6370
6500
  case 4:
6371
6501
  return {
6372
- label: "Open to All",
6373
- desc: "All qualified users receive reward"
6502
+ label: "open",
6503
+ desc: "qualified_users_receive_reward"
6374
6504
  };
6375
6505
  case 3:
6376
- return { label: "Ranking", desc: "Top ranked users win" };
6506
+ return { label: "ranking_2", desc: "top_ranked_users_win" };
6377
6507
  case 2:
6378
6508
  return {
6379
- label: "Manually Upload",
6380
- desc: "Project owner selects winners"
6509
+ label: "manually_upload",
6510
+ desc: "project_owner_selects_winners"
6381
6511
  };
6382
6512
  default:
6383
- return { label: "", desc: "" };
6513
+ return {
6514
+ label: "fcfs",
6515
+ desc: "first_complete_gets_reward"
6516
+ };
6384
6517
  }
6385
6518
  }
6386
6519
  function getEarnedWinnerSelectionList(winnerRewards, userStatus, campaignStatus) {
@@ -6526,52 +6659,52 @@ function getStatusCardConfig(status, params) {
6526
6659
  case "winner":
6527
6660
  return {
6528
6661
  badgeType: "winner",
6529
- title: "Congratulations!"
6662
+ title: "congratulations"
6530
6663
  };
6531
6664
  case "blind-box-failed":
6532
6665
  case "qualifier-failed":
6533
6666
  return {
6534
6667
  badgeType: "qualifier",
6535
- title: "Oops! Better Luck Next Time!",
6536
- description: "You have won multiple rewards!"
6668
+ title: "oops_better_luck_next_time",
6669
+ description: "won_multiple_rewards"
6537
6670
  // Will be overridden if has rewards
6538
6671
  };
6539
6672
  case "qualifier-wait":
6540
6673
  if (params == null ? void 0 : params.hasLegacyManual) {
6541
6674
  return {
6542
6675
  badgeType: "qualifier",
6543
- title: "Successfully Entered!",
6544
- 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"
6545
6678
  };
6546
6679
  }
6547
6680
  if (params == null ? void 0 : params.hasPointRanking) {
6548
6681
  return {
6549
6682
  badgeType: "qualifier",
6550
- title: "Successfully Entered!",
6551
- 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"
6552
6685
  };
6553
6686
  }
6554
6687
  return {
6555
6688
  badgeType: "qualifier",
6556
- title: "Waiting for drawing winners",
6557
- 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"
6558
6691
  };
6559
6692
  case "submitter-failed":
6560
6693
  return {
6561
6694
  badgeType: "submitter",
6562
- title: "Oops!",
6563
- description: "Not all tasks are successfully verified, better luck next time!"
6695
+ title: "oops",
6696
+ description: "tasks_successfully_verified_better_luck_next_time"
6564
6697
  };
6565
6698
  case "submitter-wait":
6566
6699
  return {
6567
6700
  badgeType: "submitter",
6568
- title: "Waiting For Task Verification",
6569
- 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"
6570
6703
  };
6571
6704
  case "too-late":
6572
6705
  return {
6573
- title: "Oops!",
6574
- description: "Sorry you are late."
6706
+ title: "oops",
6707
+ description: "sorry_late"
6575
6708
  };
6576
6709
  case "can-complete":
6577
6710
  return null;
@@ -6612,6 +6745,7 @@ function RewardToken({
6612
6745
  rewardDisplayMode = "popup",
6613
6746
  rewardRedirectUrl
6614
6747
  }) {
6748
+ const { t } = useQuestLocale();
6615
6749
  const [popupOpen, setPopupOpen] = useState(false);
6616
6750
  const params = reward.reward_value;
6617
6751
  const chainInfo = useMemo(() => {
@@ -6635,10 +6769,10 @@ function RewardToken({
6635
6769
  }, [params.amount]);
6636
6770
  const typeText = useMemo(() => {
6637
6771
  if (params.is_usdt_equal_amount) {
6638
- return `USD in ${params.token_name}`;
6772
+ return t("usd_token_name", { token_name: params.token_name });
6639
6773
  }
6640
6774
  return params.token_name;
6641
- }, [params.is_usdt_equal_amount, params.token_name]);
6775
+ }, [params.is_usdt_equal_amount, params.token_name, t]);
6642
6776
  const showAmountNotRevealed = !params.amount;
6643
6777
  const showWithdraw = isDeposited && params.amount;
6644
6778
  const handleWithdraw = useCallback(() => {
@@ -6663,9 +6797,9 @@ function RewardToken({
6663
6797
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: formattedAmount })
6664
6798
  ] }),
6665
6799
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: typeText }),
6666
- showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: "Withdraw" })
6800
+ showWithdraw && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleWithdraw, children: t("withdraw") })
6667
6801
  ] }),
6668
- 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") })
6669
6803
  ] }),
6670
6804
  /* @__PURE__ */ jsx(
6671
6805
  RewardModuleDialog,
@@ -6741,6 +6875,7 @@ function RewardNft({
6741
6875
  onRefresh,
6742
6876
  onClaimNft
6743
6877
  }) {
6878
+ const { t } = useQuestLocale();
6744
6879
  const [loading, setLoading] = useState(false);
6745
6880
  const params = reward.reward_value;
6746
6881
  const chainInfo = useMemo(() => {
@@ -6782,10 +6917,10 @@ function RewardNft({
6782
6917
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6783
6918
  ] }),
6784
6919
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6785
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6920
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6786
6921
  ] }),
6787
- openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: "Check Collection on OpenSea" }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6788
- /* @__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") }),
6789
6924
  /* @__PURE__ */ jsx(
6790
6925
  "a",
6791
6926
  {
@@ -6806,6 +6941,7 @@ function RewardMintedNft({
6806
6941
  onRefresh,
6807
6942
  onClaimNft
6808
6943
  }) {
6944
+ const { t } = useQuestLocale();
6809
6945
  const [loading, setLoading] = useState(false);
6810
6946
  const params = reward.reward_value;
6811
6947
  const chainInfo = useMemo(() => {
@@ -6850,10 +6986,10 @@ function RewardMintedNft({
6850
6986
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-type", children: "NFT" })
6851
6987
  ] }),
6852
6988
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.collection_name }),
6853
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
6989
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6854
6990
  ] }),
6855
- openseaLink ? /* @__PURE__ */ jsx(ActionButton, { href: openseaLink, children: "Check Collection on OpenSea" }) : params.tx_hash && chainInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-reward-tx", children: [
6856
- /* @__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") }),
6857
6993
  /* @__PURE__ */ jsx(
6858
6994
  "a",
6859
6995
  {
@@ -6865,7 +7001,7 @@ function RewardMintedNft({
6865
7001
  }
6866
7002
  )
6867
7003
  ] }),
6868
- 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") })
6869
7005
  ] });
6870
7006
  }
6871
7007
  function RewardCap({
@@ -6875,6 +7011,7 @@ function RewardCap({
6875
7011
  onRefresh,
6876
7012
  onClaimNft
6877
7013
  }) {
7014
+ const { t } = useQuestLocale();
6878
7015
  const [loading, setLoading] = useState(false);
6879
7016
  const params = reward.reward_value;
6880
7017
  const chainInfo = useMemo(() => {
@@ -6913,18 +7050,19 @@ function RewardCap({
6913
7050
  className: "taskon-quest-footer-earned-single-icon"
6914
7051
  }
6915
7052
  ),
6916
- /* @__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" })
6917
7054
  ] }),
6918
- params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: "Claim" })
7055
+ params.claimable && /* @__PURE__ */ jsx(ClaimButton, { onClick: handleClaim, loading, children: t("claim") })
6919
7056
  ] }),
6920
- elementLink && /* @__PURE__ */ jsx(ActionButton, { href: elementLink, children: "Check CAP on Element" }),
6921
- 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") })
6922
7059
  ] });
6923
7060
  }
6924
7061
  function RewardWhitelist({
6925
7062
  reward,
6926
7063
  chains
6927
7064
  }) {
7065
+ const { t } = useQuestLocale();
6928
7066
  const params = reward.reward_value;
6929
7067
  const chainInfo = useMemo(() => {
6930
7068
  if (!chains || !params.chain) return null;
@@ -6939,7 +7077,7 @@ function RewardWhitelist({
6939
7077
  className: "taskon-quest-footer-earned-single-icon"
6940
7078
  }
6941
7079
  ),
6942
- /* @__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") })
6943
7081
  ] }) }) });
6944
7082
  }
6945
7083
  function RewardPoint({
@@ -6947,14 +7085,15 @@ function RewardPoint({
6947
7085
  rewardDisplayMode = "popup",
6948
7086
  rewardRedirectUrl
6949
7087
  }) {
7088
+ const { t } = useQuestLocale();
6950
7089
  const [popupOpen, setPopupOpen] = useState(false);
6951
7090
  const params = reward.reward_value;
6952
7091
  const pointName = useMemo(() => {
6953
7092
  if (reward.reward_type === RewardType.GTCPoints) {
6954
- return params.points_name || "Points";
7093
+ return params.points_name || t("points");
6955
7094
  }
6956
- return "Points";
6957
- }, [reward.reward_type, params.points_name]);
7095
+ return t("points");
7096
+ }, [reward.reward_type, params.points_name, t]);
6958
7097
  const handlePointsHistory = useCallback(() => {
6959
7098
  if (rewardDisplayMode === "redirect" && rewardRedirectUrl) {
6960
7099
  window.open(rewardRedirectUrl, "_blank", "noopener,noreferrer");
@@ -6969,7 +7108,7 @@ function RewardPoint({
6969
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 }) }),
6970
7109
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: pointName })
6971
7110
  ] }),
6972
- /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: "Points History" })
7111
+ /* @__PURE__ */ jsx(ActionButton, { ...actionButtonProps, children: t("points_history") })
6973
7112
  ] }),
6974
7113
  /* @__PURE__ */ jsx(
6975
7114
  RewardModuleDialog,
@@ -6988,6 +7127,7 @@ function RewardDiscordRole({
6988
7127
  onRefresh,
6989
7128
  onClaimDiscordRole
6990
7129
  }) {
7130
+ const { t } = useQuestLocale();
6991
7131
  const [loading, setLoading] = useState(false);
6992
7132
  const params = reward.reward_value;
6993
7133
  const isClaimable = useMemo(() => {
@@ -7009,9 +7149,9 @@ function RewardDiscordRole({
7009
7149
  }
7010
7150
  }, [onClaimDiscordRole, reward, layer, onRefresh]);
7011
7151
  return /* @__PURE__ */ jsx(RewardCard, { children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-single-row", children: [
7012
- /* @__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") }) }),
7013
7153
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-earned-single-name", children: params.role_name }),
7014
- 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") })
7015
7155
  ] }) });
7016
7156
  }
7017
7157
  const REWARD_COMPONENT_MAP = {
@@ -7035,24 +7175,24 @@ function RewardItem(props) {
7035
7175
  }
7036
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";
7037
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";
7038
- function getFailedLabel(status) {
7178
+ function getFailedLabel(status, t) {
7039
7179
  if (status === "join-earlier") {
7040
- return "Join the quest earlier next time!";
7180
+ return t("join_quest_earlier_next_time");
7041
7181
  }
7042
7182
  if (status === "better-luck") {
7043
- return "Oops, Better Luck Next Time!";
7183
+ return t("oops_better_luck_next_time_2");
7044
7184
  }
7045
7185
  return "";
7046
7186
  }
7047
- function getWaitLabel(status) {
7187
+ function getWaitLabel(status, t) {
7048
7188
  if (status === "wait-draw") {
7049
- return "Waiting for drawing winners, Stay tuned to see if you win!";
7189
+ return t("waiting_drawing_winners_stay_tuned_see_win");
7050
7190
  }
7051
7191
  if (status === "wait-upload") {
7052
- 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");
7053
7193
  }
7054
7194
  if (status === "wait-ranking") {
7055
- return "Waiting For Final Ranking, Stay tuned to see if you win!";
7195
+ return t("waiting_final_ranking_stay_tuned_see_win");
7056
7196
  }
7057
7197
  return "";
7058
7198
  }
@@ -7068,12 +7208,14 @@ function SelectionItem({
7068
7208
  rewardDisplayMode,
7069
7209
  rewardRedirectUrl
7070
7210
  }) {
7211
+ const { t } = useQuestLocale();
7071
7212
  const { howToSelectWinner, status, rewards } = selection;
7072
7213
  const label = getWinnerSelectionLabel(howToSelectWinner);
7073
- const failedLabel = getFailedLabel(status);
7074
- const waitLabel = getWaitLabel(status);
7214
+ const translate = t;
7215
+ const failedLabel = getFailedLabel(status, translate);
7216
+ const waitLabel = getWaitLabel(status, translate);
7075
7217
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-item", children: [
7076
- /* @__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) }),
7077
7219
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-selection-rewards", children: [
7078
7220
  status === "winner" && rewards.map((layer) => /* @__PURE__ */ jsx(React__default.Fragment, { children: layer.reward.map((reward) => /* @__PURE__ */ jsx(
7079
7221
  RewardItem,
@@ -7132,6 +7274,7 @@ function DetailPanelDialog({
7132
7274
  rewardDisplayMode,
7133
7275
  rewardRedirectUrl
7134
7276
  }) {
7277
+ const { t } = useQuestLocale();
7135
7278
  const winnerSelectionList = useMemo(() => {
7136
7279
  return getEarnedWinnerSelectionList(
7137
7280
  campaign.winner_rewards,
@@ -7143,7 +7286,7 @@ function DetailPanelDialog({
7143
7286
  const qualifierRewards = campaign.qualifier_rewards;
7144
7287
  if (!qualifierRewards) return null;
7145
7288
  const reward = qualifierRewards.find(
7146
- (item) => item.reward_type === "Points" || item.reward_type === "GTCPoints"
7289
+ (item) => item.reward_type === "points" || item.reward_type === "GTCPoints"
7147
7290
  );
7148
7291
  if (!reward) return null;
7149
7292
  return reward.reward_params;
@@ -7153,12 +7296,12 @@ function DetailPanelDialog({
7153
7296
  {
7154
7297
  open,
7155
7298
  onOpenChange,
7156
- title: "Multiple Rewards Detail",
7299
+ title: t("multiple_rewards_detail"),
7157
7300
  showCloseButton: true,
7158
7301
  maxWidth: 480,
7159
7302
  contentClassName: "taskon-quest-footer-detail-dialog",
7160
7303
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-panel", children: [
7161
- /* @__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") }),
7162
7305
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-content", children: winnerSelectionList.map((item, index) => /* @__PURE__ */ jsx(
7163
7306
  SelectionItem,
7164
7307
  {
@@ -7176,13 +7319,11 @@ function DetailPanelDialog({
7176
7319
  index
7177
7320
  )) }),
7178
7321
  qualifierPointParams && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-bonus", children: [
7179
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-label", children: "Bonus" }),
7180
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-detail-bonus-right", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-detail-bonus-item", children: [
7181
- qualifierPointParams.amount,
7182
- " Qualifier",
7183
- " ",
7184
- qualifierPointParams.points_name || "Points"
7185
- ] }) })
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
+ }) }) })
7186
7327
  ] })
7187
7328
  ] })
7188
7329
  }
@@ -7202,6 +7343,7 @@ function EarnedRewards({
7202
7343
  rewardDisplayMode = "popup",
7203
7344
  rewardRedirectUrl
7204
7345
  }) {
7346
+ const { t } = useQuestLocale();
7205
7347
  const [dialogOpen, setDialogOpen] = useState(false);
7206
7348
  const rewardCount = useMemo(() => {
7207
7349
  return earnedRewards.reduce(
@@ -7230,8 +7372,8 @@ function EarnedRewards({
7230
7372
  hasMultiReward ? (
7231
7373
  // Multiple rewards: show text + button
7232
7374
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-footer-earned-multi", children: [
7233
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-earned-multi-text", children: "You have won multiple rewards!" }),
7234
- /* @__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") })
7235
7377
  ] })
7236
7378
  ) : (
7237
7379
  // Single reward: show detailed card
@@ -7273,7 +7415,13 @@ function EarnedRewards({
7273
7415
  ] });
7274
7416
  }
7275
7417
  function StatusBadge({ type }) {
7276
- 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];
7277
7425
  return /* @__PURE__ */ jsx("div", { className: `taskon-quest-footer-badge taskon-quest-footer-badge--${type}`, children: badgeText });
7278
7426
  }
7279
7427
  function StatusCard(props) {
@@ -7325,19 +7473,21 @@ function StatusCard(props) {
7325
7473
  ) : /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-card-message", children: description }) })
7326
7474
  ] });
7327
7475
  }
7328
- const REPEAT_SUBMIT_ERROR_MESSAGE = "Oops! Seems like you already finished this quest";
7329
- const DEFAULT_COMPLETE_ERROR_MESSAGE = "Failed to complete quest";
7330
- function normalizeCompleteSubmitError(error) {
7476
+ function normalizeCompleteSubmitError(error, t) {
7331
7477
  if (error instanceof ApiError) {
7332
7478
  if (error.code === ErrorCode.RUSER_REPEAT_SUBMIT) {
7333
- 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
+ );
7334
7484
  }
7335
7485
  return error;
7336
7486
  }
7337
7487
  if (error instanceof Error) {
7338
7488
  return error;
7339
7489
  }
7340
- return new Error(DEFAULT_COMPLETE_ERROR_MESSAGE);
7490
+ return new Error(t("failed_complete_quest"));
7341
7491
  }
7342
7492
  function CompleteButton({
7343
7493
  campaignId,
@@ -7350,13 +7500,14 @@ function CompleteButton({
7350
7500
  className,
7351
7501
  onBeforeComplete
7352
7502
  }) {
7503
+ const { t } = useQuestLocale();
7353
7504
  const [isLoading, setIsLoading] = useState(false);
7354
7505
  const { client } = useTaskOnContext();
7355
7506
  const api = useMemo(() => {
7356
7507
  if (!client) return null;
7357
7508
  return createQuestApi(client);
7358
7509
  }, [client]);
7359
- const buttonText = hasPointProportionally2 ? "Complete to qualify for rewards!" : "Complete";
7510
+ const buttonText = hasPointProportionally2 ? t("complete_qualify_rewards") : t("complete_2");
7360
7511
  const handleComplete = useCallback(async () => {
7361
7512
  if (!api || isLoading || disabled) {
7362
7513
  return;
@@ -7375,7 +7526,7 @@ function CompleteButton({
7375
7526
  }
7376
7527
  }
7377
7528
  if (requiresRecaptcha && !captchaToken) {
7378
- onError == null ? void 0 : onError(new Error("reCAPTCHA verification required"));
7529
+ onError == null ? void 0 : onError(new Error(t("recaptcha_verification_required")));
7379
7530
  return;
7380
7531
  }
7381
7532
  try {
@@ -7387,7 +7538,10 @@ function CompleteButton({
7387
7538
  });
7388
7539
  onComplete == null ? void 0 : onComplete();
7389
7540
  } catch (error) {
7390
- const normalizedError = normalizeCompleteSubmitError(error);
7541
+ const normalizedError = normalizeCompleteSubmitError(
7542
+ error,
7543
+ t
7544
+ );
7391
7545
  onError == null ? void 0 : onError(normalizedError);
7392
7546
  }
7393
7547
  } finally {
@@ -7402,7 +7556,8 @@ function CompleteButton({
7402
7556
  onBeforeComplete,
7403
7557
  onComplete,
7404
7558
  onError,
7405
- requiresRecaptcha
7559
+ requiresRecaptcha,
7560
+ t
7406
7561
  ]);
7407
7562
  return /* @__PURE__ */ jsx(
7408
7563
  "button",
@@ -7413,15 +7568,13 @@ function CompleteButton({
7413
7568
  disabled: disabled || isLoading || !api,
7414
7569
  children: isLoading ? /* @__PURE__ */ jsxs("span", { className: "taskon-quest-footer-complete-btn-loading", children: [
7415
7570
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-footer-complete-btn-spinner" }),
7416
- "Completing..."
7571
+ t("completing")
7417
7572
  ] }) : buttonText
7418
7573
  }
7419
7574
  );
7420
7575
  }
7421
- const REPEAT_SUBMIT_NOTICE_TITLE = "Oops! Seems like You already finished this quest";
7422
- const REPEAT_SUBMIT_NOTICE_DESC = "To ensure a fair experience, submissions with identical wallet addresses, X, Discord, or Telegram accounts, and email addresses are not permitted.";
7423
- const REPEAT_SUBMIT_NOTICE_CONFIRM = "Confirm";
7424
7576
  function OperateFooter(props) {
7577
+ const { t } = useQuestLocale();
7425
7578
  const {
7426
7579
  campaign,
7427
7580
  userStatus,
@@ -7482,12 +7635,22 @@ function OperateFooter(props) {
7482
7635
  hasPointRanking: hasRanking
7483
7636
  });
7484
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]);
7485
7648
  const renderConnectWallet = () => /* @__PURE__ */ jsx("div", { className: "taskon-quest-footer-connect", children: /* @__PURE__ */ jsx(
7486
7649
  "button",
7487
7650
  {
7488
7651
  className: "taskon-quest-footer-connect-btn",
7489
7652
  onClick: onConnectWallet,
7490
- children: "Connect Wallet to Participate"
7653
+ children: t("connect_wallet_participate")
7491
7654
  }
7492
7655
  ) });
7493
7656
  const handleCompleteError = useCallback(
@@ -7513,13 +7676,13 @@ function OperateFooter(props) {
7513
7676
  }
7514
7677
  );
7515
7678
  const renderStatusCard = () => {
7516
- if (!cardConfig) return null;
7679
+ if (!localizedCardConfig) return null;
7517
7680
  return /* @__PURE__ */ jsx(
7518
7681
  StatusCard,
7519
7682
  {
7520
- title: cardConfig.title,
7521
- badgeType: cardConfig.badgeType,
7522
- description: cardConfig.description,
7683
+ title: localizedCardConfig.title,
7684
+ badgeType: localizedCardConfig.badgeType,
7685
+ description: localizedCardConfig.description,
7523
7686
  campaign,
7524
7687
  userStatus: userStatus || void 0,
7525
7688
  campaignStatus: campaignStatus || void 0,
@@ -7541,12 +7704,16 @@ function OperateFooter(props) {
7541
7704
  open: isRepeatSubmitDialogVisible,
7542
7705
  onOpenChange: setIsRepeatSubmitDialogVisible,
7543
7706
  type: "warn",
7544
- title: REPEAT_SUBMIT_NOTICE_TITLE,
7545
- desc: REPEAT_SUBMIT_NOTICE_DESC,
7546
- 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"),
7547
7712
  onConfirm: () => setIsRepeatSubmitDialogVisible(false),
7548
- accessibilityTitle: REPEAT_SUBMIT_NOTICE_TITLE,
7549
- 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
+ )
7550
7717
  }
7551
7718
  );
7552
7719
  let footerContent = null;
@@ -7554,7 +7721,7 @@ function OperateFooter(props) {
7554
7721
  footerContent = renderConnectWallet();
7555
7722
  } else if (participationStatus === "can-complete") {
7556
7723
  footerContent = renderCompleteButton();
7557
- } else if (participationStatus !== "none" && cardConfig) {
7724
+ } else if (participationStatus !== "none" && localizedCardConfig) {
7558
7725
  footerContent = renderStatusCard();
7559
7726
  }
7560
7727
  if (!footerContent && !isRepeatSubmitDialogVisible) {
@@ -7565,16 +7732,16 @@ function OperateFooter(props) {
7565
7732
  renderRepeatSubmitNoticeDialog()
7566
7733
  ] });
7567
7734
  }
7568
- function getDialogTitle(errorType) {
7735
+ function getDialogTitle(errorType, t) {
7569
7736
  switch (errorType) {
7570
7737
  case "mandatory":
7571
- return "Tasks Incomplete";
7738
+ return t("tasks_incomplete");
7572
7739
  case "optional_count":
7573
- return "More Tasks Required";
7740
+ return t("tasks_required");
7574
7741
  case "optional_points":
7575
- return "More Points Required";
7742
+ return t("points_required");
7576
7743
  default:
7577
- return "Validation Failed";
7744
+ return t("validation_failed");
7578
7745
  }
7579
7746
  }
7580
7747
  function getDialogIcon(errorType) {
@@ -7608,6 +7775,7 @@ function TaskValidationDialog({
7608
7775
  error,
7609
7776
  onClose
7610
7777
  }) {
7778
+ const { t } = useQuestLocale();
7611
7779
  return /* @__PURE__ */ jsx(
7612
7780
  Dialog,
7613
7781
  {
@@ -7617,32 +7785,29 @@ function TaskValidationDialog({
7617
7785
  onClose();
7618
7786
  }
7619
7787
  },
7620
- title: getDialogTitle(error == null ? void 0 : error.type),
7788
+ title: getDialogTitle(
7789
+ error == null ? void 0 : error.type,
7790
+ t
7791
+ ),
7621
7792
  showCloseButton: true,
7622
7793
  maxWidth: 400,
7623
7794
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-task-validation-dialog", children: [
7624
7795
  /* @__PURE__ */ jsx("div", { className: "taskon-task-validation-dialog-icon-wrap", children: getDialogIcon(error == null ? void 0 : error.type) }),
7625
- /* @__PURE__ */ jsx("p", { className: "taskon-task-validation-dialog-message", children: (error == null ? void 0 : error.message) || "Please complete all required tasks before continuing." }),
7626
- (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: [
7627
- "Completed: ",
7628
- error.current,
7629
- " / ",
7630
- error.required,
7631
- " optional tasks"
7632
- ] }),
7633
- (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: [
7634
- "Earned: ",
7635
- error.current,
7636
- " / ",
7637
- error.required,
7638
- " points"
7639
- ] }),
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
+ }) }),
7640
7805
  /* @__PURE__ */ jsx(
7641
7806
  "button",
7642
7807
  {
7643
7808
  className: "taskon-task-validation-dialog-btn",
7644
7809
  onClick: onClose,
7645
- children: "OK"
7810
+ children: t("ok")
7646
7811
  }
7647
7812
  )
7648
7813
  ] })
@@ -7650,7 +7815,7 @@ function TaskValidationDialog({
7650
7815
  );
7651
7816
  }
7652
7817
  const CHAIN_TYPE_LABELS = {
7653
- evm: "EVM Chain",
7818
+ evm: "evm_chain",
7654
7819
  btc: "Bitcoin",
7655
7820
  starknet: "Starknet",
7656
7821
  solana: "Solana",
@@ -7662,6 +7827,7 @@ const CHAIN_TYPE_LABELS = {
7662
7827
  ton: "TON"
7663
7828
  };
7664
7829
  function BindItem({ chainType, isBinding, isBound, onBind }) {
7830
+ const { t } = useQuestLocale();
7665
7831
  const label = CHAIN_TYPE_LABELS[chainType.toLowerCase()] || chainType;
7666
7832
  return /* @__PURE__ */ jsxs("div", { className: `taskon-reward-bind-item ${isBound ? "taskon-reward-bind-item--bound" : ""}`, children: [
7667
7833
  /* @__PURE__ */ jsx("span", { className: "taskon-reward-bind-item-label", children: label }),
@@ -7676,7 +7842,7 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7676
7842
  strokeLinejoin: "round"
7677
7843
  }
7678
7844
  ) }),
7679
- "Bound"
7845
+ t("bound")
7680
7846
  ] }) : /* @__PURE__ */ jsx(
7681
7847
  "button",
7682
7848
  {
@@ -7696,8 +7862,8 @@ function BindItem({ chainType, isBinding, isBound, onBind }) {
7696
7862
  strokeDasharray: "31.4 31.4"
7697
7863
  }
7698
7864
  ) }),
7699
- "Binding..."
7700
- ] }) : "Bind"
7865
+ t("binding")
7866
+ ] }) : t("bind")
7701
7867
  }
7702
7868
  )
7703
7869
  ] });
@@ -7711,6 +7877,7 @@ function RewardBindDialog({
7711
7877
  onAllBind,
7712
7878
  onBindChain
7713
7879
  }) {
7880
+ const { t } = useQuestLocale();
7714
7881
  const [notBoundChains, setNotBoundChains] = useState(chainTypes);
7715
7882
  const [bindingType, setBindingType] = useState(null);
7716
7883
  React__default.useEffect(() => {
@@ -7729,7 +7896,7 @@ function RewardBindDialog({
7729
7896
  try {
7730
7897
  const success = await onBindChain(chainType);
7731
7898
  if (success) {
7732
- setNotBoundChains((prev) => prev.filter((t) => t !== chainType));
7899
+ setNotBoundChains((prev) => prev.filter((t2) => t2 !== chainType));
7733
7900
  }
7734
7901
  } finally {
7735
7902
  setBindingType(null);
@@ -7742,7 +7909,7 @@ function RewardBindDialog({
7742
7909
  onClose();
7743
7910
  }
7744
7911
  }, [skippable, onSkip, onClose]);
7745
- 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");
7746
7913
  return /* @__PURE__ */ jsx(
7747
7914
  Dialog,
7748
7915
  {
@@ -7752,7 +7919,7 @@ function RewardBindDialog({
7752
7919
  handleClose();
7753
7920
  }
7754
7921
  },
7755
- title: "Link Wallet Address",
7922
+ title: t("link_wallet_address"),
7756
7923
  showCloseButton: true,
7757
7924
  maxWidth: 480,
7758
7925
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-reward-bind-dialog", children: [
@@ -7772,7 +7939,7 @@ function RewardBindDialog({
7772
7939
  {
7773
7940
  className: "taskon-reward-bind-skip-btn",
7774
7941
  onClick: onSkip,
7775
- children: "Complete the Campaign"
7942
+ children: t("complete_campaign_2")
7776
7943
  }
7777
7944
  )
7778
7945
  ] })
@@ -7808,6 +7975,7 @@ function DiscordBindDialog({
7808
7975
  onLinkDiscord,
7809
7976
  onContinue
7810
7977
  }) {
7978
+ const { t } = useQuestLocale();
7811
7979
  return /* @__PURE__ */ jsx(
7812
7980
  Dialog,
7813
7981
  {
@@ -7817,19 +7985,23 @@ function DiscordBindDialog({
7817
7985
  onClose();
7818
7986
  }
7819
7987
  },
7820
- title: "Discord Account Not Linked",
7988
+ title: t("discord_account_linked"),
7821
7989
  showCloseButton: true,
7822
7990
  maxWidth: 440,
7823
7991
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog", children: [
7824
7992
  /* @__PURE__ */ jsx("div", { className: "taskon-discord-bind-dialog-icon-wrap", children: /* @__PURE__ */ jsx(DiscordIcon, {}) }),
7825
- /* @__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
+ ] }),
7826
7998
  /* @__PURE__ */ jsxs("div", { className: "taskon-discord-bind-dialog-buttons", children: [
7827
7999
  /* @__PURE__ */ jsx(
7828
8000
  "button",
7829
8001
  {
7830
8002
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--secondary",
7831
8003
  onClick: onLinkDiscord,
7832
- children: "Link Discord Account"
8004
+ children: t("link_discord_account")
7833
8005
  }
7834
8006
  ),
7835
8007
  /* @__PURE__ */ jsx(
@@ -7837,7 +8009,7 @@ function DiscordBindDialog({
7837
8009
  {
7838
8010
  className: "taskon-discord-bind-dialog-btn taskon-discord-bind-dialog-btn--primary",
7839
8011
  onClick: onContinue,
7840
- children: "Complete Campaign"
8012
+ children: t("complete_campaign")
7841
8013
  }
7842
8014
  )
7843
8015
  ] })
@@ -7845,6 +8017,46 @@ function DiscordBindDialog({
7845
8017
  }
7846
8018
  );
7847
8019
  }
8020
+ function QuestLoadingSkeleton() {
8021
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest-loading", "aria-busy": "true", "aria-label": "Loading quest", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-layout taskon-quest-skeleton-layout", children: [
8022
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-content taskon-quest-skeleton-content", children: [
8023
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-skeleton-group", children: [
8024
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-title" }),
8025
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-meta" }),
8026
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-banner" }),
8027
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-description" }),
8028
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-description taskon-quest-skeleton-description--short" })
8029
+ ] }),
8030
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-content-divider taskon-quest-skeleton-content-divider" }),
8031
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-skeleton-group taskon-quest-skeleton-group--tasks", children: [
8032
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-section-title" }),
8033
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-progress" }),
8034
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-task" }),
8035
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-task" }),
8036
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-task" }),
8037
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-complete-button" })
8038
+ ] })
8039
+ ] }),
8040
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-divider taskon-quest-skeleton-divider" }),
8041
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-sidebar taskon-quest-skeleton-sidebar", children: [
8042
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-skeleton-panel", children: [
8043
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-title" }),
8044
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line" }),
8045
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line taskon-quest-skeleton-panel-line--short" })
8046
+ ] }),
8047
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-skeleton-panel", children: [
8048
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-title" }),
8049
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line" }),
8050
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line" }),
8051
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line taskon-quest-skeleton-panel-line--short" })
8052
+ ] }),
8053
+ /* @__PURE__ */ jsxs("div", { className: "taskon-quest-skeleton-panel", children: [
8054
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-title" }),
8055
+ /* @__PURE__ */ jsx("div", { className: "taskon-quest-skeleton-block taskon-quest-skeleton-panel-line" })
8056
+ ] })
8057
+ ] })
8058
+ ] }) });
8059
+ }
7848
8060
  function ChevronRightIcon() {
7849
8061
  return /* @__PURE__ */ jsx(
7850
8062
  "svg",
@@ -7871,11 +8083,13 @@ function ChevronRightIcon() {
7871
8083
  function WinnersRow({
7872
8084
  campaignId,
7873
8085
  winnerRewards,
7874
- pointsName = "Points",
8086
+ pointsName,
7875
8087
  onVisibleChange,
7876
8088
  className
7877
8089
  }) {
8090
+ const { t } = useQuestLocale();
7878
8091
  const { client } = useTaskOnContext();
8092
+ const resolvedPointsName = pointsName || t("points");
7879
8093
  const api = useMemo(() => {
7880
8094
  if (!client) return null;
7881
8095
  return createQuestApi(client);
@@ -7911,9 +8125,9 @@ function WinnersRow({
7911
8125
  type: "button",
7912
8126
  className: `taskon-quest-winners-row ${className || ""}`,
7913
8127
  onClick: () => setIsModalOpen(true),
7914
- "aria-label": "View winners list",
8128
+ "aria-label": t("view_winners_list"),
7915
8129
  children: [
7916
- /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: "Winners" }),
8130
+ /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-label", children: t("winners") }),
7917
8131
  /* @__PURE__ */ jsx("span", { className: "taskon-quest-winners-row-count", children: total.toLocaleString() }),
7918
8132
  /* @__PURE__ */ jsx(ChevronRightIcon, {})
7919
8133
  ]
@@ -7926,7 +8140,7 @@ function WinnersRow({
7926
8140
  onClose: () => setIsModalOpen(false),
7927
8141
  campaignId,
7928
8142
  winnerRewards,
7929
- pointsName
8143
+ pointsName: resolvedPointsName
7930
8144
  }
7931
8145
  )
7932
8146
  ] });
@@ -7980,23 +8194,10 @@ function ArrowUpRightIcon() {
7980
8194
  }
7981
8195
  function formatDateShort(timestamp) {
7982
8196
  const date = new Date(timestamp);
7983
- const months = [
7984
- "Jan",
7985
- "Feb",
7986
- "Mar",
7987
- "Apr",
7988
- "May",
7989
- "Jun",
7990
- "Jul",
7991
- "Aug",
7992
- "Sep",
7993
- "Oct",
7994
- "Nov",
7995
- "Dec"
7996
- ];
7997
- const month = months[date.getMonth()];
7998
- const day = String(date.getDate()).padStart(2, "0");
7999
- return `${month} ${day}`;
8197
+ return new Intl.DateTimeFormat(void 0, {
8198
+ month: "short",
8199
+ day: "2-digit"
8200
+ }).format(date);
8000
8201
  }
8001
8202
  function WinnersStatus({
8002
8203
  campaign,
@@ -8007,6 +8208,7 @@ function WinnersStatus({
8007
8208
  className = ""
8008
8209
  }) {
8009
8210
  var _a, _b, _c;
8211
+ const { t } = useQuestLocale();
8010
8212
  const [hasWinners, setHasWinners] = useState(false);
8011
8213
  const endTime = campaign.end_time;
8012
8214
  const isWaitingReviewPow = useMemo(() => {
@@ -8052,29 +8254,35 @@ function WinnersStatus({
8052
8254
  className: "taskon-winners-alert",
8053
8255
  children: [
8054
8256
  /* @__PURE__ */ jsx(TimerIcon, {}),
8055
- /* @__PURE__ */ jsxs("span", { className: "taskon-winners-alert-text", children: [
8056
- "Waiting for",
8057
- " ",
8058
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name }),
8059
- " ",
8060
- "Reviewed All Tasks"
8061
- ] }),
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
+ ) }),
8062
8267
  /* @__PURE__ */ jsx(ArrowUpRightIcon, {})
8063
8268
  ]
8064
8269
  }
8065
8270
  ) : /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8066
8271
  /* @__PURE__ */ jsx(TimerIcon, {}),
8067
- /* @__PURE__ */ jsxs("span", { className: "taskon-winners-alert-text", children: [
8068
- "Waiting for",
8069
- " ",
8070
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-alert-community", children: campaign.community_name }),
8071
- " ",
8072
- "Reviewed All Tasks"
8073
- ] })
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
+ ) })
8074
8282
  ] })),
8075
8283
  !isWaitingReviewPow && isDrawingWinner && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-alert", children: [
8076
8284
  /* @__PURE__ */ jsx(TimerIcon, {}),
8077
- /* @__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") })
8078
8286
  ] }),
8079
8287
  /* @__PURE__ */ jsxs(
8080
8288
  "div",
@@ -8083,22 +8291,26 @@ function WinnersStatus({
8083
8291
  style: { display: isShowContent ? "block" : "none" },
8084
8292
  children: [
8085
8293
  isWaitingReviewPow && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-pow-info", children: [
8086
- "*This quest includes Proof of Work (POW) tasks, which",
8087
- " ",
8088
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-community", children: campaign.community_name }),
8089
- " ",
8090
- "will review. Winners will be selected",
8091
- " ",
8092
- /* @__PURE__ */ jsx("span", { className: "taskon-winners-pow-info-only", children: "ONLY" }),
8093
- " 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
+ )
8094
8306
  ] }),
8095
8307
  /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card", children: [
8096
8308
  isWaitingReviewPow && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card-row", children: [
8097
- /* @__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") }),
8098
8310
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value", children: reviewDeadlineText })
8099
8311
  ] }),
8100
8312
  isDrawingWinner && /* @__PURE__ */ jsxs("div", { className: "taskon-winners-card-row", children: [
8101
- /* @__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") }),
8102
8314
  /* @__PURE__ */ jsx("span", { className: "taskon-winners-card-value--primary", children: drawWinnersDeadlineText })
8103
8315
  ] }),
8104
8316
  /* @__PURE__ */ jsx(
@@ -8139,34 +8351,40 @@ function mergeQuestConfig(props, cloud) {
8139
8351
  rewardRedirectUrl: props.rewardRedirectUrl ?? (cloud == null ? void 0 : cloud.rewardRedirectUrl) ?? ""
8140
8352
  };
8141
8353
  }
8142
- const QUEST_NFT_CLAIM_MESSAGES = {
8143
- claimDialog: {
8144
- claimNft: "Claim NFT",
8145
- claimingNft: "Claiming NFT...",
8146
- claimConnectingWallet: "Connecting wallet...",
8147
- claimSwitchingNetwork: "Switching network...",
8148
- claimGettingSignature: "Getting signature...",
8149
- claimConfirmInWallet: "Please confirm in your wallet",
8150
- claimTransactionPending: "Transaction pending...",
8151
- claimSuccess: "Claim successful!",
8152
- claimFailed: "Claim failed",
8153
- claimCanceled: "Transaction was rejected by user.",
8154
- viewOnExplorer: "View on Explorer",
8155
- retry: "Retry",
8156
- close: "Close"
8157
- },
8158
- pendingDialog: {
8159
- pendingTransaction: "Pending Transaction",
8160
- claimPendingTitle: "You have already claimed this NFT, please wait for this transaction to be confirmed.",
8161
- claimPendingCheckExplorer: "You can check this transaction on explorer:",
8162
- claimPendingHashLabel: "Transaction hash:",
8163
- claimPendingClaimAgainWarn: '"Claim Again" will send a new transaction it is only recommended when you are sure there is something wrong with the current transaction.',
8164
- claimPendingReceiveAddressNoChange: "This receive address can’t be changed:",
8165
- claimAgain: "Claim Again",
8166
- continueWaiting: "Continue Waiting"
8167
- }
8168
- };
8169
- 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) {
8170
8388
  const now = Date.now();
8171
8389
  const startMs = startTime;
8172
8390
  const endMs = endTime;
@@ -8177,13 +8395,13 @@ function getQuestStatusDisplay(campaignStatus, startTime, endTime, isEnd) {
8177
8395
  let label;
8178
8396
  if (!isStarted) {
8179
8397
  status = "upcoming";
8180
- label = "Upcoming";
8398
+ label = labels.upcoming;
8181
8399
  } else if (isEnded) {
8182
8400
  status = "ended";
8183
- label = "Ended";
8401
+ label = labels.ended;
8184
8402
  } else {
8185
8403
  status = "ongoing";
8186
- label = "Ongoing";
8404
+ label = labels.ongoing;
8187
8405
  }
8188
8406
  return {
8189
8407
  status,
@@ -8203,6 +8421,7 @@ function getHasRanking(winnerRewards) {
8203
8421
  }
8204
8422
  function QuestWidget(props) {
8205
8423
  const { widgetId, themeMode } = props;
8424
+ const { t } = useQuestLocale();
8206
8425
  const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
8207
8426
  const mergedConfig = useMemo(() => {
8208
8427
  return mergeQuestConfig(
@@ -8231,7 +8450,9 @@ function QuestWidget(props) {
8231
8450
  cloudTheme,
8232
8451
  themeMode,
8233
8452
  className: "taskon-quest",
8234
- 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),
8235
8456
  children: /* @__PURE__ */ jsx(
8236
8457
  QuestWidgetInner,
8237
8458
  {
@@ -8254,6 +8475,7 @@ function QuestWidget(props) {
8254
8475
  }
8255
8476
  function QuestWidgetInner(props) {
8256
8477
  var _a, _b, _c, _d, _e;
8478
+ const { t } = useQuestLocale();
8257
8479
  const {
8258
8480
  campaignId,
8259
8481
  channel,
@@ -8281,6 +8503,10 @@ function QuestWidgetInner(props) {
8281
8503
  } = props;
8282
8504
  const { client, chains, isLoggedIn, userInfo, requestLogin, communityInfo } = useTaskOnContext();
8283
8505
  const { toast } = useToast();
8506
+ const questNftClaimMessages = useMemo(
8507
+ () => createQuestNftClaimMessages(t),
8508
+ [t]
8509
+ );
8284
8510
  const chainMap = useMemo(() => {
8285
8511
  if (!chains || chains.length === 0) return {};
8286
8512
  return Object.fromEntries(
@@ -8348,13 +8574,13 @@ function QuestWidgetInner(props) {
8348
8574
  } = useNftClaimFlow({
8349
8575
  campaignId,
8350
8576
  targetType: (campaign == null ? void 0 : campaign.campaign_type) === CampaignType.Event ? "event" : "campaign",
8351
- messages: QUEST_NFT_CLAIM_MESSAGES,
8577
+ messages: questNftClaimMessages,
8352
8578
  onClaimSuccess: async () => {
8353
8579
  refetchUserStatus();
8354
8580
  refetchStatus();
8355
8581
  },
8356
8582
  onClaimError: (error2) => {
8357
- toast.error(error2.message || "Failed to claim NFT");
8583
+ toast.error(error2.message || t("failed_claim_nft"));
8358
8584
  },
8359
8585
  onWalletError: (errorMessage) => {
8360
8586
  toast.error(errorMessage);
@@ -8399,9 +8625,14 @@ function QuestWidgetInner(props) {
8399
8625
  campaign.campaign_status,
8400
8626
  campaign.start_time,
8401
8627
  campaign.end_time,
8402
- campaign.is_end
8628
+ campaign.is_end,
8629
+ {
8630
+ upcoming: t("upcoming"),
8631
+ ended: t("ended"),
8632
+ ongoing: t("ongoing")
8633
+ }
8403
8634
  );
8404
- }, [campaign]);
8635
+ }, [campaign, t]);
8405
8636
  const isTaskDisabled = useMemo(() => {
8406
8637
  if (!statusDisplay) return true;
8407
8638
  return !statusDisplay.isActive;
@@ -8486,7 +8717,7 @@ function QuestWidgetInner(props) {
8486
8717
  setBlindBoxRewardVisible(true);
8487
8718
  } catch (error2) {
8488
8719
  console.error("Claim blind box error:", error2);
8489
- 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");
8490
8721
  toast.error(errorMessage);
8491
8722
  (_a2 = blindBoxDialogRef.current) == null ? void 0 : _a2.resetToUnopened();
8492
8723
  } finally {
@@ -8499,6 +8730,7 @@ function QuestWidgetInner(props) {
8499
8730
  buildBlindBoxRewardValue,
8500
8731
  refetchUserStatus,
8501
8732
  refetchStatus,
8733
+ t,
8502
8734
  toast
8503
8735
  ]);
8504
8736
  useEffect(() => {
@@ -8531,7 +8763,7 @@ function QuestWidgetInner(props) {
8531
8763
  const handleTaskCompleted = (taskId, result) => {
8532
8764
  var _a2;
8533
8765
  const successTaskIds = (result == null ? void 0 : result.success_tasks) ?? [taskId];
8534
- 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);
8535
8767
  const isSwapDex = (task == null ? void 0 : task.template_id) === "SwapDexContractInteractive";
8536
8768
  const isSuccess = successTaskIds.includes(taskId);
8537
8769
  if (isSuccess) {
@@ -8678,10 +8910,7 @@ function QuestWidgetInner(props) {
8678
8910
  return userStatus.campaign_eligible !== UserEligibleStatus.Eligible;
8679
8911
  }, [statusDisplay == null ? void 0 : statusDisplay.isActive, userStatus]);
8680
8912
  if (isLoading && !campaign) {
8681
- return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-loading", children: [
8682
- /* @__PURE__ */ jsx("div", { className: "taskon-quest-loading-spinner" }),
8683
- /* @__PURE__ */ jsx("span", { children: "Loading quest..." })
8684
- ] }) });
8913
+ return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsx(QuestLoadingSkeleton, {}) });
8685
8914
  }
8686
8915
  if (error && !campaign) {
8687
8916
  return /* @__PURE__ */ jsx("div", { className: "taskon-quest", children: /* @__PURE__ */ jsxs("div", { className: "taskon-quest-error", children: [
@@ -8696,13 +8925,13 @@ function QuestWidgetInner(props) {
8696
8925
  refetchUserStatus();
8697
8926
  refetchStatus();
8698
8927
  },
8699
- children: "Retry"
8928
+ children: t("retry")
8700
8929
  }
8701
8930
  )
8702
8931
  ] }) });
8703
8932
  }
8704
8933
  if (!campaign) {
8705
- 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") }) });
8706
8935
  }
8707
8936
  return /* @__PURE__ */ jsxs("div", { className: "taskon-quest", children: [
8708
8937
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-layout", children: [
@@ -8730,7 +8959,7 @@ function QuestWidgetInner(props) {
8730
8959
  ),
8731
8960
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-content-divider" }),
8732
8961
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-tasks", children: [
8733
- /* @__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") }) }),
8734
8963
  mandatoryTasks.length > 0 && optionalTasks.length === 0 && /* @__PURE__ */ jsx(
8735
8964
  CompletedCount,
8736
8965
  {
@@ -8791,7 +9020,7 @@ function QuestWidgetInner(props) {
8791
9020
  /* @__PURE__ */ jsx("div", { className: "taskon-quest-divider" }),
8792
9021
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-sidebar", children: [
8793
9022
  (statusDisplay == null ? void 0 : statusDisplay.isEnded) && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-winners-section", children: [
8794
- /* @__PURE__ */ jsx("h3", { className: "taskon-quest-winners-section-title", children: "Winners" }),
9023
+ /* @__PURE__ */ jsx("h3", { className: "taskon-quest-winners-section-title", children: t("winners") }),
8795
9024
  /* @__PURE__ */ jsx(
8796
9025
  WinnersStatus,
8797
9026
  {
@@ -8804,7 +9033,7 @@ function QuestWidgetInner(props) {
8804
9033
  )
8805
9034
  ] }),
8806
9035
  /* @__PURE__ */ jsxs("div", { className: "taskon-quest-rewards-section", children: [
8807
- /* @__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") }),
8808
9037
  /* @__PURE__ */ jsx(
8809
9038
  QuestRewards,
8810
9039
  {
@@ -8828,7 +9057,7 @@ function QuestWidgetInner(props) {
8828
9057
  )
8829
9058
  ] }),
8830
9059
  hasEligibility && /* @__PURE__ */ jsxs("div", { className: "taskon-quest-eligs-section", children: [
8831
- /* @__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") }) }),
8832
9061
  /* @__PURE__ */ jsx(
8833
9062
  EligibilityInfo,
8834
9063
  {
@@ -8858,7 +9087,7 @@ function QuestWidgetInner(props) {
8858
9087
  {
8859
9088
  open: isBlindBoxDialogVisible,
8860
9089
  onOpenChange: setBlindBoxDialogVisible,
8861
- title: "Open Blind Box",
9090
+ title: t("open_blind_box"),
8862
9091
  showCloseButton: false,
8863
9092
  closeOnOverlayClick: false,
8864
9093
  closeOnEscapeKey: false,
@@ -8878,7 +9107,7 @@ function QuestWidgetInner(props) {
8878
9107
  {
8879
9108
  open: isBlindBoxRewardVisible,
8880
9109
  onOpenChange: setBlindBoxRewardVisible,
8881
- title: "Blind Box Reward",
9110
+ title: t("blind_box_reward"),
8882
9111
  showCloseButton: true,
8883
9112
  contentClassName: "taskon-quest-blindbox-reward-wrapper",
8884
9113
  children: /* @__PURE__ */ jsx(