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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/CommunityTaskList.css +110 -110
  2. package/dist/EligibilityInfo.css +69 -69
  3. package/dist/Quest.css +241 -241
  4. package/dist/chunks/{CommunityTaskList-C9Gv8KOF.js → CommunityTaskList-CrMvOB8w.js} +725 -441
  5. package/dist/chunks/{EligibilityInfo-D-Fuy9GE.js → EligibilityInfo-Beww12QX.js} +1569 -597
  6. package/dist/chunks/{LeaderboardWidget-BV2D2q1N.js → LeaderboardWidget-DwuSpVl0.js} +2 -2
  7. package/dist/chunks/{PageBuilder-DQoU4Mwf.js → PageBuilder-DsX6Tv0N.js} +5 -5
  8. package/dist/chunks/{Quest-B5NyVr3o.js → Quest-CuD2LElS.js} +661 -473
  9. package/dist/chunks/{TaskOnProvider-93UxARFo.js → TaskOnProvider-xUeP2Nro.js} +78 -65
  10. package/dist/chunks/{ThemeProvider-CPI_roeh.js → ThemeProvider-Bt4UZ33y.js} +30 -6
  11. package/dist/chunks/{UserCenterWidget-BRtigY_S.js → UserCenterWidget-CB0hnj-L.js} +67 -30
  12. package/dist/chunks/{UserCenterWidget-cADBSVg7.js → UserCenterWidget-CvU6K4AC.js} +2 -2
  13. package/dist/chunks/communitytask-es-1zawvXEX.js +311 -0
  14. package/dist/chunks/communitytask-ja-CmW6nP-L.js +311 -0
  15. package/dist/chunks/communitytask-ko-BD0hzQSi.js +311 -0
  16. package/dist/chunks/communitytask-ru-DhySaZL8.js +311 -0
  17. package/dist/chunks/createLocaleLoader-BameiEhU.js +65 -0
  18. package/dist/chunks/{dynamic-import-helper-DwXlQC0S.js → dynamic-import-helper-WmIF58Sb.js} +1 -1
  19. package/dist/chunks/quest-es-D-b5xcme.js +948 -0
  20. package/dist/chunks/quest-ja-Dxd2vqBF.js +948 -0
  21. package/dist/chunks/quest-ko-CSmRWgK_.js +948 -0
  22. package/dist/chunks/quest-ru-CkEKv1_F.js +948 -0
  23. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  24. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  25. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  26. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  27. package/dist/community-task.js +1 -1
  28. package/dist/core.d.ts +17 -5
  29. package/dist/core.js +8 -7
  30. package/dist/index.d.ts +56 -5
  31. package/dist/index.js +18 -16
  32. package/dist/leaderboard.js +2 -2
  33. package/dist/page-builder.js +1 -1
  34. package/dist/quest.d.ts +682 -0
  35. package/dist/quest.js +3 -1
  36. package/dist/user-center.d.ts +3 -1
  37. package/dist/user-center.js +5 -5
  38. package/package.json +4 -1
@@ -1,11 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import React__default, { useState, useRef, useCallback, useEffect, useContext, useMemo } from "react";
3
- import { isUnauthorizedError, TaskReviewResult, formatLongNumber, EligibilityType, Operator, MeetConditionStatus, RewardType, formatUtcTime, ErrorCode, SnsType, createCommunityTaskApi, ApiError, TaskCardType, ChainType, getSwapDexTitleExpress, UserEligibleStatus, CampaignStatus, MediaType, createQuestApi, CampaignType, formatTokenAmount, TaskTemplateId, EligibilityTemplateId, RecurrenceType, createCommonApi, normalizeTask, formatSwapTokensForDisplay, formatAddress } from "@taskon/core";
4
- import { p as TaskOnContext, d as useTaskOnContext, s as useTaskOnPortalContainer } from "./ThemeProvider-CPI_roeh.js";
5
- import { D as Dialog, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-DwXlQC0S.js";
3
+ import { isUnauthorizedError, TaskReviewResult, formatLongNumber, EligibilityType, Operator, MeetConditionStatus, RewardType, formatUtcTime, ErrorCode, SnsType, createCommunityTaskApi, TaskCardType, ChainType, getSwapDexTitleExpress, UserEligibleStatus, CampaignStatus, MediaType, createQuestApi, CampaignType, formatTokenAmount, TaskTemplateId, EligibilityTemplateId, RecurrenceType, createCommonApi, normalizeTask, formatSwapTokensForDisplay, formatAddress } from "@taskon/core";
4
+ import { q as TaskOnContext, d as useTaskOnContext, t as useTaskOnPortalContainer } from "./ThemeProvider-Bt4UZ33y.js";
5
+ import { D as Dialog, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-WmIF58Sb.js";
6
+ import { u as useTranslation, c as createLocaleLoader } from "./createLocaleLoader-BameiEhU.js";
6
7
  import { d as useToast } from "./useToast-CaRkylKe.js";
7
- import { u as useBindWallet, T as TitleExpress, a as CardDescExpress, b as useNftClaimFlow, R as RewardModuleDialog, B as BlindBoxDialog, c as TaskItem, E as EligibilityInfo, d as Textarea } from "./EligibilityInfo-D-Fuy9GE.js";
8
- import { g as useBindSocialAccount, B as BindWalletDialog, l as useChainMap, s as TipPopover, k as useIsMobile, I as Input } from "./UserCenterWidget-cADBSVg7.js";
8
+ import { a as useBindWallet, T as TitleExpress, b as CardDescExpress, c as useNftClaimFlow, R as RewardModuleDialog, B as BlindBoxDialog, d as TaskItem, E as EligibilityInfo, e as Textarea } from "./EligibilityInfo-Beww12QX.js";
9
+ import { g as useBindSocialAccount, B as BindWalletDialog, l as useChainMap, s as TipPopover, k as useIsMobile, I as Input } from "./UserCenterWidget-CvU6K4AC.js";
9
10
  import { createPortal } from "react-dom";
10
11
  import '../CommunityTaskList.css';function CardSelector({
11
12
  options,
@@ -39,6 +40,251 @@ import '../CommunityTaskList.css';function CardSelector({
39
40
  );
40
41
  }) });
41
42
  }
43
+ const once_tag = "Once";
44
+ const daily_tag = "Daily";
45
+ const weekly_tag = "Weekly";
46
+ const monthly_tag = "Monthly";
47
+ const unlimited_tag = "Unlimited";
48
+ const verify_claim = "Verify & Claim";
49
+ const claim = "Claim";
50
+ const update = "Update";
51
+ const valid_util_is = "Valid Until:";
52
+ const won = "Won";
53
+ const gift_rewards = "🎁 Rewards";
54
+ const max_claim_num = "Max. Claims";
55
+ const updated_at = "Updated at {val}";
56
+ const oops = "Oops!";
57
+ const verify_failed = "Verification Failed";
58
+ const oops_failed = "Oops, Failed";
59
+ const under_review = "Under Review";
60
+ const failed = "Failed";
61
+ const completed_now = "Task is complete for now.";
62
+ const continue_in = "Continue in";
63
+ const done_today = "Done for today";
64
+ const per_time = "/Time";
65
+ const earned = "Earned";
66
+ const retry_after = "Retry after {val}";
67
+ const task_verify_warning = "This task only verify action during {start} - {end}(UTC)";
68
+ const you_have_completed = "🎉 You have completed";
69
+ const you_not_pass = "Oops! You did not pass this task.";
70
+ const proceed_2_complete_the_task = "Proceed to complete the task";
71
+ const twitter_delay_error = "This is usually due to X(Twitter) delays. \nPlease try again in 30 seconds and make sure you used your linked X account, {name}.";
72
+ const discord_delay_error = "This is usually due to Discord delays. \n Please try again in 30 seconds and make sure you used your linked Discord account, {name}.";
73
+ const telegram_delay_error = "This is usually due to Telegram delays. \n Please try again in 30 seconds and make sure you used your linked Telegram account, {name}.";
74
+ const discord_invites_err = "Your Invites: {invited} , {need} more needed. Please invite more friends to join the Discord Server";
75
+ const close_in = "🎉 Congratulations, close in {val}s";
76
+ const check = "Check";
77
+ const level_above = "Reach level {val} or above";
78
+ const level_below = "is lower than level {val}";
79
+ const discord_role_is_val = "Discord role is {val}";
80
+ const discord_role_is_not_val = "Discord role is not {val}";
81
+ const nft_token_label = "Own at least {amt} {token} on {chain}";
82
+ const complete_task = "Completed {val}";
83
+ const not_complete_task = "Not Completed {val}";
84
+ const taskon_community = "TaskOn Community";
85
+ const copy = "copy";
86
+ const copy_success = "Copy success";
87
+ const copy_failed = "Copy failed";
88
+ const invalid_image_size_10m = "Please upload an image below 10M";
89
+ const upload_failed = "Upload Failed, please try again!";
90
+ const please_enter_url = "Please enter URL";
91
+ const please_enter_text = "Please enter text";
92
+ const invalid_url = "Please enter a valid url address";
93
+ const enter_here = "Enter here";
94
+ const resubmit = "Resubmit";
95
+ const re_submitted_success = "Re-submitted Successfully";
96
+ const submit = "Submit";
97
+ const swap = "Swap";
98
+ const chain_is = "Chain:";
99
+ const swap_from_is = "Swap From:";
100
+ const swap_to_is = "Swap To:";
101
+ const rules = "Rules";
102
+ const instructions = "Instructions";
103
+ const times = "Times";
104
+ const address_is = "Address:";
105
+ const only_left = "Hurry up! Only {val} left";
106
+ const task_up = "Task";
107
+ const no_task = "No Task";
108
+ const all = "All";
109
+ const any = "Any";
110
+ const meet_all_conditions_to_unlock = "Meet all conditions to Unlock";
111
+ const meet_any_condition_to_unlock = "Meet any condition to Unlock";
112
+ const contact_to_check_progress = "Contact {name} to check your progress";
113
+ const loading = "Loading...";
114
+ const error = "Something went wrong";
115
+ const retry = "Retry";
116
+ const loading_tasks = "Loading tasks...";
117
+ const no_tasks_available = "No tasks available";
118
+ const loading_task = "Loading task...";
119
+ const task_details = "Task details";
120
+ const task_details_desc = "View task details and reward information";
121
+ const no_task_data = "No task data";
122
+ const client_not_initialized = "Client not initialized";
123
+ const failed_to_load = "Failed to load";
124
+ const submission_failed = "Submission failed";
125
+ const failed_to_submit_task = "Failed to submit task:";
126
+ const join_required_discord_channel = "Please join the required Discord channel and try again.";
127
+ const verification_failed_twitter = "Oops! Task verification failed. There might be a delay due to Twitter restrictions. Please try again later.";
128
+ const verification_failed_discord = "Oops! Task verification failed. There might be a delay due to Discord restrictions. Please try again later.";
129
+ const verification_failed_telegram = "Oops! Task verification failed. There might be a delay due to Telegram restrictions. Please try again later.";
130
+ const verification_failed_generic = "Task verification failed. Please check if you completed the required action.";
131
+ const upload_image = "Upload image";
132
+ const click_to_upload_image = "Click to upload image";
133
+ const please_upload_image = "Please upload an image";
134
+ const submitting = "Submitting...";
135
+ const task_completed = "Task completed";
136
+ const every = "Every";
137
+ const will_give_you = "will give you";
138
+ const copy_to_clipboard = "Copy to clipboard";
139
+ const copied = "Copied!";
140
+ const community_login_first = "Please login first";
141
+ const community_points = "Points";
142
+ const community_token = "Token";
143
+ const community_dex = "DEX";
144
+ const community_rule_max = "(Max {val} {name})";
145
+ const enMessages = {
146
+ once_tag,
147
+ daily_tag,
148
+ weekly_tag,
149
+ monthly_tag,
150
+ unlimited_tag,
151
+ verify_claim,
152
+ claim,
153
+ update,
154
+ valid_util_is,
155
+ won,
156
+ gift_rewards,
157
+ max_claim_num,
158
+ updated_at,
159
+ oops,
160
+ verify_failed,
161
+ oops_failed,
162
+ under_review,
163
+ failed,
164
+ completed_now,
165
+ continue_in,
166
+ done_today,
167
+ per_time,
168
+ earned,
169
+ retry_after,
170
+ task_verify_warning,
171
+ you_have_completed,
172
+ you_not_pass,
173
+ proceed_2_complete_the_task,
174
+ twitter_delay_error,
175
+ discord_delay_error,
176
+ telegram_delay_error,
177
+ discord_invites_err,
178
+ close_in,
179
+ check,
180
+ level_above,
181
+ level_below,
182
+ discord_role_is_val,
183
+ discord_role_is_not_val,
184
+ nft_token_label,
185
+ complete_task,
186
+ not_complete_task,
187
+ taskon_community,
188
+ copy,
189
+ copy_success,
190
+ copy_failed,
191
+ invalid_image_size_10m,
192
+ upload_failed,
193
+ please_enter_url,
194
+ please_enter_text,
195
+ invalid_url,
196
+ enter_here,
197
+ resubmit,
198
+ re_submitted_success,
199
+ submit,
200
+ swap,
201
+ chain_is,
202
+ swap_from_is,
203
+ swap_to_is,
204
+ rules,
205
+ instructions,
206
+ times,
207
+ address_is,
208
+ only_left,
209
+ task_up,
210
+ no_task,
211
+ all,
212
+ any,
213
+ meet_all_conditions_to_unlock,
214
+ meet_any_condition_to_unlock,
215
+ contact_to_check_progress,
216
+ loading,
217
+ error,
218
+ retry,
219
+ loading_tasks,
220
+ no_tasks_available,
221
+ loading_task,
222
+ task_details,
223
+ task_details_desc,
224
+ no_task_data,
225
+ client_not_initialized,
226
+ failed_to_load,
227
+ submission_failed,
228
+ failed_to_submit_task,
229
+ join_required_discord_channel,
230
+ verification_failed_twitter,
231
+ verification_failed_discord,
232
+ verification_failed_telegram,
233
+ verification_failed_generic,
234
+ upload_image,
235
+ click_to_upload_image,
236
+ please_upload_image,
237
+ submitting,
238
+ task_completed,
239
+ every,
240
+ will_give_you,
241
+ copy_to_clipboard,
242
+ copied,
243
+ community_login_first,
244
+ community_points,
245
+ community_token,
246
+ community_dex,
247
+ community_rule_max
248
+ };
249
+ const loadMessages = createLocaleLoader(
250
+ enMessages,
251
+ {
252
+ ko: () => import("./communitytask-ko-BD0hzQSi.js").then((module) => ({
253
+ default: module.default
254
+ })),
255
+ ja: () => import("./communitytask-ja-CmW6nP-L.js").then((module) => ({
256
+ default: module.default
257
+ })),
258
+ ru: () => import("./communitytask-ru-DhySaZL8.js").then((module) => ({
259
+ default: module.default
260
+ })),
261
+ es: () => import("./communitytask-es-1zawvXEX.js").then((module) => ({
262
+ default: module.default
263
+ }))
264
+ }
265
+ );
266
+ function useCommunityTaskLocale() {
267
+ return useTranslation({
268
+ widgetId: "CommunityTask",
269
+ defaultMessages: enMessages,
270
+ loadMessages
271
+ });
272
+ }
273
+ const RECURRENCE_KEY_MAP = {
274
+ Once: "once_tag",
275
+ Daily: "daily_tag",
276
+ Weekly: "weekly_tag",
277
+ Monthly: "monthly_tag",
278
+ Unlimited: "unlimited_tag"
279
+ };
280
+ function getRecurrenceLabel(t, recurrence) {
281
+ const recurrenceCode = recurrence ?? "Once";
282
+ const key = RECURRENCE_KEY_MAP[recurrenceCode];
283
+ if (!key) {
284
+ return recurrenceCode;
285
+ }
286
+ return t(key);
287
+ }
42
288
  function ClaimButton({
43
289
  verifyClaim = false,
44
290
  recurrence,
@@ -55,6 +301,7 @@ function ClaimButton({
55
301
  chainType,
56
302
  onBindFailed
57
303
  }) {
304
+ const { t } = useCommunityTaskLocale();
58
305
  const [internalLoading, setInternalLoading] = useState(false);
59
306
  const [showWalletDialog, setShowWalletDialog] = useState(false);
60
307
  const needBindCheck = !claimDialog;
@@ -104,11 +351,11 @@ function ClaimButton({
104
351
  }, [bindWithProvider]);
105
352
  const buttonLabel = (() => {
106
353
  if (customLabel) return customLabel;
107
- if (mini) return "Update";
354
+ if (mini) return t("update");
108
355
  if (recurrence === "Unlimited") {
109
- return hasPoints ? "Update" : "Claim";
356
+ return hasPoints ? t("update") : t("claim");
110
357
  }
111
- return verifyClaim ? "Verify & Claim" : "Claim";
358
+ return verifyClaim ? t("verify_claim") : t("claim");
112
359
  })();
113
360
  const isDisabled = disabled || isSubmitting || internalLoading || isWaitingAuth || isBindingWallet;
114
361
  const buttonClass = [
@@ -187,7 +434,7 @@ function ClaimButton({
187
434
  }
188
435
  function formatCountdown$1(valueMillSec) {
189
436
  if (valueMillSec <= 0) {
190
- return "0 min";
437
+ return "0s";
191
438
  }
192
439
  const hours = Math.floor(valueMillSec / 1e3 / 60 / 60);
193
440
  const minutes = Math.floor((valueMillSec / 1e3 / 60 / 60 - hours) * 60);
@@ -195,11 +442,11 @@ function formatCountdown$1(valueMillSec) {
195
442
  (valueMillSec / 1e3 / 60 - hours * 60 - minutes) * 60
196
443
  );
197
444
  if (hours > 0) {
198
- return `${hours} hour${hours > 1 ? "s" : ""}`;
445
+ return `${hours}h`;
199
446
  } else if (minutes > 0) {
200
- return `${minutes} min${minutes > 1 ? "s" : ""}`;
447
+ return `${minutes}m`;
201
448
  } else {
202
- return `${seconds} sec${seconds > 1 ? "s" : ""}`;
449
+ return `${seconds}s`;
203
450
  }
204
451
  }
205
452
  function ClaimRetry({
@@ -208,6 +455,7 @@ function ClaimRetry({
208
455
  onComplete
209
456
  }) {
210
457
  const [timeLeft, setTimeLeft] = useState(leftMillSecond);
458
+ const { t } = useCommunityTaskLocale();
211
459
  const onUpdateRef = useRef(onUpdate);
212
460
  const onCompleteRef = useRef(onComplete);
213
461
  useEffect(() => {
@@ -239,25 +487,16 @@ function ClaimRetry({
239
487
  clearInterval(timer);
240
488
  };
241
489
  }, [leftMillSecond]);
242
- return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-retry", children: [
243
- "Retry after ",
244
- formatCountdown$1(timeLeft)
245
- ] });
490
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-retry", children: t("retry_after", { val: formatCountdown$1(timeLeft) }) });
246
491
  }
247
492
  const SECOND = 1e3;
248
493
  const MINUTE = 60 * SECOND;
249
494
  const HOUR = 60 * MINUTE;
250
- const DAY = 24 * HOUR;
251
495
  function prefix(num) {
252
496
  return num < 10 ? `0${num}` : `${num}`;
253
497
  }
254
498
  function formatDurationLabel(from, to) {
255
499
  const time = Math.abs(from - to);
256
- const totalHours = time / HOUR;
257
- if (totalHours > 24) {
258
- const days = Math.ceil(time / DAY);
259
- return `${days} day${days > 1 ? "s" : ""}`;
260
- }
261
500
  const hours = Math.floor(time / HOUR);
262
501
  const minutes = Math.floor(time % HOUR / MINUTE);
263
502
  const seconds = Math.floor(time % MINUTE / SECOND);
@@ -268,6 +507,7 @@ function DoneCountdown({
268
507
  onComplete
269
508
  }) {
270
509
  const [now, setNow] = useState(Date.now());
510
+ const { t } = useCommunityTaskLocale();
271
511
  const onCompleteRef = useRef(onComplete);
272
512
  useEffect(() => {
273
513
  onCompleteRef.current = onComplete;
@@ -288,9 +528,9 @@ function DoneCountdown({
288
528
  }, [nextTime]);
289
529
  const countdownLabel = now >= nextTime ? "00h : 00m : 00s" : formatDurationLabel(now, nextTime);
290
530
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-done-countdown", children: [
291
- /* @__PURE__ */ jsx("div", { className: "taskon-community-task-done-countdown-text", children: "Task is complete for now." }),
531
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-task-done-countdown-text", children: t("completed_now") }),
292
532
  /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-done-countdown-timer", children: [
293
- /* @__PURE__ */ jsx("span", { children: "Continue in" }),
533
+ /* @__PURE__ */ jsx("span", { children: t("continue_in") }),
294
534
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-done-countdown-time", children: countdownLabel })
295
535
  ] })
296
536
  ] });
@@ -343,26 +583,27 @@ function WarningIcon() {
343
583
  function ValidationTimeTip({
344
584
  timeFrame
345
585
  }) {
586
+ const { t } = useCommunityTaskLocale();
346
587
  const startDate = formatDate$1(normalizeTimestamp(timeFrame.start_time));
347
588
  const endDate = formatDate$1(normalizeTimestamp(timeFrame.end_time));
348
589
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-validation-tip", children: [
349
590
  /* @__PURE__ */ jsx(WarningIcon, {}),
350
- /* @__PURE__ */ jsxs("p", { className: "taskon-community-validation-tip-text", children: [
351
- "This task only verify action during ",
352
- startDate,
353
- " - ",
354
- endDate,
355
- "(UTC)"
356
- ] })
591
+ /* @__PURE__ */ jsx("p", { className: "taskon-community-validation-tip-text", children: t("task_verify_warning", {
592
+ start: startDate,
593
+ end: endDate
594
+ }) })
357
595
  ] });
358
596
  }
359
597
  function CheckProgressTip({
360
598
  communityName,
361
599
  contactLink
362
600
  }) {
601
+ const { t } = useCommunityTaskLocale();
363
602
  if (!communityName) {
364
603
  return null;
365
604
  }
605
+ const textTemplate = t("contact_to_check_progress", { name: "{name}" });
606
+ const [prefixText = "", suffixText = ""] = textTemplate.split("{name}");
366
607
  const handleLinkClick = (e) => {
367
608
  e.stopPropagation();
368
609
  if (contactLink) {
@@ -370,7 +611,7 @@ function CheckProgressTip({
370
611
  }
371
612
  };
372
613
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-progress-tip", children: [
373
- /* @__PURE__ */ jsx("span", { children: "Contact " }),
614
+ /* @__PURE__ */ jsx("span", { children: prefixText }),
374
615
  contactLink ? /* @__PURE__ */ jsx(
375
616
  "span",
376
617
  {
@@ -379,7 +620,7 @@ function CheckProgressTip({
379
620
  children: communityName
380
621
  }
381
622
  ) : /* @__PURE__ */ jsx("span", { className: "taskon-community-task-progress-tip-name", children: communityName }),
382
- /* @__PURE__ */ jsx("span", { children: " to check your progress" })
623
+ /* @__PURE__ */ jsx("span", { children: suffixText })
383
624
  ] });
384
625
  }
385
626
  function ProgressUi({
@@ -472,6 +713,7 @@ function BlingSvg({ className }) {
472
713
  function BaseTask(props) {
473
714
  const authFromContext = useOptionalAuth();
474
715
  const { showToast } = useToast();
716
+ const { t } = useCommunityTaskLocale();
475
717
  const {
476
718
  title,
477
719
  isWon,
@@ -534,6 +776,12 @@ function BaseTask(props) {
534
776
  if (!availableUnit || !totalUnit) return 0;
535
777
  return Number((availableUnit / totalUnit * 100).toFixed(2));
536
778
  }, [reward]);
779
+ const recurrenceBadgeLabel = useMemo(() => {
780
+ if (!recurrenceLabel) {
781
+ return void 0;
782
+ }
783
+ return getRecurrenceLabel(t, recurrenceLabel);
784
+ }, [recurrenceLabel, t]);
537
785
  const handleActionClick = (e) => {
538
786
  e.stopPropagation();
539
787
  if (actionAutoDialog && onClick) {
@@ -557,8 +805,8 @@ function BaseTask(props) {
557
805
  return { successful: false };
558
806
  }, [onClaim, isSubmitting]);
559
807
  const handleBindFailed = useCallback(
560
- (error) => {
561
- showToast(error, "error");
808
+ (error2) => {
809
+ showToast(error2, "error");
562
810
  },
563
811
  [showToast]
564
812
  );
@@ -581,7 +829,7 @@ function BaseTask(props) {
581
829
  ] }) });
582
830
  }
583
831
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-time", children: [
584
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-label", children: "Valid Until:" }),
832
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-label", children: t("valid_util_is") }),
585
833
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-value", children: validTime.endTime })
586
834
  ] });
587
835
  };
@@ -589,7 +837,7 @@ function BaseTask(props) {
589
837
  if (!reward || reward.type === "none") {
590
838
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won", children: [
591
839
  /* @__PURE__ */ jsx(IconCheckedTask, { className: "taskon-community-task-won-checked" }),
592
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-text", children: "Completed" })
840
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-text", children: t("task_completed") })
593
841
  ] });
594
842
  }
595
843
  if (reward.type === "points") {
@@ -598,12 +846,13 @@ function BaseTask(props) {
598
846
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-single", children: reward.amount }),
599
847
  /* @__PURE__ */ jsxs("span", { className: "taskon-community-task-won-label", children: [
600
848
  reward.name,
601
- "/Time"
849
+ t("per_time")
602
850
  ] }),
603
851
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-total", children: reward.totalAmount }),
604
852
  /* @__PURE__ */ jsxs("span", { className: "taskon-community-task-won-earned", children: [
605
853
  reward.name,
606
- " earned"
854
+ " ",
855
+ t("earned")
607
856
  ] })
608
857
  ] });
609
858
  }
@@ -622,7 +871,7 @@ function BaseTask(props) {
622
871
  )
623
872
  ] }),
624
873
  /* @__PURE__ */ jsx(BlingSvg, { className: "taskon-community-task-won-bling" }),
625
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: "Won" })
874
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: t("won") })
626
875
  ] });
627
876
  }
628
877
  if (reward.type === "token" && reward.token) {
@@ -630,7 +879,7 @@ function BaseTask(props) {
630
879
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won taskon-community-task-won--periodic", children: [
631
880
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-single", children: reward.token.amount }),
632
881
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-total", children: reward.token.name }),
633
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-earned", children: "earned" })
882
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-earned", children: t("earned") })
634
883
  ] });
635
884
  }
636
885
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won", children: [
@@ -638,7 +887,7 @@ function BaseTask(props) {
638
887
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-amount", children: reward.token.amount }),
639
888
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-name", children: reward.token.name }),
640
889
  /* @__PURE__ */ jsx(BlingSvg, { className: "taskon-community-task-won-bling" }),
641
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: "Won" })
890
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: t("won") })
642
891
  ] });
643
892
  }
644
893
  return null;
@@ -646,7 +895,7 @@ function BaseTask(props) {
646
895
  const renderRewardInfo = () => {
647
896
  if (!reward || reward.type === "none") return null;
648
897
  if (reward.type === "points") {
649
- const nameSuffix = isPeriodic ? "/Time" : "";
898
+ const nameSuffix = isPeriodic ? t("per_time") : "";
650
899
  let displayAmount = reward.amount ?? 0;
651
900
  if (recurrence === "Unlimited") {
652
901
  const totalAmount = reward.totalAmount ?? 0;
@@ -694,10 +943,10 @@ function BaseTask(props) {
694
943
  const renderClaimArea = () => {
695
944
  if (noClaim) return null;
696
945
  if (reviewResult === TaskReviewResult.Failed) {
697
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--failed", children: "Oops! Failed" });
946
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--failed", children: t("oops_failed") });
698
947
  }
699
948
  if (reviewResult === TaskReviewResult.UnReviewed) {
700
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--review", children: "Under Review" });
949
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--review", children: t("under_review") });
701
950
  }
702
951
  if (coolDown > 0) {
703
952
  return /* @__PURE__ */ jsx(ClaimRetry, { leftMillSecond: coolDown, onComplete: onCoolDownComplete });
@@ -742,7 +991,7 @@ function BaseTask(props) {
742
991
  className: `taskon-community-task ${isCompleted ? "taskon-community-task--won" : ""} ${disabled ? "taskon-community-task--disabled" : ""}`,
743
992
  onClick: handleCardClick,
744
993
  children: [
745
- recurrenceLabel && !noRecurrence && /* @__PURE__ */ jsx("div", { className: "taskon-community-task-badge", children: recurrenceLabel }),
994
+ recurrenceBadgeLabel && !noRecurrence && /* @__PURE__ */ jsx("div", { className: "taskon-community-task-badge", children: recurrenceBadgeLabel }),
746
995
  disabled && /* @__PURE__ */ jsx(
747
996
  "div",
748
997
  {
@@ -862,7 +1111,8 @@ function CardField({
862
1111
  link,
863
1112
  copy_text
864
1113
  }) {
865
- const [copied, setCopied] = useState(false);
1114
+ const [copied2, setCopied] = useState(false);
1115
+ const { t } = useCommunityTaskLocale();
866
1116
  const handleCopy = async (e) => {
867
1117
  e.preventDefault();
868
1118
  e.stopPropagation();
@@ -892,9 +1142,9 @@ function CardField({
892
1142
  "button",
893
1143
  {
894
1144
  type: "button",
895
- className: `taskon-community-task-field-copy ${copied ? "taskon-community-task-field-copy--copied" : ""}`,
1145
+ className: `taskon-community-task-field-copy ${copied2 ? "taskon-community-task-field-copy--copied" : ""}`,
896
1146
  onClick: handleCopy,
897
- title: copied ? "Copied!" : "Copy to clipboard",
1147
+ title: copied2 ? t("copied") : t("copy_to_clipboard"),
898
1148
  children: /* @__PURE__ */ jsx(CopyIcon, { className: "taskon-community-task-field-copy-icon" })
899
1149
  }
900
1150
  )
@@ -1058,6 +1308,7 @@ function ConditionItem({
1058
1308
  condition,
1059
1309
  onTaskClick
1060
1310
  }) {
1311
+ const { t } = useCommunityTaskLocale();
1061
1312
  const payload = useMemo(() => {
1062
1313
  return parseConditionParams(condition.condition_params);
1063
1314
  }, [condition.condition_params]);
@@ -1066,34 +1317,35 @@ function ConditionItem({
1066
1317
  if (type === EligibilityType.CommunityUserLevel) {
1067
1318
  const params = payload;
1068
1319
  if (params.operator === Operator.Gte) {
1069
- return `Reach level ${params.level} or above`;
1320
+ return t("level_above", { val: params.level });
1070
1321
  }
1071
- return `is lower than level ${params.level}`;
1322
+ return t("level_below", { val: params.level });
1072
1323
  }
1073
1324
  if (type === EligibilityType.DiscordRole) {
1074
1325
  const params = payload;
1075
1326
  if (params.operator === Operator.Is) {
1076
- return `Discord role is ${params.role}`;
1327
+ return t("discord_role_is_val", { val: params.role });
1077
1328
  }
1078
- return `Discord role is not ${params.role}`;
1329
+ return t("discord_role_is_not_val", { val: params.role });
1079
1330
  }
1080
1331
  if (type === EligibilityType.TokenBalance) {
1081
1332
  const params = payload;
1082
- return `Own at least ${params.amount} ${params.token_name} on ${params.chain_label}`;
1333
+ return t("nft_token_label", {
1334
+ amt: params.amount,
1335
+ token: params.token_name,
1336
+ chain: params.chain_label
1337
+ });
1083
1338
  }
1084
1339
  if (type === EligibilityType.NftHolder) {
1085
1340
  const params = payload;
1086
- return `Own at least ${params.amount} ${params.nft_name} on ${params.chain_label}`;
1087
- }
1088
- if (type === EligibilityType.CommunityPreTask) {
1089
- const params = payload;
1090
- if (params.operator === Operator.Is) {
1091
- return { key: "complete_task", val: params.task_name };
1092
- }
1093
- return { key: "not_complete_task", val: params.task_name };
1341
+ return t("nft_token_label", {
1342
+ amt: params.amount,
1343
+ token: params.nft_name,
1344
+ chain: params.chain_label
1345
+ });
1094
1346
  }
1095
1347
  return "";
1096
- }, [condition.condition_type, payload]);
1348
+ }, [condition.condition_type, payload, t]);
1097
1349
  const renderStatusIcon = () => {
1098
1350
  switch (condition.status) {
1099
1351
  case MeetConditionStatus.passed:
@@ -1108,7 +1360,8 @@ function ConditionItem({
1108
1360
  if (condition.condition_type === EligibilityType.CommunityPreTask) {
1109
1361
  const params = payload;
1110
1362
  const isCompleted = params.operator === Operator.Is;
1111
- const prefix2 = isCompleted ? "Completed " : "Not Completed ";
1363
+ const template = isCompleted ? t("complete_task", { val: "{val}" }) : t("not_complete_task", { val: "{val}" });
1364
+ const [prefix2 = "", suffix = ""] = template.split("{val}");
1112
1365
  const canClick = onTaskClick && params.task_id;
1113
1366
  return /* @__PURE__ */ jsxs("span", { className: "taskon-eligibility-mask-item-text", children: [
1114
1367
  prefix2,
@@ -1130,15 +1383,13 @@ function ConditionItem({
1130
1383
  },
1131
1384
  children: params.task_name
1132
1385
  }
1133
- ) : /* @__PURE__ */ jsx("span", { children: params.task_name })
1386
+ ) : /* @__PURE__ */ jsx("span", { children: params.task_name }),
1387
+ suffix
1134
1388
  ] });
1135
1389
  }
1136
- if (typeof typeLabel === "string") {
1137
- return /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-item-text", children: typeLabel });
1138
- }
1139
- return null;
1390
+ return /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-item-text", children: typeLabel });
1140
1391
  };
1141
- if (!typeLabel) {
1392
+ if (!typeLabel && condition.condition_type !== EligibilityType.CommunityPreTask) {
1142
1393
  return /* @__PURE__ */ jsx(Fragment, {});
1143
1394
  }
1144
1395
  return /* @__PURE__ */ jsxs("div", { className: "taskon-eligibility-mask-item", children: [
@@ -1152,7 +1403,8 @@ function UserEligibilityMask({
1152
1403
  onCheck,
1153
1404
  onTaskClick
1154
1405
  }) {
1155
- const [loading, setLoading] = useState(false);
1406
+ const { t } = useCommunityTaskLocale();
1407
+ const [loading2, setLoading] = useState(false);
1156
1408
  const rewardInfo = useMemo(() => {
1157
1409
  if (!task.reward || task.reward.length === 0) return null;
1158
1410
  const pointsReward = task.reward.find(
@@ -1176,7 +1428,7 @@ function UserEligibilityMask({
1176
1428
  return null;
1177
1429
  }, [task.reward]);
1178
1430
  const handleCheck = useCallback(async () => {
1179
- if (loading || !onCheck) return;
1431
+ if (loading2 || !onCheck) return;
1180
1432
  const result = onCheck();
1181
1433
  if (result instanceof Promise) {
1182
1434
  setLoading(true);
@@ -1186,7 +1438,7 @@ function UserEligibilityMask({
1186
1438
  setLoading(false);
1187
1439
  }
1188
1440
  }
1189
- }, [loading, onCheck]);
1441
+ }, [loading2, onCheck]);
1190
1442
  const renderRewardInfo = () => {
1191
1443
  if (!rewardInfo) return null;
1192
1444
  if (rewardInfo.type === "points") {
@@ -1209,15 +1461,7 @@ function UserEligibilityMask({
1209
1461
  };
1210
1462
  const renderConditionTitle = () => {
1211
1463
  const isAnd = task.eligiblity_expression === "and";
1212
- return /* @__PURE__ */ jsxs("span", { className: "taskon-eligibility-mask-cond-title", children: [
1213
- "Meet",
1214
- " ",
1215
- /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-cond-label", children: isAnd ? "All" : "Any" }),
1216
- " ",
1217
- "condition",
1218
- isAnd ? "s" : "",
1219
- " to Unlock"
1220
- ] });
1464
+ return /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-cond-title", children: isAnd ? t("meet_all_conditions_to_unlock") : t("meet_any_condition_to_unlock") });
1221
1465
  };
1222
1466
  return /* @__PURE__ */ jsxs("div", { className: "taskon-eligibility-mask", children: [
1223
1467
  renderRewardInfo(),
@@ -1228,17 +1472,17 @@ function UserEligibilityMask({
1228
1472
  "button",
1229
1473
  {
1230
1474
  type: "button",
1231
- className: `taskon-eligibility-mask-check-btn${loading ? " taskon-eligibility-mask-check-btn--loading" : ""}`,
1475
+ className: `taskon-eligibility-mask-check-btn${loading2 ? " taskon-eligibility-mask-check-btn--loading" : ""}`,
1232
1476
  onClick: handleCheck,
1233
- disabled: loading,
1477
+ disabled: loading2,
1234
1478
  children: [
1235
1479
  /* @__PURE__ */ jsx(
1236
1480
  ReloadIcon,
1237
1481
  {
1238
- className: `taskon-eligibility-mask-reload-icon${loading ? " taskon-eligibility-mask-reload-icon--spinning" : ""}`
1482
+ className: `taskon-eligibility-mask-reload-icon${loading2 ? " taskon-eligibility-mask-reload-icon--spinning" : ""}`
1239
1483
  }
1240
1484
  ),
1241
- "Check"
1485
+ t("check")
1242
1486
  ]
1243
1487
  }
1244
1488
  )
@@ -1275,14 +1519,7 @@ function useTaskState(task, userStatus) {
1275
1519
  }
1276
1520
  const isCompleted = (userStatus == null ? void 0 : userStatus.current_completed) || false;
1277
1521
  const isPeriodic = task.recurrence !== "Once" && task.template.template_id !== "DailyConnect" && task.recurrence !== "Unlimited";
1278
- const recurrenceLabelMap = {
1279
- Once: "Once",
1280
- Daily: "Daily",
1281
- Weekly: "Weekly",
1282
- Monthly: "Monthly",
1283
- Unlimited: "Unlimited"
1284
- };
1285
- const recurrenceLabel = recurrenceLabelMap[task.recurrence] || task.recurrence;
1522
+ const recurrenceLabel = task.recurrence;
1286
1523
  let showUnlimitedClaim = true;
1287
1524
  if (task.recurrence === "Unlimited") {
1288
1525
  const totalPointAmount = ((_a = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a.amount) ?? 0;
@@ -1371,22 +1608,25 @@ const isBlankMessage = (message) => {
1371
1608
  const isDiscordNotJoinedError = (errorCode) => {
1372
1609
  return errorCode === ErrorCode.DISCORD_USRE_NOT_IN_GROUP || errorCode === DISCORD_USER_NOT_IN_CHANNEL_CODE;
1373
1610
  };
1374
- const resolveCommunityTaskSubmitErrorMessage = (error, errorCode) => {
1375
- const errorMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "";
1611
+ const resolveCommunityTaskSubmitErrorMessage = (error2, options) => {
1612
+ const errorCode = options == null ? void 0 : options.errorCode;
1613
+ const t = options == null ? void 0 : options.t;
1614
+ const errorMessage = error2 instanceof Error ? error2.message : typeof error2 === "string" ? error2 : "";
1376
1615
  if (!isBlankMessage(errorMessage)) {
1377
1616
  return errorMessage;
1378
1617
  }
1379
1618
  if (isDiscordNotJoinedError(errorCode)) {
1380
- return DISCORD_JOIN_REQUIRED_FALLBACK_MESSAGE;
1619
+ return t ? t("join_required_discord_channel") : DISCORD_JOIN_REQUIRED_FALLBACK_MESSAGE;
1381
1620
  }
1382
- return DEFAULT_SUBMIT_TASK_ERROR_MESSAGE;
1621
+ return t ? t("submission_failed") : DEFAULT_SUBMIT_TASK_ERROR_MESSAGE;
1383
1622
  };
1384
1623
  function useSubmitTask(taskId, onSuccess, platform, options) {
1624
+ const { t } = useCommunityTaskLocale();
1385
1625
  const { refreshOnFail = false } = options ?? {};
1386
1626
  const { client, userToken, userInfo } = useTaskOnContext();
1387
1627
  const { toast } = useToast();
1388
1628
  const [isSubmitting, setIsSubmitting] = useState(false);
1389
- const [error, setError] = useState(null);
1629
+ const [error2, setError] = useState(null);
1390
1630
  const getSnsUserName = useCallback((platformName) => {
1391
1631
  if (!(userInfo == null ? void 0 : userInfo.sns)) return "";
1392
1632
  const snsTypeMap = {
@@ -1407,13 +1647,13 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1407
1647
  }
1408
1648
  };
1409
1649
  if (!userToken) {
1410
- const errorMsg = "Please login first";
1650
+ const errorMsg = t("community_login_first");
1411
1651
  setError(errorMsg);
1412
1652
  toast.error(errorMsg);
1413
1653
  return { successful: false, error: errorMsg };
1414
1654
  }
1415
1655
  if (!client) {
1416
- const errorMsg = "Client not initialized";
1656
+ const errorMsg = t("client_not_initialized");
1417
1657
  setError(errorMsg);
1418
1658
  toast.error(errorMsg);
1419
1659
  return { successful: false, error: errorMsg };
@@ -1438,23 +1678,27 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1438
1678
  } else {
1439
1679
  if (platform === "Twitter") {
1440
1680
  const name = getSnsUserName("Twitter");
1441
- toast.error(`Oops! Verification Failed! This is usually due to X(Twitter) delays. Please try again in 30 seconds and make sure you used your linked X account, ${name}.`, 1e4);
1681
+ toast.error(t("twitter_delay_error", { name }), 1e4);
1442
1682
  } else if (platform === "Discord") {
1443
1683
  const name = getSnsUserName("Discord");
1444
- toast.error(`Oops! Verification Failed! This is usually due to Discord delays. Please try again in 30 seconds and make sure you used your linked Discord account, ${name}.`, 1e4);
1684
+ toast.error(t("discord_delay_error", { name }), 1e4);
1445
1685
  } else if (platform === "Telegram") {
1446
1686
  const name = getSnsUserName("Telegram");
1447
- toast.error(`Oops! Verification Failed! This is usually due to Telegram delays. Please try again in 30 seconds and make sure you used your linked Telegram account, ${name}.`, 1e4);
1687
+ toast.error(t("telegram_delay_error", { name }), 1e4);
1448
1688
  } else {
1449
- toast.error("Oops! You did not pass this task.");
1689
+ toast.error(t("you_not_pass"));
1450
1690
  }
1451
1691
  refreshOnFailure();
1452
1692
  return { successful: false };
1453
1693
  }
1454
1694
  } catch (err) {
1455
- const errorCode = err instanceof ApiError ? err.code : void 0;
1456
- const errorData = err instanceof ApiError ? err.data : void 0;
1457
- const errorMsg = resolveCommunityTaskSubmitErrorMessage(err, errorCode);
1695
+ const apiError = err;
1696
+ const errorCode = apiError == null ? void 0 : apiError.code;
1697
+ const errorData = apiError == null ? void 0 : apiError.data;
1698
+ const errorMsg = resolveCommunityTaskSubmitErrorMessage(err, {
1699
+ errorCode,
1700
+ t
1701
+ });
1458
1702
  setError(errorMsg);
1459
1703
  console.error("Submit task failed:", err);
1460
1704
  if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
@@ -1467,7 +1711,12 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1467
1711
  }
1468
1712
  if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
1469
1713
  const { invited = 0, min_required = 0 } = errorData;
1470
- toast.error(`You have invited ${invited} users, but need ${min_required - invited} more to complete this task.`);
1714
+ toast.error(
1715
+ t("discord_invites_err", {
1716
+ invited,
1717
+ need: Math.max(min_required - invited, 0)
1718
+ })
1719
+ );
1471
1720
  refreshOnFailure();
1472
1721
  return {
1473
1722
  successful: false,
@@ -1486,7 +1735,7 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1486
1735
  setIsSubmitting(false);
1487
1736
  }
1488
1737
  },
1489
- [taskId, client, userToken, onSuccess, platform, toast, getSnsUserName, refreshOnFail]
1738
+ [taskId, client, userToken, onSuccess, platform, toast, getSnsUserName, refreshOnFail, t]
1490
1739
  );
1491
1740
  return {
1492
1741
  /** 提交任务函数 */
@@ -1494,15 +1743,16 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1494
1743
  /** 是否正在提交 */
1495
1744
  isSubmitting,
1496
1745
  /** 错误信息 */
1497
- error
1746
+ error: error2
1498
1747
  };
1499
1748
  }
1500
1749
  function useTaskDetail(options) {
1501
1750
  const { taskId } = options;
1751
+ const { t } = useCommunityTaskLocale();
1502
1752
  const { client } = useTaskOnContext();
1503
1753
  const [data, setData] = useState(null);
1504
1754
  const [isLoading, setIsLoading] = useState(false);
1505
- const [error, setError] = useState(null);
1755
+ const [error2, setError] = useState(null);
1506
1756
  const fetchDetail = useCallback(async () => {
1507
1757
  if (!taskId || !client) {
1508
1758
  setData(null);
@@ -1518,19 +1768,19 @@ function useTaskDetail(options) {
1518
1768
  });
1519
1769
  setData(detail);
1520
1770
  } catch (err) {
1521
- setError(err instanceof Error ? err.message : "Failed to load task");
1771
+ setError(err instanceof Error ? err.message : t("failed_to_load"));
1522
1772
  setData(null);
1523
1773
  } finally {
1524
1774
  setIsLoading(false);
1525
1775
  }
1526
- }, [taskId, client]);
1776
+ }, [taskId, client, t]);
1527
1777
  useEffect(() => {
1528
1778
  fetchDetail();
1529
1779
  }, [fetchDetail]);
1530
1780
  return {
1531
1781
  data,
1532
1782
  isLoading,
1533
- error,
1783
+ error: error2,
1534
1784
  refetch: fetchDetail
1535
1785
  };
1536
1786
  }
@@ -1763,6 +2013,7 @@ function PowTask({
1763
2013
  onDoneCountdownComplete
1764
2014
  }) {
1765
2015
  var _a;
2016
+ const { t } = useCommunityTaskLocale();
1766
2017
  const params = useMemo(() => {
1767
2018
  try {
1768
2019
  return JSON.parse(task.template.params);
@@ -1786,9 +2037,9 @@ function PowTask({
1786
2037
  return (userStatus == null ? void 0 : userStatus.current_completed) ?? false;
1787
2038
  }, [userStatus == null ? void 0 : userStatus.current_completed]);
1788
2039
  const actionLabel = useMemo(() => {
1789
- if (isUnderReview || isFailedButCanRetry) return "Re-Submit";
1790
- return "Submit";
1791
- }, [isUnderReview, isFailedButCanRetry]);
2040
+ if (isUnderReview || isFailedButCanRetry) return t("resubmit");
2041
+ return t("submit");
2042
+ }, [isUnderReview, isFailedButCanRetry, t]);
1792
2043
  const alwaysShowAction = useMemo(() => {
1793
2044
  return isUnderReview || isFailedButCanRetry;
1794
2045
  }, [isUnderReview, isFailedButCanRetry]);
@@ -1812,7 +2063,7 @@ function PowTask({
1812
2063
  return {
1813
2064
  type: "points",
1814
2065
  amount: rewardParams.amount || 0,
1815
- name: rewardParams.points_name || "Points",
2066
+ name: rewardParams.points_name || t("community_points"),
1816
2067
  icon: rewardParams.points_icon
1817
2068
  };
1818
2069
  }
@@ -1882,6 +2133,7 @@ function ContractInteractiveTask({
1882
2133
  onDoneCountdownComplete
1883
2134
  }) {
1884
2135
  var _a, _b;
2136
+ const { t } = useCommunityTaskLocale();
1885
2137
  const [localCoolDown, setLocalCoolDown] = useState(
1886
2138
  () => (userStatus == null ? void 0 : userStatus.waiting_cool_down) ?? 0
1887
2139
  );
@@ -1968,7 +2220,7 @@ function ContractInteractiveTask({
1968
2220
  recurrenceLabel: task.recurrence,
1969
2221
  taskId: task.id,
1970
2222
  // 固定按钮文案,复刻原版 t('proceed_2_complete_the_task')
1971
- actionLabel: "Proceed to complete the task",
2223
+ actionLabel: t("proceed_2_complete_the_task"),
1972
2224
  // 使用 task_url 作为按钮链接
1973
2225
  actionLink: params.task_url,
1974
2226
  // 需要验证后才能 Claim
@@ -1989,7 +2241,7 @@ function ContractInteractiveTask({
1989
2241
  return {
1990
2242
  type: "points",
1991
2243
  amount: rewardParams.amount || 0,
1992
- name: rewardParams.points_name || "Points",
2244
+ name: rewardParams.points_name || t("community_points"),
1993
2245
  icon: rewardParams.points_icon,
1994
2246
  totalAmount: (_a2 = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a2.amount
1995
2247
  };
@@ -2059,6 +2311,7 @@ function SwapDexTask({
2059
2311
  onDoneCountdownComplete
2060
2312
  }) {
2061
2313
  var _a, _b;
2314
+ const { t } = useCommunityTaskLocale();
2062
2315
  const [localCoolDown, setLocalCoolDown] = useState(
2063
2316
  () => (userStatus == null ? void 0 : userStatus.waiting_cool_down) ?? 0
2064
2317
  );
@@ -2097,13 +2350,13 @@ function SwapDexTask({
2097
2350
  tokenInList: params.token_in_list,
2098
2351
  chainLabel,
2099
2352
  // 优先使用 task.project_name,其次使用 community name
2100
- dexName: task.project_name || (contextCommunityInfo == null ? void 0 : contextCommunityInfo.name) || "DEX",
2353
+ dexName: task.project_name || (contextCommunityInfo == null ? void 0 : contextCommunityInfo.name) || t("community_dex"),
2101
2354
  dexLink: params.task_url,
2102
2355
  isFixedReward: params.is_fixed_reward_type || false,
2103
2356
  minTradingVolume: params.min_trading_volume,
2104
2357
  minTradesTimes: params.min_trades_times
2105
2358
  });
2106
- }, [params, chainLabel, task.project_name, contextCommunityInfo == null ? void 0 : contextCommunityInfo.name]);
2359
+ }, [params, chainLabel, task.project_name, contextCommunityInfo == null ? void 0 : contextCommunityInfo.name, t]);
2107
2360
  const titleNode = useMemo(() => {
2108
2361
  return /* @__PURE__ */ jsx(TitleExpress, { express: titleExpress });
2109
2362
  }, [titleExpress]);
@@ -2178,7 +2431,7 @@ function SwapDexTask({
2178
2431
  validTime: validTimeProp,
2179
2432
  validationTimeFrame,
2180
2433
  chainType,
2181
- actionLabel: "Swap",
2434
+ actionLabel: t("swap"),
2182
2435
  actionLink: params.task_url,
2183
2436
  verifyClaim: true,
2184
2437
  currentCompleted: userStatus == null ? void 0 : userStatus.current_completed,
@@ -2647,7 +2900,7 @@ function useTaskChainDetail(options) {
2647
2900
  const [userStatus, setUserStatus] = useState(null);
2648
2901
  const [campaignStatusInfo, setCampaignStatusInfo] = useState(null);
2649
2902
  const [isLoading, setIsLoading] = useState(false);
2650
- const [error, setError] = useState(null);
2903
+ const [error2, setError] = useState(null);
2651
2904
  const api = useMemo(() => {
2652
2905
  if (!client) return null;
2653
2906
  return createQuestApi(client);
@@ -2738,7 +2991,7 @@ function useTaskChainDetail(options) {
2738
2991
  userStatus,
2739
2992
  campaignStatusInfo,
2740
2993
  isLoading,
2741
- error,
2994
+ error: error2,
2742
2995
  refetchCampaign: fetchCampaign,
2743
2996
  refetchUserStatus: fetchUserStatus,
2744
2997
  updateTaskStatus
@@ -3167,8 +3420,8 @@ function TaskChainClaimedRewards({
3167
3420
  onClaimSuccess: async () => {
3168
3421
  await (onClaimedNft == null ? void 0 : onClaimedNft());
3169
3422
  },
3170
- onClaimError: (error) => {
3171
- toast.error(error.message || "Failed to claim NFT");
3423
+ onClaimError: (error2) => {
3424
+ toast.error(error2.message || "Failed to claim NFT");
3172
3425
  },
3173
3426
  onWalletError: (errorMessage) => {
3174
3427
  toast.error(errorMessage);
@@ -3209,8 +3462,8 @@ function TaskChainClaimedRewards({
3209
3462
  }
3210
3463
  try {
3211
3464
  await claimNftReward(reward);
3212
- } catch (error) {
3213
- console.error("TaskChain NFT claim failed:", error);
3465
+ } catch (error2) {
3466
+ console.error("TaskChain NFT claim failed:", error2);
3214
3467
  }
3215
3468
  },
3216
3469
  [isSupportedNftRewardType, claimNftReward]
@@ -3590,8 +3843,8 @@ function TaskChainRewardStep({
3590
3843
  });
3591
3844
  await refetchUserStatus();
3592
3845
  await switchToClaimedView();
3593
- } catch (error) {
3594
- console.error("Failed to claim reward:", error);
3846
+ } catch (error2) {
3847
+ console.error("Failed to claim reward:", error2);
3595
3848
  toast.error("Failed to submit campaign. Please try again.");
3596
3849
  } finally {
3597
3850
  setIsLoading(false);
@@ -3805,8 +4058,8 @@ function TaskChainBlindBoxStep({
3805
4058
  auto_follow_community: false
3806
4059
  });
3807
4060
  await refetchUserStatus();
3808
- } catch (error) {
3809
- console.error("Failed to submit campaign:", error);
4061
+ } catch (error2) {
4062
+ console.error("Failed to submit campaign:", error2);
3810
4063
  toast.error("Failed to submit campaign. Please try again.");
3811
4064
  setShowManualSubmit(true);
3812
4065
  } finally {
@@ -3826,8 +4079,8 @@ function TaskChainBlindBoxStep({
3826
4079
  }
3827
4080
  await api.claimBlindBoxRewards({ campaign_id: campaign.id });
3828
4081
  await refetchUserStatus();
3829
- } catch (error) {
3830
- console.error("Failed to claim blind box:", error);
4082
+ } catch (error2) {
4083
+ console.error("Failed to claim blind box:", error2);
3831
4084
  toast.error("Failed to claim reward. Please try again.");
3832
4085
  (_a = blindBoxDialogRef.current) == null ? void 0 : _a.resetToUnopened();
3833
4086
  } finally {
@@ -4000,8 +4253,8 @@ function NotEligible({
4000
4253
  if (refetchUserStatus) {
4001
4254
  await refetchUserStatus();
4002
4255
  }
4003
- } catch (error) {
4004
- console.error("Failed to check eligibility:", error);
4256
+ } catch (error2) {
4257
+ console.error("Failed to check eligibility:", error2);
4005
4258
  } finally {
4006
4259
  setIsRefreshing(false);
4007
4260
  }
@@ -4217,8 +4470,8 @@ function TaskChainDetail({
4217
4470
  const api = createQuestApi(client);
4218
4471
  await api.checkUserCampaignEligibility({ campaign_id: campaign.id });
4219
4472
  await refetchUserStatus();
4220
- } catch (error) {
4221
- console.error("Failed to check eligibility after login:", error);
4473
+ } catch (error2) {
4474
+ console.error("Failed to check eligibility after login:", error2);
4222
4475
  }
4223
4476
  };
4224
4477
  checkEligibility();
@@ -4457,7 +4710,7 @@ function TaskChainDialog({
4457
4710
  userStatus,
4458
4711
  campaignStatusInfo,
4459
4712
  isLoading,
4460
- error,
4713
+ error: error2,
4461
4714
  refetchUserStatus
4462
4715
  } = useTaskChainDetail({
4463
4716
  campaignId,
@@ -4514,11 +4767,11 @@ function TaskChainDialog({
4514
4767
  }
4515
4768
  }, [(_b = userStatus == null ? void 0 : userStatus.user_status) == null ? void 0 : _b.is_winner, onUpdate]);
4516
4769
  return /* @__PURE__ */ jsx(BottomDialog, { open, onClose, top: "6vh", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-content", children: [
4517
- error && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4770
+ error2 && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4518
4771
  /* @__PURE__ */ jsx("div", { children: "Failed to load task chain" }),
4519
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error })
4772
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error2 })
4520
4773
  ] }),
4521
- !error && /* @__PURE__ */ jsx(
4774
+ !error2 && /* @__PURE__ */ jsx(
4522
4775
  TaskChainDetail,
4523
4776
  {
4524
4777
  campaign,
@@ -4553,6 +4806,7 @@ function SectorItemComponent({
4553
4806
  onCoolDownComplete,
4554
4807
  onDoneCountdownComplete
4555
4808
  }) {
4809
+ const { t } = useCommunityTaskLocale();
4556
4810
  const hasPeriodicTask = useMemo(() => {
4557
4811
  return sector.cards.some((card) => {
4558
4812
  if (card.card_type !== TaskCardType.GTCTask) return false;
@@ -4635,7 +4889,7 @@ function SectorItemComponent({
4635
4889
  return null;
4636
4890
  }) }),
4637
4891
  completedCards.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
4638
- /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: "🎉 You have completed" }),
4892
+ /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: t("you_have_completed") }),
4639
4893
  /* @__PURE__ */ jsx("div", { className: "taskon-sector-tasks taskon-sector-tasks-completed", children: completedCards.map((card) => {
4640
4894
  const key = getCardKey(card);
4641
4895
  if (card.card_type === TaskCardType.TaskChain) {
@@ -4723,16 +4977,6 @@ function CommunityTaskListSkeleton({
4723
4977
  }
4724
4978
  );
4725
4979
  }
4726
- const RECURRENCE_LABEL_MAP = {
4727
- Once: "Once",
4728
- Daily: "Daily",
4729
- Weekly: "Weekly",
4730
- Monthly: "Monthly",
4731
- Unlimited: "Unlimited"
4732
- };
4733
- function getRecurrenceLabel(recurrence) {
4734
- return RECURRENCE_LABEL_MAP[recurrence || "Once"] || "Once";
4735
- }
4736
4980
  function DialogPointReward({
4737
4981
  isPeriodic,
4738
4982
  recurrence,
@@ -4742,6 +4986,7 @@ function DialogPointReward({
4742
4986
  totalEarned = 0,
4743
4987
  communityInfo
4744
4988
  }) {
4989
+ const { t } = useCommunityTaskLocale();
4745
4990
  const displayAmount = useMemo(() => {
4746
4991
  if (recurrence === RecurrenceType.Unlimited) {
4747
4992
  if (totalEarned) {
@@ -4768,13 +5013,15 @@ function DialogPointReward({
4768
5013
  ] }),
4769
5014
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label", children: [
4770
5015
  name,
4771
- " /Time"
5016
+ " ",
5017
+ t("per_time")
4772
5018
  ] })
4773
5019
  ] }),
4774
5020
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount taskon-task-dialog-period-amount--em", children: totalEarned || 0 }),
4775
5021
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label taskon-task-dialog-period-label--em", children: [
4776
5022
  name,
4777
- " earned"
5023
+ " ",
5024
+ t("earned")
4778
5025
  ] })
4779
5026
  ] });
4780
5027
  }
@@ -4827,6 +5074,7 @@ function DialogTokenReward({
4827
5074
  chainIcon,
4828
5075
  communityInfo
4829
5076
  }) {
5077
+ const { t } = useCommunityTaskLocale();
4830
5078
  if (isPeriodic) {
4831
5079
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period", children: [
4832
5080
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount", children: amount }),
@@ -4842,7 +5090,7 @@ function DialogTokenReward({
4842
5090
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-period-label", children: name }),
4843
5091
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-period-label taskon-task-dialog-token-period-label--em", children: [
4844
5092
  " ",
4845
- "earned"
5093
+ t("earned")
4846
5094
  ] })
4847
5095
  ] })
4848
5096
  ] });
@@ -4913,18 +5161,13 @@ function TokenStatusLeft({
4913
5161
  totalUnit,
4914
5162
  availableUnit
4915
5163
  }) {
5164
+ const { t } = useCommunityTaskLocale();
4916
5165
  const current = useMemo(
4917
5166
  () => calcCurrent(totalUnit, availableUnit),
4918
5167
  [totalUnit, availableUnit]
4919
5168
  );
4920
5169
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress", children: [
4921
- /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress__content", children: [
4922
- "Hurry up! Only",
4923
- " ",
4924
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-token-progress__text", children: availableUnit ?? 0 }),
4925
- " ",
4926
- "left"
4927
- ] }),
5170
+ /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__content", children: t("only_left", { val: availableUnit ?? 0 }) }),
4928
5171
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__bar", children: /* @__PURE__ */ jsx(ColorfulProgress, { current, total: String(totalUnit) }) })
4929
5172
  ] });
4930
5173
  }
@@ -4939,17 +5182,11 @@ function formatDateTime(timestamp) {
4939
5182
  }
4940
5183
  function formatCountdown(diff) {
4941
5184
  if (diff <= 0) return "00:00:00";
4942
- if (diff / (1e3 * 60 * 60) > 24) {
4943
- const day2 = 24 * 60 * 60 * 1e3;
4944
- const days = Math.ceil(diff / day2);
4945
- return `${days} day${days > 1 ? "s" : ""}`;
4946
- }
4947
- const day = 24 * 60 * 60 * 1e3;
4948
5185
  const hour = 60 * 60 * 1e3;
4949
5186
  const minute = 60 * 1e3;
4950
5187
  const second = 1e3;
4951
5188
  const normalizedDiff = Math.abs(diff);
4952
- const hours = Math.floor(normalizedDiff % day / hour);
5189
+ const hours = Math.floor(normalizedDiff / hour);
4953
5190
  const minutes = Math.floor(normalizedDiff % hour / minute);
4954
5191
  const seconds = Math.floor(normalizedDiff % minute / second);
4955
5192
  const prefix2 = (n) => String(n).padStart(2, "0");
@@ -4977,6 +5214,7 @@ function DialogRewardCard({
4977
5214
  communityInfo,
4978
5215
  latestSubmittedTime = 0
4979
5216
  }) {
5217
+ const { t } = useCommunityTaskLocale();
4980
5218
  const { chains } = useTaskOnContext();
4981
5219
  const tokenChainIcon = useMemo(() => {
4982
5220
  var _a;
@@ -5003,21 +5241,18 @@ function DialogRewardCard({
5003
5241
  const renderPeriodicCountdown = useCallback(() => {
5004
5242
  if (!showPeriodicCountdown) return null;
5005
5243
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-periodic-done", children: [
5006
- /* @__PURE__ */ jsx("span", { children: "Done for today" }),
5244
+ /* @__PURE__ */ jsx("span", { children: t("done_today") }),
5007
5245
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__line" }),
5008
- /* @__PURE__ */ jsx("span", { children: "Continue in" }),
5246
+ /* @__PURE__ */ jsx("span", { children: t("continue_in") }),
5009
5247
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__time", children: countdownLabel })
5010
5248
  ] });
5011
- }, [showPeriodicCountdown, countdownLabel]);
5249
+ }, [showPeriodicCountdown, countdownLabel, t]);
5012
5250
  const renderDefaultStatus = () => {
5013
5251
  if (recurrence === RecurrenceType.Unlimited && latestSubmittedTime && latestSubmittedTime > 0) {
5014
- return /* @__PURE__ */ jsxs("span", { className: "taskon-task-dialog-updated", children: [
5015
- "Updated at ",
5016
- formatDateTime(latestSubmittedTime)
5017
- ] });
5252
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-updated", children: t("updated_at", { val: formatDateTime(latestSubmittedTime) }) });
5018
5253
  }
5019
5254
  if (isWon) {
5020
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
5255
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
5021
5256
  }
5022
5257
  return null;
5023
5258
  };
@@ -5030,7 +5265,7 @@ function DialogRewardCard({
5030
5265
  isPeriodic,
5031
5266
  recurrence,
5032
5267
  amount: reward.amount ?? 0,
5033
- name: reward.name ?? "Points",
5268
+ name: reward.name ?? t("community_points"),
5034
5269
  icon: reward.icon,
5035
5270
  totalEarned,
5036
5271
  communityInfo
@@ -5088,12 +5323,12 @@ function DialogRewardCard({
5088
5323
  const statusNode = showPeriodicCountdown ? renderPeriodicCountdown() : renderStatus ? renderStatus() : renderDefaultStatus();
5089
5324
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-reward-card", children: [
5090
5325
  claimLimit > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-max-claim", children: [
5091
- "Max. Claims",
5326
+ t("max_claim_num"),
5092
5327
  " ",
5093
5328
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-max-claim--highlight", children: claimLimit })
5094
5329
  ] }),
5095
5330
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-row", children: [
5096
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-rewards-label", children: "🎁 Rewards" }),
5331
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-rewards-label", children: t("gift_rewards") }),
5097
5332
  (statusPrefixNode || statusNode) && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-right", children: [
5098
5333
  statusPrefixNode,
5099
5334
  statusNode
@@ -5109,6 +5344,7 @@ function CloseIn({
5109
5344
  onClose
5110
5345
  }) {
5111
5346
  const [countdown, setCountdown] = useState(seconds);
5347
+ const { t } = useCommunityTaskLocale();
5112
5348
  const timerRef = useRef(null);
5113
5349
  const handleClose = useCallback(() => {
5114
5350
  onClose();
@@ -5134,11 +5370,7 @@ function CloseIn({
5134
5370
  }
5135
5371
  };
5136
5372
  }, [handleClose]);
5137
- return /* @__PURE__ */ jsxs("div", { className: "taskon-close-in", children: [
5138
- "Closing in ",
5139
- countdown,
5140
- "s"
5141
- ] });
5373
+ return /* @__PURE__ */ jsx("div", { className: "taskon-close-in", children: t("close_in", { val: countdown }) });
5142
5374
  }
5143
5375
  function BaseDialogLayout({
5144
5376
  recurrence,
@@ -5175,7 +5407,8 @@ function BaseDialogLayout({
5175
5407
  onCloseInClose
5176
5408
  }) {
5177
5409
  var _a;
5178
- const recurrenceLabel = getRecurrenceLabel(recurrence);
5410
+ const { t } = useCommunityTaskLocale();
5411
+ const recurrenceLabel = getRecurrenceLabel(t, recurrence);
5179
5412
  const shouldShowEligibilityMask = Boolean(
5180
5413
  ((_a = eligibilityTask == null ? void 0 : eligibilityTask.eligiblity) == null ? void 0 : _a.length) && (eligibilityConditions == null ? void 0 : eligibilityConditions.length)
5181
5414
  );
@@ -5189,7 +5422,7 @@ function BaseDialogLayout({
5189
5422
  ] }) });
5190
5423
  }
5191
5424
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-valid-time", children: [
5192
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-label", children: "Valid Until:" }),
5425
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-label", children: t("valid_util_is") }),
5193
5426
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-value", children: validTime.endTime })
5194
5427
  ] });
5195
5428
  };
@@ -5268,6 +5501,7 @@ function TemplateDialogContent({
5268
5501
  }) {
5269
5502
  var _a, _b, _c, _d;
5270
5503
  const userStatus = task.user_status;
5504
+ const { t } = useCommunityTaskLocale();
5271
5505
  const { showToast } = useToast();
5272
5506
  const { getChainType } = useChainMap();
5273
5507
  const { communityInfo } = useTaskOnContext();
@@ -5291,7 +5525,7 @@ function TemplateDialogContent({
5291
5525
  );
5292
5526
  const coolDown = sharedCoolDown ?? localCoolDown;
5293
5527
  const taskTitle = useMemo(() => {
5294
- if (!info) return "Task";
5528
+ if (!info) return t("task_up");
5295
5529
  const { template, name } = info;
5296
5530
  if (name !== template.template_name) {
5297
5531
  return name;
@@ -5303,7 +5537,7 @@ function TemplateDialogContent({
5303
5537
  return null;
5304
5538
  }
5305
5539
  return name;
5306
- }, [info, params.custom_title, params.title_express]);
5540
+ }, [info, params.custom_title, params.title_express, t]);
5307
5541
  const titleContent = useMemo(() => {
5308
5542
  if (taskTitle) return taskTitle;
5309
5543
  if (params.title_express) {
@@ -5314,8 +5548,8 @@ function TemplateDialogContent({
5314
5548
  }
5315
5549
  );
5316
5550
  }
5317
- return (info == null ? void 0 : info.name) || "Task";
5318
- }, [taskTitle, params.title_express, info == null ? void 0 : info.name]);
5551
+ return (info == null ? void 0 : info.name) || t("task_up");
5552
+ }, [taskTitle, params.title_express, info == null ? void 0 : info.name, t]);
5319
5553
  const validationTimeFrame = useMemo(() => {
5320
5554
  if (!(info == null ? void 0 : info.template)) return void 0;
5321
5555
  const { class_type, is_hold } = info.template;
@@ -5351,8 +5585,8 @@ function TemplateDialogContent({
5351
5585
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5352
5586
  }, [sharedOnCoolDownComplete]);
5353
5587
  const handleBindFailed = useCallback(
5354
- (error) => {
5355
- showToast(error, "error");
5588
+ (error2) => {
5589
+ showToast(error2, "error");
5356
5590
  },
5357
5591
  [showToast]
5358
5592
  );
@@ -5379,7 +5613,7 @@ function TemplateDialogContent({
5379
5613
  }
5380
5614
  }, [params.action_link, params.action_auto_verify, params.is_link_task, handleClaim]);
5381
5615
  if (!info) {
5382
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
5616
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5383
5617
  }
5384
5618
  return /* @__PURE__ */ jsxs(
5385
5619
  BaseDialogLayout,
@@ -5453,6 +5687,7 @@ function PowImageUploader({
5453
5687
  onConfirmed,
5454
5688
  onError
5455
5689
  }) {
5690
+ const { t } = useCommunityTaskLocale();
5456
5691
  const [previewUrl, setPreviewUrl] = useState(defaultUrl);
5457
5692
  const [file, setFile] = useState(null);
5458
5693
  const [progress, setProgress] = useState(0);
@@ -5473,7 +5708,7 @@ function PowImageUploader({
5473
5708
  const selectedFile = (_a = event.target.files) == null ? void 0 : _a[0];
5474
5709
  if (!selectedFile) return;
5475
5710
  if (selectedFile.size > MAX_FILE_SIZE) {
5476
- onError == null ? void 0 : onError("Image size exceeds 10MB limit");
5711
+ onError == null ? void 0 : onError(t("invalid_image_size_10m"));
5477
5712
  return;
5478
5713
  }
5479
5714
  setFile(selectedFile);
@@ -5486,12 +5721,12 @@ function PowImageUploader({
5486
5721
  reader.readAsDataURL(selectedFile);
5487
5722
  await uploadFile(selectedFile);
5488
5723
  },
5489
- [onError]
5724
+ [onError, t]
5490
5725
  );
5491
5726
  const uploadFile = useCallback(
5492
5727
  async (fileToUpload) => {
5493
5728
  if (!client) {
5494
- onError == null ? void 0 : onError("Client not initialized");
5729
+ onError == null ? void 0 : onError(t("client_not_initialized"));
5495
5730
  return;
5496
5731
  }
5497
5732
  try {
@@ -5514,17 +5749,17 @@ function PowImageUploader({
5514
5749
  );
5515
5750
  abortControllerRef.current = null;
5516
5751
  onConfirmed(result.cdn_url);
5517
- } catch (error) {
5518
- if (error instanceof DOMException && error.name === "AbortError") {
5752
+ } catch (error2) {
5753
+ if (error2 instanceof DOMException && error2.name === "AbortError") {
5519
5754
  return;
5520
5755
  }
5521
- const message = error instanceof Error ? error.message : "Upload failed";
5756
+ const message = error2 instanceof Error ? error2.message : t("upload_failed");
5522
5757
  onError == null ? void 0 : onError(message);
5523
5758
  } finally {
5524
5759
  setIsUploading(false);
5525
5760
  }
5526
5761
  },
5527
- [client, onConfirmed, onError]
5762
+ [client, onConfirmed, onError, t]
5528
5763
  );
5529
5764
  const handleClick = useCallback(() => {
5530
5765
  var _a;
@@ -5548,7 +5783,7 @@ function PowImageUploader({
5548
5783
  onKeyDown: handleKeyDown,
5549
5784
  role: "button",
5550
5785
  tabIndex: disabled ? -1 : 0,
5551
- "aria-label": "Upload image",
5786
+ "aria-label": t("upload_image"),
5552
5787
  "aria-disabled": disabled,
5553
5788
  children: [
5554
5789
  /* @__PURE__ */ jsx(
@@ -5567,7 +5802,7 @@ function PowImageUploader({
5567
5802
  "img",
5568
5803
  {
5569
5804
  src: previewUrl,
5570
- alt: "Preview",
5805
+ alt: t("upload_image"),
5571
5806
  className: "taskon-pow-uploader-preview"
5572
5807
  }
5573
5808
  ),
@@ -5601,7 +5836,7 @@ function PowImageUploader({
5601
5836
  ]
5602
5837
  }
5603
5838
  ),
5604
- /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip", children: "Click to upload image" })
5839
+ /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip", children: t("click_to_upload_image") })
5605
5840
  ] })
5606
5841
  ] }) : (
5607
5842
  /* 无预览时显示上传提示 */
@@ -5635,7 +5870,7 @@ function PowImageUploader({
5635
5870
  ]
5636
5871
  }
5637
5872
  ),
5638
- /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip taskon-pow-uploader-tip--empty", children: "Click to upload image" })
5873
+ /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip taskon-pow-uploader-tip--empty", children: t("click_to_upload_image") })
5639
5874
  ] })
5640
5875
  ),
5641
5876
  isUploading && /* @__PURE__ */ jsx("div", { className: "taskon-pow-uploader-progress", children: /* @__PURE__ */ jsx(
@@ -5668,6 +5903,7 @@ function PowTaskDialogContent({
5668
5903
  }) {
5669
5904
  var _a, _b, _c;
5670
5905
  const userStatus = task.user_status;
5906
+ const { t } = useCommunityTaskLocale();
5671
5907
  const { toast } = useToast();
5672
5908
  const { communityInfo } = useTaskOnContext();
5673
5909
  const totalEarned = ((_a = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a.amount) ?? 0;
@@ -5697,7 +5933,7 @@ function PowTaskDialogContent({
5697
5933
  const validateInput = useCallback(() => {
5698
5934
  if (params.type === "Image") {
5699
5935
  if (!answer.trim()) {
5700
- setInputError("Please upload an image");
5936
+ setInputError(t("please_upload_image"));
5701
5937
  return false;
5702
5938
  }
5703
5939
  setInputError(null);
@@ -5705,7 +5941,7 @@ function PowTaskDialogContent({
5705
5941
  }
5706
5942
  if (!answer.trim()) {
5707
5943
  setInputError(
5708
- params.type === "URL" ? "Please enter URL" : "Please enter text"
5944
+ params.type === "URL" ? t("please_enter_url") : t("please_enter_text")
5709
5945
  );
5710
5946
  return false;
5711
5947
  }
@@ -5713,24 +5949,24 @@ function PowTaskDialogContent({
5713
5949
  try {
5714
5950
  new URL(answer);
5715
5951
  } catch {
5716
- setInputError("Please enter a valid url address");
5952
+ setInputError(t("invalid_url"));
5717
5953
  return false;
5718
5954
  }
5719
5955
  }
5720
5956
  setInputError(null);
5721
5957
  return true;
5722
- }, [answer, params.type]);
5958
+ }, [answer, params.type, t]);
5723
5959
  const handleSubmit = useCallback(async () => {
5724
5960
  if (!validateInput()) return;
5725
5961
  await submitTask(answer);
5726
5962
  }, [validateInput, submitTask, answer]);
5727
5963
  const handleResubmit = useCallback(async () => {
5728
5964
  if (!validateInput()) return;
5729
- const success = await submitTask(answer);
5730
- if (success) {
5731
- toast.success("Re-submitted successfully");
5965
+ const result = await submitTask(answer);
5966
+ if (result.successful) {
5967
+ toast.success(t("re_submitted_success"));
5732
5968
  }
5733
- }, [validateInput, submitTask, answer, toast]);
5969
+ }, [validateInput, submitTask, answer, toast, t]);
5734
5970
  const renderInputArea = () => {
5735
5971
  const powType = params.type || "Text";
5736
5972
  if (powType === "URL") {
@@ -5741,7 +5977,7 @@ function PowTaskDialogContent({
5741
5977
  type: "url",
5742
5978
  value: answer,
5743
5979
  onChange: setAnswer,
5744
- placeholder: "Please enter URL",
5980
+ placeholder: t("please_enter_url"),
5745
5981
  maxLength: 2e3,
5746
5982
  disabled: isInputDisabled,
5747
5983
  hasError: !!inputError,
@@ -5758,7 +5994,7 @@ function PowTaskDialogContent({
5758
5994
  {
5759
5995
  value: answer,
5760
5996
  onChange: setAnswer,
5761
- placeholder: "Enter here",
5997
+ placeholder: t("enter_here"),
5762
5998
  maxLength: 500,
5763
5999
  showCount: true,
5764
6000
  disabled: isInputDisabled,
@@ -5780,8 +6016,8 @@ function PowTaskDialogContent({
5780
6016
  setAnswer(url);
5781
6017
  setInputError(null);
5782
6018
  },
5783
- onError: (error) => {
5784
- setInputError(error);
6019
+ onError: (error2) => {
6020
+ setInputError(error2);
5785
6021
  }
5786
6022
  }
5787
6023
  ),
@@ -5790,7 +6026,10 @@ function PowTaskDialogContent({
5790
6026
  };
5791
6027
  const renderActionButton = () => {
5792
6028
  if (state.isWon) {
5793
- return /* @__PURE__ */ jsx("div", { className: "taskon-pow-dialog-done", children: "✅ Task completed" });
6029
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-pow-dialog-done", children: [
6030
+ "✅ ",
6031
+ t("task_completed")
6032
+ ] });
5794
6033
  }
5795
6034
  if (isUnderReview || isFailedButCanRetry) {
5796
6035
  return /* @__PURE__ */ jsx(
@@ -5800,7 +6039,7 @@ function PowTaskDialogContent({
5800
6039
  className: "taskon-pow-dialog-submit",
5801
6040
  onClick: handleResubmit,
5802
6041
  disabled: isSubmitting,
5803
- children: isSubmitting ? "Submitting..." : "Re-submit"
6042
+ children: isSubmitting ? t("submitting") : t("resubmit")
5804
6043
  }
5805
6044
  );
5806
6045
  }
@@ -5812,7 +6051,7 @@ function PowTaskDialogContent({
5812
6051
  className: "taskon-pow-dialog-submit",
5813
6052
  onClick: handleSubmit,
5814
6053
  disabled: isSubmitting,
5815
- children: isSubmitting ? "Submitting..." : "Submit"
6054
+ children: isSubmitting ? t("submitting") : t("submit")
5816
6055
  }
5817
6056
  );
5818
6057
  }
@@ -5820,18 +6059,18 @@ function PowTaskDialogContent({
5820
6059
  };
5821
6060
  const renderReviewStatus = useCallback(() => {
5822
6061
  if (state.isWon) {
5823
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
6062
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
5824
6063
  }
5825
6064
  if (isUnderReview) {
5826
- return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--review", children: "Under Review" });
6065
+ return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--review", children: t("under_review") });
5827
6066
  }
5828
6067
  if ((userStatus == null ? void 0 : userStatus.review_result) === TaskReviewResult.Failed) {
5829
- return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--failed", children: "Failed" });
6068
+ return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--failed", children: t("failed") });
5830
6069
  }
5831
6070
  return null;
5832
- }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result]);
6071
+ }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result, t]);
5833
6072
  if (!info) {
5834
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6073
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5835
6074
  }
5836
6075
  return /* @__PURE__ */ jsxs(
5837
6076
  BaseDialogLayout,
@@ -5887,6 +6126,7 @@ function ContractInteractiveDialogContent({
5887
6126
  }) {
5888
6127
  var _a, _b, _c;
5889
6128
  const userStatus = task.user_status;
6129
+ const { t } = useCommunityTaskLocale();
5890
6130
  const { showToast } = useToast();
5891
6131
  const { getChainType } = useChainMap();
5892
6132
  const { communityInfo } = useTaskOnContext();
@@ -5947,8 +6187,8 @@ function ContractInteractiveDialogContent({
5947
6187
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5948
6188
  }, [sharedOnCoolDownComplete]);
5949
6189
  const handleBindFailed = useCallback(
5950
- (error) => {
5951
- showToast(error, "error");
6190
+ (error2) => {
6191
+ showToast(error2, "error");
5952
6192
  },
5953
6193
  [showToast]
5954
6194
  );
@@ -5962,7 +6202,7 @@ function ContractInteractiveDialogContent({
5962
6202
  }
5963
6203
  }, [params.task_url]);
5964
6204
  if (!info) {
5965
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6205
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5966
6206
  }
5967
6207
  return /* @__PURE__ */ jsxs(
5968
6208
  BaseDialogLayout,
@@ -5994,13 +6234,16 @@ function ContractInteractiveDialogContent({
5994
6234
  children: [
5995
6235
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
5996
6236
  params.desc && /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) }),
5997
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6237
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
5998
6238
  "button",
5999
6239
  {
6000
6240
  type: "button",
6001
6241
  className: "taskon-task-dialog-action",
6002
6242
  onClick: handleAction,
6003
- children: "👉 Proceed to complete the task"
6243
+ children: [
6244
+ "👉 ",
6245
+ t("proceed_2_complete_the_task")
6246
+ ]
6004
6247
  }
6005
6248
  )
6006
6249
  ]
@@ -6030,6 +6273,7 @@ function SwapDexDialogContent({
6030
6273
  }) {
6031
6274
  var _a, _b, _c;
6032
6275
  const userStatus = task.user_status;
6276
+ const { t } = useCommunityTaskLocale();
6033
6277
  const { showToast } = useToast();
6034
6278
  const { getChainType, chainMap } = useChainMap();
6035
6279
  const { communityInfo } = useTaskOnContext();
@@ -6058,13 +6302,16 @@ function SwapDexDialogContent({
6058
6302
  );
6059
6303
  const coolDown = sharedCoolDown ?? localCoolDown;
6060
6304
  const isFixedRule = params.is_fixed_reward_type;
6061
- const rulePointName = reward.name || "Points";
6305
+ const rulePointName = reward.name || t("community_points");
6062
6306
  const ruleMaxText = useMemo(() => {
6063
6307
  if (typeof params.swap_receive_max_points === "number" && params.swap_receive_max_points >= 0) {
6064
- return `(Max ${params.swap_receive_max_points} ${rulePointName})`;
6308
+ return t("community_rule_max", {
6309
+ val: params.swap_receive_max_points,
6310
+ name: rulePointName
6311
+ });
6065
6312
  }
6066
6313
  return "";
6067
- }, [params.swap_receive_max_points, rulePointName]);
6314
+ }, [params.swap_receive_max_points, rulePointName, t]);
6068
6315
  const hasRulesText = useMemo(() => {
6069
6316
  return Boolean(params.each_trading_volume && params.each_receive_points);
6070
6317
  }, [params.each_trading_volume, params.each_receive_points]);
@@ -6078,13 +6325,13 @@ function SwapDexDialogContent({
6078
6325
  tokenOutList: params.token_out_list,
6079
6326
  tokenInList: params.token_in_list,
6080
6327
  chainLabel,
6081
- dexName: (info == null ? void 0 : info.project_name) || (communityInfo == null ? void 0 : communityInfo.name) || "DEX",
6328
+ dexName: (info == null ? void 0 : info.project_name) || (communityInfo == null ? void 0 : communityInfo.name) || t("community_dex"),
6082
6329
  dexLink: params.task_url,
6083
6330
  isFixedReward: params.is_fixed_reward_type || false,
6084
6331
  minTradingVolume: params.min_trading_volume,
6085
6332
  minTradesTimes: params.min_trades_times
6086
6333
  });
6087
- }, [params, chainLabel, info == null ? void 0 : info.project_name, communityInfo == null ? void 0 : communityInfo.name]);
6334
+ }, [params, chainLabel, info == null ? void 0 : info.project_name, communityInfo == null ? void 0 : communityInfo.name, t]);
6088
6335
  const fromTokenDisplay = useMemo(
6089
6336
  () => formatSwapTokensForDisplay(params.token_out_list),
6090
6337
  [params.token_out_list]
@@ -6133,8 +6380,8 @@ function SwapDexDialogContent({
6133
6380
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
6134
6381
  }, [sharedOnCoolDownComplete]);
6135
6382
  const handleBindFailed = useCallback(
6136
- (error) => {
6137
- showToast(error, "error");
6383
+ (error2) => {
6384
+ showToast(error2, "error");
6138
6385
  },
6139
6386
  [showToast]
6140
6387
  );
@@ -6155,22 +6402,23 @@ function SwapDexDialogContent({
6155
6402
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-progress-separator", children: "/" }),
6156
6403
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-progress-total", children: [
6157
6404
  minTimes,
6158
- " Times"
6405
+ " ",
6406
+ t("times")
6159
6407
  ] })
6160
6408
  ] });
6161
6409
  }
6162
6410
  return null;
6163
- }, [isDynamicTimes, userStatus == null ? void 0 : userStatus.current_trades_times, params.min_trades_times]);
6411
+ }, [isDynamicTimes, userStatus == null ? void 0 : userStatus.current_trades_times, params.min_trades_times, t]);
6164
6412
  const renderFixedModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6165
- params.chain && /* @__PURE__ */ jsx(CardField, { label: "Chain: ", value: chainLabel }),
6413
+ params.chain && /* @__PURE__ */ jsx(CardField, { label: t("chain_is"), value: chainLabel }),
6166
6414
  params.token_out_list && params.token_out_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6167
- /* @__PURE__ */ jsx(CardField, { label: "Swap From: ", value: fromTokenDisplay }),
6415
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_from_is"), value: fromTokenDisplay }),
6168
6416
  params.token_out_list.filter(
6169
6417
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6170
6418
  ).map((token) => /* @__PURE__ */ jsx(
6171
6419
  CardField,
6172
6420
  {
6173
- label: `${token.symbol || "Token"} Address: `,
6421
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6174
6422
  value: formatAddress(token.address || ""),
6175
6423
  copy_text: token.address
6176
6424
  },
@@ -6178,13 +6426,13 @@ function SwapDexDialogContent({
6178
6426
  ))
6179
6427
  ] }),
6180
6428
  params.token_in_list && params.token_in_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6181
- /* @__PURE__ */ jsx(CardField, { label: "Swap To: ", value: toTokenDisplay }),
6429
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_to_is"), value: toTokenDisplay }),
6182
6430
  params.token_in_list.filter(
6183
6431
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6184
6432
  ).map((token) => /* @__PURE__ */ jsx(
6185
6433
  CardField,
6186
6434
  {
6187
- label: `${token.symbol || "Token"} Address: `,
6435
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6188
6436
  value: formatAddress(token.address || ""),
6189
6437
  copy_text: token.address
6190
6438
  },
@@ -6192,21 +6440,21 @@ function SwapDexDialogContent({
6192
6440
  ))
6193
6441
  ] }),
6194
6442
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6195
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6443
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6196
6444
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6197
6445
  ] })
6198
6446
  ] });
6199
6447
  const renderDynamicModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6200
6448
  hasRulesText && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6201
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Rules" }),
6449
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("rules") }),
6202
6450
  /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section-content taskon-swap-dialog-section-content--rules", children: [
6203
- /* @__PURE__ */ jsx("span", { children: "Every" }),
6451
+ /* @__PURE__ */ jsx("span", { children: t("every") }),
6204
6452
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-highlight", children: [
6205
6453
  "$",
6206
6454
  params.each_trading_volume || "0",
6207
6455
  " USD"
6208
6456
  ] }),
6209
- /* @__PURE__ */ jsx("span", { children: "will give you" }),
6457
+ /* @__PURE__ */ jsx("span", { children: t("will_give_you") }),
6210
6458
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-rules-highlight", children: params.each_receive_points }),
6211
6459
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-point-name", children: [
6212
6460
  rulePointName,
@@ -6215,12 +6463,12 @@ function SwapDexDialogContent({
6215
6463
  ] })
6216
6464
  ] }),
6217
6465
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6218
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6466
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6219
6467
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6220
6468
  ] })
6221
6469
  ] });
6222
6470
  if (!info) {
6223
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6471
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
6224
6472
  }
6225
6473
  return /* @__PURE__ */ jsxs(
6226
6474
  BaseDialogLayout,
@@ -6253,13 +6501,16 @@ function SwapDexDialogContent({
6253
6501
  children: [
6254
6502
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
6255
6503
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: isFixedRule ? renderFixedModeContent() : renderDynamicModeContent() }),
6256
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6504
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
6257
6505
  "button",
6258
6506
  {
6259
6507
  type: "button",
6260
6508
  className: "taskon-task-dialog-action",
6261
6509
  onClick: handleAction,
6262
- children: "👉 Swap"
6510
+ children: [
6511
+ "👉 ",
6512
+ t("swap")
6513
+ ]
6263
6514
  }
6264
6515
  )
6265
6516
  ]
@@ -6342,15 +6593,17 @@ function getDialogContentComponent(templateId) {
6342
6593
  return TaskDialogContent;
6343
6594
  }
6344
6595
  function DialogLoading() {
6596
+ const { t } = useCommunityTaskLocale();
6345
6597
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-loading", children: [
6346
6598
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-loading-spinner" }),
6347
- /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: "Loading task..." })
6599
+ /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: t("loading_task") })
6348
6600
  ] });
6349
6601
  }
6350
6602
  function DialogError({
6351
6603
  message,
6352
6604
  onRetry
6353
6605
  }) {
6606
+ const { t } = useCommunityTaskLocale();
6354
6607
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-error", children: [
6355
6608
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-error-icon", children: ":(" }),
6356
6609
  /* @__PURE__ */ jsx("p", { className: "taskon-dialog-error-message", children: message }),
@@ -6360,7 +6613,7 @@ function DialogError({
6360
6613
  type: "button",
6361
6614
  className: "taskon-dialog-error-retry",
6362
6615
  onClick: onRetry,
6363
- children: "Retry"
6616
+ children: t("retry")
6364
6617
  }
6365
6618
  )
6366
6619
  ] });
@@ -6380,11 +6633,12 @@ function TaskDialogComponent(props) {
6380
6633
  onCoolDownUpdate,
6381
6634
  onCoolDownComplete
6382
6635
  } = props;
6636
+ const { t } = useCommunityTaskLocale();
6383
6637
  const [justVerified, setJustVerified] = useState(false);
6384
6638
  const {
6385
6639
  data: fetchedTask,
6386
6640
  isLoading,
6387
- error,
6641
+ error: error2,
6388
6642
  refetch
6389
6643
  } = useTaskDetail({
6390
6644
  taskId: task ? null : taskId ?? null
@@ -6435,7 +6689,7 @@ function TaskDialogComponent(props) {
6435
6689
  const templateId = (_a2 = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a2.template_id;
6436
6690
  return getDialogContentComponent(templateId);
6437
6691
  }, [(_a = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a.template_id]);
6438
- const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? "任务详情";
6692
+ const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? t("task_details");
6439
6693
  const isOpen = task !== null || taskId !== null;
6440
6694
  if (typeof document === "undefined") {
6441
6695
  return null;
@@ -6446,14 +6700,14 @@ function TaskDialogComponent(props) {
6446
6700
  open: isOpen,
6447
6701
  onOpenChange: handleOpenChange,
6448
6702
  title: dialogTitle,
6449
- description: "查看任务详情和奖励信息",
6703
+ description: t("task_details_desc"),
6450
6704
  showCloseButton: true,
6451
6705
  bodyPadding: false,
6452
6706
  contentClassName: "taskon-task-dialog",
6453
6707
  maxWidth: rightSlot ? 800 : 480,
6454
6708
  children: [
6455
6709
  !task && isLoading && /* @__PURE__ */ jsx(DialogLoading, {}),
6456
- !task && error && /* @__PURE__ */ jsx(DialogError, { message: error, onRetry: refetch }),
6710
+ !task && error2 && /* @__PURE__ */ jsx(DialogError, { message: error2, onRetry: refetch }),
6457
6711
  taskData && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-wrapper", children: [
6458
6712
  renderContent ? renderContent(taskData) : /* @__PURE__ */ jsx(
6459
6713
  DialogContentComponent,
@@ -6573,12 +6827,13 @@ function CommunityTaskListInner(props) {
6573
6827
  rewardRedirectUrl = ""
6574
6828
  } = props;
6575
6829
  const { client, userToken } = useTaskOnContext();
6830
+ const { t } = useCommunityTaskLocale();
6576
6831
  const [taskCards, setTaskCards] = useState(
6577
6832
  []
6578
6833
  );
6579
6834
  const [selectedSectorId, setSelectedSectorId] = useState(null);
6580
6835
  const [isLoading, setIsLoading] = useState(true);
6581
- const [error, setError] = useState(null);
6836
+ const [error2, setError] = useState(null);
6582
6837
  const [openTask, setOpenTask] = useState(null);
6583
6838
  const [openTaskId, setOpenTaskId] = useState(
6584
6839
  initialTaskId ?? null
@@ -6597,10 +6852,13 @@ function CommunityTaskListInner(props) {
6597
6852
  return next;
6598
6853
  });
6599
6854
  }, []);
6600
- const handleTaskChainOpen = useCallback((taskChainId) => {
6601
- setOpenTaskChainId(taskChainId);
6602
- onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
6603
- }, [onTaskChainOpen]);
6855
+ const handleTaskChainOpen = useCallback(
6856
+ (taskChainId) => {
6857
+ setOpenTaskChainId(taskChainId);
6858
+ onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
6859
+ },
6860
+ [onTaskChainOpen]
6861
+ );
6604
6862
  const handleTaskChainClose = useCallback(() => {
6605
6863
  setOpenTaskChainId(null);
6606
6864
  onTaskChainClose == null ? void 0 : onTaskChainClose();
@@ -6618,7 +6876,7 @@ function CommunityTaskListInner(props) {
6618
6876
  useEffect(() => {
6619
6877
  const loadTasks = async () => {
6620
6878
  if (!client) {
6621
- setError("Client not initialized");
6879
+ setError(t("client_not_initialized"));
6622
6880
  setIsLoading(false);
6623
6881
  return;
6624
6882
  }
@@ -6632,60 +6890,54 @@ function CommunityTaskListInner(props) {
6632
6890
  });
6633
6891
  setTaskCards(data);
6634
6892
  } catch (err) {
6635
- setError(err instanceof Error ? err.message : "Failed to load");
6893
+ setError(err instanceof Error ? err.message : t("failed_to_load"));
6636
6894
  console.error("Failed to load community tasks:", err);
6637
6895
  } finally {
6638
6896
  setIsLoading(false);
6639
6897
  }
6640
6898
  };
6641
6899
  loadTasks();
6642
- }, [client, isPreview, userToken, sectorIds]);
6643
- const selectorOptions = React__default.useMemo(
6644
- () => {
6645
- const sectors = taskCards.map((item) => item.sector);
6646
- let options = sectors.map((sector) => ({
6647
- value: sector.id,
6648
- label: sector.name
6649
- }));
6650
- if (sectorIds && sectorIds.length > 0) {
6651
- const orderMap = new Map(
6652
- sectorIds.map((sectorId, index) => [sectorId, index])
6653
- );
6654
- options = options.filter((option) => orderMap.has(option.value)).sort((a, b) => {
6655
- const aIndex = orderMap.get(a.value) ?? 0;
6656
- const bIndex = orderMap.get(b.value) ?? 0;
6657
- return aIndex - bIndex;
6658
- });
6659
- }
6660
- return options;
6661
- },
6662
- [taskCards, sectorIds]
6663
- );
6664
- const filteredTaskCards = React__default.useMemo(
6665
- () => {
6666
- let result = taskCards;
6667
- if (sectorIds && sectorIds.length > 0) {
6668
- const idSet = new Set(sectorIds);
6669
- const orderMap = new Map(
6670
- sectorIds.map((sectorId, index) => [sectorId, index])
6671
- );
6672
- result = result.filter((item) => idSet.has(item.sector.id));
6673
- result = [...result].sort((a, b) => {
6674
- const aIndex = orderMap.get(a.sector.id);
6675
- const bIndex = orderMap.get(b.sector.id);
6676
- if (aIndex === void 0 && bIndex === void 0) return 0;
6677
- if (aIndex === void 0) return 1;
6678
- if (bIndex === void 0) return -1;
6679
- return aIndex - bIndex;
6680
- });
6681
- }
6682
- if (selectedSectorId !== null) {
6683
- result = result.filter((item) => item.sector.id === selectedSectorId);
6684
- }
6685
- return result;
6686
- },
6687
- [taskCards, selectedSectorId, sectorIds]
6688
- );
6900
+ }, [client, isPreview, userToken, sectorIds, t]);
6901
+ const selectorOptions = React__default.useMemo(() => {
6902
+ const sectors = taskCards.map((item) => item.sector);
6903
+ let options = sectors.map((sector) => ({
6904
+ value: sector.id,
6905
+ label: sector.name
6906
+ }));
6907
+ if (sectorIds && sectorIds.length > 0) {
6908
+ const orderMap = new Map(
6909
+ sectorIds.map((sectorId, index) => [sectorId, index])
6910
+ );
6911
+ options = options.filter((option) => orderMap.has(option.value)).sort((a, b) => {
6912
+ const aIndex = orderMap.get(a.value) ?? 0;
6913
+ const bIndex = orderMap.get(b.value) ?? 0;
6914
+ return aIndex - bIndex;
6915
+ });
6916
+ }
6917
+ return options;
6918
+ }, [taskCards, sectorIds]);
6919
+ const filteredTaskCards = React__default.useMemo(() => {
6920
+ let result = taskCards;
6921
+ if (sectorIds && sectorIds.length > 0) {
6922
+ const idSet = new Set(sectorIds);
6923
+ const orderMap = new Map(
6924
+ sectorIds.map((sectorId, index) => [sectorId, index])
6925
+ );
6926
+ result = result.filter((item) => idSet.has(item.sector.id));
6927
+ result = [...result].sort((a, b) => {
6928
+ const aIndex = orderMap.get(a.sector.id);
6929
+ const bIndex = orderMap.get(b.sector.id);
6930
+ if (aIndex === void 0 && bIndex === void 0) return 0;
6931
+ if (aIndex === void 0) return 1;
6932
+ if (bIndex === void 0) return -1;
6933
+ return aIndex - bIndex;
6934
+ });
6935
+ }
6936
+ if (selectedSectorId !== null) {
6937
+ result = result.filter((item) => item.sector.id === selectedSectorId);
6938
+ }
6939
+ return result;
6940
+ }, [taskCards, selectedSectorId, sectorIds]);
6689
6941
  const taskDependencyIndex = useMemo(() => {
6690
6942
  const index = /* @__PURE__ */ new Map();
6691
6943
  for (const sectorItem of taskCards) {
@@ -6703,7 +6955,9 @@ function CommunityTaskListInner(props) {
6703
6955
  if (eligibility.type !== EligibilityType.CommunityPreTask) {
6704
6956
  continue;
6705
6957
  }
6706
- const preTaskId = parsePreTaskIdFromEligibilityParams(eligibility.params);
6958
+ const preTaskId = parsePreTaskIdFromEligibilityParams(
6959
+ eligibility.params
6960
+ );
6707
6961
  if (!preTaskId || preTaskId === currentTaskId) {
6708
6962
  continue;
6709
6963
  }
@@ -6718,16 +6972,22 @@ function CommunityTaskListInner(props) {
6718
6972
  const handleSelectorChange = (value) => {
6719
6973
  setSelectedSectorId(value ?? null);
6720
6974
  };
6721
- const handleTaskClick = useCallback((taskCard) => {
6722
- setOpenTask(taskCard);
6723
- setOpenTaskId(null);
6724
- onTaskOpen == null ? void 0 : onTaskOpen(taskCard.card_info.id);
6725
- }, [onTaskOpen]);
6726
- const handleEligTaskClick = useCallback((taskId) => {
6727
- setOpenTaskId(taskId);
6728
- setOpenTask(null);
6729
- onTaskOpen == null ? void 0 : onTaskOpen(taskId);
6730
- }, [onTaskOpen]);
6975
+ const handleTaskClick = useCallback(
6976
+ (taskCard) => {
6977
+ setOpenTask(taskCard);
6978
+ setOpenTaskId(null);
6979
+ onTaskOpen == null ? void 0 : onTaskOpen(taskCard.card_info.id);
6980
+ },
6981
+ [onTaskOpen]
6982
+ );
6983
+ const handleEligTaskClick = useCallback(
6984
+ (taskId) => {
6985
+ setOpenTaskId(taskId);
6986
+ setOpenTask(null);
6987
+ onTaskOpen == null ? void 0 : onTaskOpen(taskId);
6988
+ },
6989
+ [onTaskOpen]
6990
+ );
6731
6991
  const handleDialogClose = useCallback(() => {
6732
6992
  setOpenTask(null);
6733
6993
  setOpenTaskId(null);
@@ -6746,138 +7006,162 @@ function CommunityTaskListInner(props) {
6746
7006
  if (!currentOpenTask) {
6747
7007
  return null;
6748
7008
  }
6749
- const updatedTask = findTaskByIdFromCards(data, currentOpenTask.card_info.id);
7009
+ const updatedTask = findTaskByIdFromCards(
7010
+ data,
7011
+ currentOpenTask.card_info.id
7012
+ );
6750
7013
  return updatedTask ?? currentOpenTask;
6751
7014
  });
6752
7015
  } catch (err) {
6753
7016
  console.error("Failed to refresh tasks:", err);
6754
7017
  }
6755
7018
  }, [client, isPreview, sectorIds]);
6756
- const refreshSingleCard = useCallback(async (cardId, cardType) => {
6757
- if (!client) return;
6758
- try {
6759
- const api = createCommunityTaskApi(client);
6760
- const latestCard = await api.getCommunityTaskCardInfo({
6761
- card_id: cardId,
6762
- card_type: cardType,
6763
- is_preview: isPreview
6764
- });
6765
- setTaskCards((currentCards) => {
6766
- let targetSectorIndex = -1;
6767
- let targetCardIndex = -1;
6768
- for (let sectorIndex = 0; sectorIndex < currentCards.length; sectorIndex += 1) {
6769
- const sectorItem = currentCards[sectorIndex];
6770
- if (!sectorItem) {
6771
- continue;
7019
+ const refreshSingleCard = useCallback(
7020
+ async (cardId, cardType) => {
7021
+ if (!client) return;
7022
+ try {
7023
+ const api = createCommunityTaskApi(client);
7024
+ const latestCard = await api.getCommunityTaskCardInfo({
7025
+ card_id: cardId,
7026
+ card_type: cardType,
7027
+ is_preview: isPreview
7028
+ });
7029
+ setTaskCards((currentCards) => {
7030
+ let targetSectorIndex = -1;
7031
+ let targetCardIndex = -1;
7032
+ for (let sectorIndex = 0; sectorIndex < currentCards.length; sectorIndex += 1) {
7033
+ const sectorItem = currentCards[sectorIndex];
7034
+ if (!sectorItem) {
7035
+ continue;
7036
+ }
7037
+ const cardIndex = sectorItem.cards.findIndex(
7038
+ (card) => card.card_type === cardType && card.card_info.id === cardId
7039
+ );
7040
+ if (cardIndex !== -1) {
7041
+ targetSectorIndex = sectorIndex;
7042
+ targetCardIndex = cardIndex;
7043
+ break;
7044
+ }
6772
7045
  }
6773
- const cardIndex = sectorItem.cards.findIndex(
6774
- (card) => card.card_type === cardType && card.card_info.id === cardId
6775
- );
6776
- if (cardIndex !== -1) {
6777
- targetSectorIndex = sectorIndex;
6778
- targetCardIndex = cardIndex;
6779
- break;
7046
+ if (targetSectorIndex === -1 || targetCardIndex === -1) {
7047
+ return currentCards;
6780
7048
  }
6781
- }
6782
- if (targetSectorIndex === -1 || targetCardIndex === -1) {
6783
- return currentCards;
6784
- }
6785
- const nextCards = [...currentCards];
6786
- const targetSector = currentCards[targetSectorIndex];
6787
- if (!targetSector) {
6788
- return currentCards;
6789
- }
6790
- const nextSectorCards = [...targetSector.cards];
6791
- nextSectorCards[targetCardIndex] = latestCard;
6792
- nextCards[targetSectorIndex] = {
6793
- ...targetSector,
6794
- cards: nextSectorCards
6795
- };
6796
- return nextCards;
6797
- });
6798
- if (cardType === TaskCardType.GTCTask) {
6799
- setOpenTask((currentOpenTask) => {
6800
- if (!currentOpenTask || currentOpenTask.card_info.id !== cardId) {
6801
- return currentOpenTask;
7049
+ const nextCards = [...currentCards];
7050
+ const targetSector = currentCards[targetSectorIndex];
7051
+ if (!targetSector) {
7052
+ return currentCards;
6802
7053
  }
6803
- return latestCard;
7054
+ const nextSectorCards = [...targetSector.cards];
7055
+ nextSectorCards[targetCardIndex] = latestCard;
7056
+ nextCards[targetSectorIndex] = {
7057
+ ...targetSector,
7058
+ cards: nextSectorCards
7059
+ };
7060
+ return nextCards;
6804
7061
  });
7062
+ if (cardType === TaskCardType.GTCTask) {
7063
+ setOpenTask((currentOpenTask) => {
7064
+ if (!currentOpenTask || currentOpenTask.card_info.id !== cardId) {
7065
+ return currentOpenTask;
7066
+ }
7067
+ return latestCard;
7068
+ });
7069
+ }
7070
+ } catch (err) {
7071
+ console.error(`Failed to refresh card ${cardType}:${cardId}:`, err);
6805
7072
  }
6806
- } catch (err) {
6807
- console.error(`Failed to refresh card ${cardType}:${cardId}:`, err);
6808
- }
6809
- }, [client, isPreview]);
6810
- const refreshSingleTask = useCallback(async (taskId) => {
6811
- await refreshSingleCard(taskId, TaskCardType.GTCTask);
6812
- }, [refreshSingleCard]);
6813
- const refreshSingleTaskChain = useCallback(async (taskChainId) => {
6814
- await refreshSingleCard(taskChainId, TaskCardType.TaskChain);
6815
- }, [refreshSingleCard]);
6816
- const handleClaimSuccess = useCallback(async (taskId) => {
6817
- if (!client) {
6818
- return;
6819
- }
6820
- if (typeof taskId !== "number") {
6821
- await refreshTaskList();
6822
- return;
6823
- }
6824
- await refreshSingleTask(taskId);
6825
- const dependentTasks = taskDependencyIndex.get(taskId);
6826
- if (dependentTasks && dependentTasks.size > 0) {
6827
- await refreshTaskList();
6828
- }
6829
- }, [client, refreshSingleTask, refreshTaskList, taskDependencyIndex]);
7073
+ },
7074
+ [client, isPreview]
7075
+ );
7076
+ const refreshSingleTask = useCallback(
7077
+ async (taskId) => {
7078
+ await refreshSingleCard(taskId, TaskCardType.GTCTask);
7079
+ },
7080
+ [refreshSingleCard]
7081
+ );
7082
+ const refreshSingleTaskChain = useCallback(
7083
+ async (taskChainId) => {
7084
+ await refreshSingleCard(taskChainId, TaskCardType.TaskChain);
7085
+ },
7086
+ [refreshSingleCard]
7087
+ );
7088
+ const handleClaimSuccess = useCallback(
7089
+ async (taskId) => {
7090
+ if (!client) {
7091
+ return;
7092
+ }
7093
+ if (typeof taskId !== "number") {
7094
+ await refreshTaskList();
7095
+ return;
7096
+ }
7097
+ await refreshSingleTask(taskId);
7098
+ const dependentTasks = taskDependencyIndex.get(taskId);
7099
+ if (dependentTasks && dependentTasks.size > 0) {
7100
+ await refreshTaskList();
7101
+ }
7102
+ },
7103
+ [client, refreshSingleTask, refreshTaskList, taskDependencyIndex]
7104
+ );
6830
7105
  const { toast } = useToast();
6831
- const handleClaimTask = useCallback(async (taskId, token, platform) => {
6832
- if (!client) return { successful: false };
6833
- try {
6834
- const api = createCommunityTaskApi(client);
6835
- const result = await api.submitTask({
6836
- task_id: taskId,
6837
- task_value: token || ""
6838
- });
6839
- if (result.successful) {
6840
- await handleClaimSuccess(taskId);
6841
- return { successful: true };
6842
- } else if (result.cool_down) {
6843
- updateCoolDown(taskId, result.cool_down);
6844
- return { successful: false, cool_down: result.cool_down };
6845
- } else {
6846
- if (platform === "Twitter") {
6847
- toast.error("Oops! Task verification failed. There might be a delay due to Twitter restrictions. Please try again later.");
6848
- } else if (platform === "Discord") {
6849
- toast.error("Oops! Task verification failed. There might be a delay due to Discord restrictions. Please try again later.");
6850
- } else if (platform === "Telegram") {
6851
- toast.error("Oops! Task verification failed. There might be a delay due to Telegram restrictions. Please try again later.");
7106
+ const handleClaimTask = useCallback(
7107
+ async (taskId, token, platform) => {
7108
+ if (!client) return { successful: false };
7109
+ try {
7110
+ const api = createCommunityTaskApi(client);
7111
+ const result = await api.submitTask({
7112
+ task_id: taskId,
7113
+ task_value: token || ""
7114
+ });
7115
+ if (result.successful) {
7116
+ await handleClaimSuccess(taskId);
7117
+ return { successful: true };
7118
+ } else if (result.cool_down) {
7119
+ updateCoolDown(taskId, result.cool_down);
7120
+ return { successful: false, cool_down: result.cool_down };
6852
7121
  } else {
6853
- toast.error("Task verification failed. Please check if you completed the required action.");
7122
+ if (platform === "Twitter") {
7123
+ toast.error(t("verification_failed_twitter"));
7124
+ } else if (platform === "Discord") {
7125
+ toast.error(t("verification_failed_discord"));
7126
+ } else if (platform === "Telegram") {
7127
+ toast.error(t("verification_failed_telegram"));
7128
+ } else {
7129
+ toast.error(t("verification_failed_generic"));
7130
+ }
7131
+ return { successful: false };
6854
7132
  }
6855
- return { successful: false };
6856
- }
6857
- } catch (err) {
6858
- console.error("Failed to submit task:", err);
6859
- const errorCode = err instanceof ApiError ? err.code : void 0;
6860
- const errorMessage = resolveCommunityTaskSubmitErrorMessage(err, errorCode);
6861
- const errorData = err instanceof ApiError ? err.data : void 0;
6862
- if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
6863
- return { successful: false, errorCode };
6864
- }
6865
- if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
6866
- const { invited = 0, min_required = 0 } = errorData;
6867
- toast.error(`You have invited ${invited} users, but need ${min_required - invited} more to complete this task.`);
7133
+ } catch (err) {
7134
+ console.error("Failed to submit task:", err);
7135
+ const apiError = err;
7136
+ const errorCode = apiError == null ? void 0 : apiError.code;
7137
+ const errorMessage = resolveCommunityTaskSubmitErrorMessage(err, {
7138
+ errorCode,
7139
+ t
7140
+ });
7141
+ const errorData = apiError == null ? void 0 : apiError.data;
7142
+ if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
7143
+ return { successful: false, errorCode };
7144
+ }
7145
+ if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
7146
+ const { invited = 0, min_required = 0 } = errorData;
7147
+ toast.error(
7148
+ t("discord_invites_err", {
7149
+ invited,
7150
+ need: Math.max(min_required - invited, 0)
7151
+ })
7152
+ );
7153
+ return { successful: false, errorCode };
7154
+ }
7155
+ toast.error(errorMessage);
6868
7156
  return { successful: false, errorCode };
6869
7157
  }
6870
- toast.error(errorMessage);
6871
- return { successful: false, errorCode };
6872
- }
6873
- }, [client, handleClaimSuccess, toast, updateCoolDown]);
7158
+ },
7159
+ [client, handleClaimSuccess, toast, updateCoolDown, t]
7160
+ );
6874
7161
  const isDialogOpen = openTask !== null || openTaskId !== null;
6875
7162
  const currentSelectorValue = selectedSectorId ?? void 0;
6876
- if (error) {
6877
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-error", children: [
6878
- "Error: ",
6879
- error
6880
- ] }) });
7163
+ if (error2) {
7164
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsx("div", { className: "taskon-community-list-error", children: error2 }) });
6881
7165
  }
6882
7166
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-list", children: [
6883
7167
  showSectorTab && !isLoading && /* @__PURE__ */ jsx(
@@ -6898,7 +7182,7 @@ function CommunityTaskListInner(props) {
6898
7182
  showSectorDescription,
6899
7183
  showSectorReward
6900
7184
  }
6901
- ) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: "No tasks available" }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
7185
+ ) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: t("no_tasks_available") }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
6902
7186
  SectorItem,
6903
7187
  {
6904
7188
  sector: sectorItem,