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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/dist/CommunityTaskList.css +1340 -1292
  3. package/dist/EligibilityInfo.css +512 -332
  4. package/dist/LeaderboardWidget.css +355 -152
  5. package/dist/Quest.css +911 -629
  6. package/dist/TaskOnProvider.css +35 -16
  7. package/dist/UserCenterWidget.css +116 -71
  8. package/dist/UserCenterWidget2.css +1285 -748
  9. package/dist/chunks/{CommunityTaskList-C9mPl_31.js → CommunityTaskList-CrMvOB8w.js} +784 -452
  10. package/dist/chunks/{EligibilityInfo-DGBffKN8.js → EligibilityInfo-Beww12QX.js} +1569 -597
  11. package/dist/chunks/{LeaderboardWidget-DPOQVXkT.js → LeaderboardWidget-DwuSpVl0.js} +2 -2
  12. package/dist/chunks/{PageBuilder-WCZvxL2j.js → PageBuilder-DsX6Tv0N.js} +5 -5
  13. package/dist/chunks/{Quest-DjGH_8bx.js → Quest-CuD2LElS.js} +713 -484
  14. package/dist/chunks/{TaskOnProvider-iannERG1.js → TaskOnProvider-xUeP2Nro.js} +78 -65
  15. package/dist/chunks/{ThemeProvider-DNJqI2lD.js → ThemeProvider-Bt4UZ33y.js} +33 -9
  16. package/dist/chunks/{UserCenterWidget-CAhgp46j.js → UserCenterWidget-CB0hnj-L.js} +69 -31
  17. package/dist/chunks/{UserCenterWidget-B0O-f_xl.js → UserCenterWidget-CvU6K4AC.js} +21 -7
  18. package/dist/chunks/communitytask-es-1zawvXEX.js +311 -0
  19. package/dist/chunks/communitytask-ja-CmW6nP-L.js +311 -0
  20. package/dist/chunks/communitytask-ko-BD0hzQSi.js +311 -0
  21. package/dist/chunks/communitytask-ru-DhySaZL8.js +311 -0
  22. package/dist/chunks/createLocaleLoader-BameiEhU.js +65 -0
  23. package/dist/chunks/{dynamic-import-helper-B2j_dZ4V.js → dynamic-import-helper-WmIF58Sb.js} +1 -1
  24. package/dist/chunks/quest-es-D-b5xcme.js +948 -0
  25. package/dist/chunks/quest-ja-Dxd2vqBF.js +948 -0
  26. package/dist/chunks/quest-ko-CSmRWgK_.js +948 -0
  27. package/dist/chunks/quest-ru-CkEKv1_F.js +948 -0
  28. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  29. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  30. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  31. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  32. package/dist/community-task.js +1 -1
  33. package/dist/core.d.ts +17 -5
  34. package/dist/core.js +8 -7
  35. package/dist/dynamic-import-helper.css +424 -303
  36. package/dist/index.d.ts +56 -5
  37. package/dist/index.js +18 -16
  38. package/dist/leaderboard.js +2 -2
  39. package/dist/page-builder.js +1 -1
  40. package/dist/quest.d.ts +682 -0
  41. package/dist/quest.js +3 -1
  42. package/dist/user-center.d.ts +3 -1
  43. package/dist/user-center.js +5 -5
  44. package/package.json +7 -1
@@ -1,11 +1,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-DNJqI2lD.js";
5
- import { D as Dialog, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-B2j_dZ4V.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-DGBffKN8.js";
8
- import { g as useBindSocialAccount, B as BindWalletDialog, l as useChainMap, s as TipPopover, I as Input } from "./UserCenterWidget-B0O-f_xl.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]
@@ -3510,17 +3763,6 @@ function getExpectedRewardDisplay(reward) {
3510
3763
  }
3511
3764
  return { icon: "", text: "", colorClass: "" };
3512
3765
  }
3513
- function useIsMobile() {
3514
- const [isMobile, setIsMobile] = useState(false);
3515
- useEffect(() => {
3516
- const mql = window.matchMedia("(max-width: 750px)");
3517
- setIsMobile(mql.matches);
3518
- const handler = (e) => setIsMobile(e.matches);
3519
- mql.addEventListener("change", handler);
3520
- return () => mql.removeEventListener("change", handler);
3521
- }, []);
3522
- return isMobile;
3523
- }
3524
3766
  function TaskChainRewardStep({
3525
3767
  campaignId,
3526
3768
  campaign,
@@ -3601,8 +3843,8 @@ function TaskChainRewardStep({
3601
3843
  });
3602
3844
  await refetchUserStatus();
3603
3845
  await switchToClaimedView();
3604
- } catch (error) {
3605
- console.error("Failed to claim reward:", error);
3846
+ } catch (error2) {
3847
+ console.error("Failed to claim reward:", error2);
3606
3848
  toast.error("Failed to submit campaign. Please try again.");
3607
3849
  } finally {
3608
3850
  setIsLoading(false);
@@ -3816,8 +4058,8 @@ function TaskChainBlindBoxStep({
3816
4058
  auto_follow_community: false
3817
4059
  });
3818
4060
  await refetchUserStatus();
3819
- } catch (error) {
3820
- console.error("Failed to submit campaign:", error);
4061
+ } catch (error2) {
4062
+ console.error("Failed to submit campaign:", error2);
3821
4063
  toast.error("Failed to submit campaign. Please try again.");
3822
4064
  setShowManualSubmit(true);
3823
4065
  } finally {
@@ -3837,8 +4079,8 @@ function TaskChainBlindBoxStep({
3837
4079
  }
3838
4080
  await api.claimBlindBoxRewards({ campaign_id: campaign.id });
3839
4081
  await refetchUserStatus();
3840
- } catch (error) {
3841
- console.error("Failed to claim blind box:", error);
4082
+ } catch (error2) {
4083
+ console.error("Failed to claim blind box:", error2);
3842
4084
  toast.error("Failed to claim reward. Please try again.");
3843
4085
  (_a = blindBoxDialogRef.current) == null ? void 0 : _a.resetToUnopened();
3844
4086
  } finally {
@@ -4011,8 +4253,8 @@ function NotEligible({
4011
4253
  if (refetchUserStatus) {
4012
4254
  await refetchUserStatus();
4013
4255
  }
4014
- } catch (error) {
4015
- console.error("Failed to check eligibility:", error);
4256
+ } catch (error2) {
4257
+ console.error("Failed to check eligibility:", error2);
4016
4258
  } finally {
4017
4259
  setIsRefreshing(false);
4018
4260
  }
@@ -4228,8 +4470,8 @@ function TaskChainDetail({
4228
4470
  const api = createQuestApi(client);
4229
4471
  await api.checkUserCampaignEligibility({ campaign_id: campaign.id });
4230
4472
  await refetchUserStatus();
4231
- } catch (error) {
4232
- console.error("Failed to check eligibility after login:", error);
4473
+ } catch (error2) {
4474
+ console.error("Failed to check eligibility after login:", error2);
4233
4475
  }
4234
4476
  };
4235
4477
  checkEligibility();
@@ -4468,7 +4710,7 @@ function TaskChainDialog({
4468
4710
  userStatus,
4469
4711
  campaignStatusInfo,
4470
4712
  isLoading,
4471
- error,
4713
+ error: error2,
4472
4714
  refetchUserStatus
4473
4715
  } = useTaskChainDetail({
4474
4716
  campaignId,
@@ -4525,11 +4767,11 @@ function TaskChainDialog({
4525
4767
  }
4526
4768
  }, [(_b = userStatus == null ? void 0 : userStatus.user_status) == null ? void 0 : _b.is_winner, onUpdate]);
4527
4769
  return /* @__PURE__ */ jsx(BottomDialog, { open, onClose, top: "6vh", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-content", children: [
4528
- error && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4770
+ error2 && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4529
4771
  /* @__PURE__ */ jsx("div", { children: "Failed to load task chain" }),
4530
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error })
4772
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error2 })
4531
4773
  ] }),
4532
- !error && /* @__PURE__ */ jsx(
4774
+ !error2 && /* @__PURE__ */ jsx(
4533
4775
  TaskChainDetail,
4534
4776
  {
4535
4777
  campaign,
@@ -4564,6 +4806,7 @@ function SectorItemComponent({
4564
4806
  onCoolDownComplete,
4565
4807
  onDoneCountdownComplete
4566
4808
  }) {
4809
+ const { t } = useCommunityTaskLocale();
4567
4810
  const hasPeriodicTask = useMemo(() => {
4568
4811
  return sector.cards.some((card) => {
4569
4812
  if (card.card_type !== TaskCardType.GTCTask) return false;
@@ -4646,7 +4889,7 @@ function SectorItemComponent({
4646
4889
  return null;
4647
4890
  }) }),
4648
4891
  completedCards.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
4649
- /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: "🎉 You have completed" }),
4892
+ /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: t("you_have_completed") }),
4650
4893
  /* @__PURE__ */ jsx("div", { className: "taskon-sector-tasks taskon-sector-tasks-completed", children: completedCards.map((card) => {
4651
4894
  const key = getCardKey(card);
4652
4895
  if (card.card_type === TaskCardType.TaskChain) {
@@ -4683,15 +4926,56 @@ function SectorItemComponent({
4683
4926
  ] });
4684
4927
  }
4685
4928
  const SectorItem = React__default.memo(SectorItemComponent);
4686
- const RECURRENCE_LABEL_MAP = {
4687
- Once: "Once",
4688
- Daily: "Daily",
4689
- Weekly: "Weekly",
4690
- Monthly: "Monthly",
4691
- Unlimited: "Unlimited"
4692
- };
4693
- function getRecurrenceLabel(recurrence) {
4694
- return RECURRENCE_LABEL_MAP[recurrence || "Once"] || "Once";
4929
+ function renderTaskCards(count) {
4930
+ return Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx(
4931
+ "div",
4932
+ {
4933
+ className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-task"
4934
+ },
4935
+ `task-${index}`
4936
+ ));
4937
+ }
4938
+ function CommunityTaskListSkeleton({
4939
+ showSectorTab = true,
4940
+ showSectorName = true,
4941
+ showSectorDescription = true,
4942
+ showSectorReward = true
4943
+ }) {
4944
+ return /* @__PURE__ */ jsxs(
4945
+ "div",
4946
+ {
4947
+ className: "taskon-community-list-skeleton",
4948
+ "aria-busy": "true",
4949
+ "aria-label": "Loading tasks",
4950
+ children: [
4951
+ showSectorTab && /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-selector", children: [
4952
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-chip taskon-community-list-skeleton-chip--wide" }),
4953
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-chip" }),
4954
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-chip" })
4955
+ ] }),
4956
+ /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-content", children: [
4957
+ /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-sector", children: [
4958
+ showSectorName && /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-title" }),
4959
+ showSectorDescription && /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-lines", children: [
4960
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-line" }),
4961
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-line taskon-community-list-skeleton-line--short" })
4962
+ ] }),
4963
+ showSectorReward && /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-points", children: [
4964
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-pill" }),
4965
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-pill taskon-community-list-skeleton-pill--short" })
4966
+ ] }),
4967
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-tasks", children: renderTaskCards(4) })
4968
+ ] }),
4969
+ /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-skeleton-sector", children: [
4970
+ showSectorName && /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-title taskon-community-list-skeleton-title--second" }),
4971
+ showSectorDescription && /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-lines", children: /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-line" }) }),
4972
+ showSectorReward && /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-points", children: /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-block taskon-community-list-skeleton-pill taskon-community-list-skeleton-pill--short" }) }),
4973
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-skeleton-tasks", children: renderTaskCards(3) })
4974
+ ] })
4975
+ ] })
4976
+ ]
4977
+ }
4978
+ );
4695
4979
  }
4696
4980
  function DialogPointReward({
4697
4981
  isPeriodic,
@@ -4702,6 +4986,7 @@ function DialogPointReward({
4702
4986
  totalEarned = 0,
4703
4987
  communityInfo
4704
4988
  }) {
4989
+ const { t } = useCommunityTaskLocale();
4705
4990
  const displayAmount = useMemo(() => {
4706
4991
  if (recurrence === RecurrenceType.Unlimited) {
4707
4992
  if (totalEarned) {
@@ -4728,13 +5013,15 @@ function DialogPointReward({
4728
5013
  ] }),
4729
5014
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label", children: [
4730
5015
  name,
4731
- " /Time"
5016
+ " ",
5017
+ t("per_time")
4732
5018
  ] })
4733
5019
  ] }),
4734
5020
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount taskon-task-dialog-period-amount--em", children: totalEarned || 0 }),
4735
5021
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label taskon-task-dialog-period-label--em", children: [
4736
5022
  name,
4737
- " earned"
5023
+ " ",
5024
+ t("earned")
4738
5025
  ] })
4739
5026
  ] });
4740
5027
  }
@@ -4787,6 +5074,7 @@ function DialogTokenReward({
4787
5074
  chainIcon,
4788
5075
  communityInfo
4789
5076
  }) {
5077
+ const { t } = useCommunityTaskLocale();
4790
5078
  if (isPeriodic) {
4791
5079
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period", children: [
4792
5080
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount", children: amount }),
@@ -4802,7 +5090,7 @@ function DialogTokenReward({
4802
5090
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-period-label", children: name }),
4803
5091
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-period-label taskon-task-dialog-token-period-label--em", children: [
4804
5092
  " ",
4805
- "earned"
5093
+ t("earned")
4806
5094
  ] })
4807
5095
  ] })
4808
5096
  ] });
@@ -4873,18 +5161,13 @@ function TokenStatusLeft({
4873
5161
  totalUnit,
4874
5162
  availableUnit
4875
5163
  }) {
5164
+ const { t } = useCommunityTaskLocale();
4876
5165
  const current = useMemo(
4877
5166
  () => calcCurrent(totalUnit, availableUnit),
4878
5167
  [totalUnit, availableUnit]
4879
5168
  );
4880
5169
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress", children: [
4881
- /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress__content", children: [
4882
- "Hurry up! Only",
4883
- " ",
4884
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-token-progress__text", children: availableUnit ?? 0 }),
4885
- " ",
4886
- "left"
4887
- ] }),
5170
+ /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__content", children: t("only_left", { val: availableUnit ?? 0 }) }),
4888
5171
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__bar", children: /* @__PURE__ */ jsx(ColorfulProgress, { current, total: String(totalUnit) }) })
4889
5172
  ] });
4890
5173
  }
@@ -4899,17 +5182,11 @@ function formatDateTime(timestamp) {
4899
5182
  }
4900
5183
  function formatCountdown(diff) {
4901
5184
  if (diff <= 0) return "00:00:00";
4902
- if (diff / (1e3 * 60 * 60) > 24) {
4903
- const day2 = 24 * 60 * 60 * 1e3;
4904
- const days = Math.ceil(diff / day2);
4905
- return `${days} day${days > 1 ? "s" : ""}`;
4906
- }
4907
- const day = 24 * 60 * 60 * 1e3;
4908
5185
  const hour = 60 * 60 * 1e3;
4909
5186
  const minute = 60 * 1e3;
4910
5187
  const second = 1e3;
4911
5188
  const normalizedDiff = Math.abs(diff);
4912
- const hours = Math.floor(normalizedDiff % day / hour);
5189
+ const hours = Math.floor(normalizedDiff / hour);
4913
5190
  const minutes = Math.floor(normalizedDiff % hour / minute);
4914
5191
  const seconds = Math.floor(normalizedDiff % minute / second);
4915
5192
  const prefix2 = (n) => String(n).padStart(2, "0");
@@ -4937,6 +5214,7 @@ function DialogRewardCard({
4937
5214
  communityInfo,
4938
5215
  latestSubmittedTime = 0
4939
5216
  }) {
5217
+ const { t } = useCommunityTaskLocale();
4940
5218
  const { chains } = useTaskOnContext();
4941
5219
  const tokenChainIcon = useMemo(() => {
4942
5220
  var _a;
@@ -4963,21 +5241,18 @@ function DialogRewardCard({
4963
5241
  const renderPeriodicCountdown = useCallback(() => {
4964
5242
  if (!showPeriodicCountdown) return null;
4965
5243
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-periodic-done", children: [
4966
- /* @__PURE__ */ jsx("span", { children: "Done for today" }),
5244
+ /* @__PURE__ */ jsx("span", { children: t("done_today") }),
4967
5245
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__line" }),
4968
- /* @__PURE__ */ jsx("span", { children: "Continue in" }),
5246
+ /* @__PURE__ */ jsx("span", { children: t("continue_in") }),
4969
5247
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__time", children: countdownLabel })
4970
5248
  ] });
4971
- }, [showPeriodicCountdown, countdownLabel]);
5249
+ }, [showPeriodicCountdown, countdownLabel, t]);
4972
5250
  const renderDefaultStatus = () => {
4973
5251
  if (recurrence === RecurrenceType.Unlimited && latestSubmittedTime && latestSubmittedTime > 0) {
4974
- return /* @__PURE__ */ jsxs("span", { className: "taskon-task-dialog-updated", children: [
4975
- "Updated at ",
4976
- formatDateTime(latestSubmittedTime)
4977
- ] });
5252
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-updated", children: t("updated_at", { val: formatDateTime(latestSubmittedTime) }) });
4978
5253
  }
4979
5254
  if (isWon) {
4980
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
5255
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
4981
5256
  }
4982
5257
  return null;
4983
5258
  };
@@ -4990,7 +5265,7 @@ function DialogRewardCard({
4990
5265
  isPeriodic,
4991
5266
  recurrence,
4992
5267
  amount: reward.amount ?? 0,
4993
- name: reward.name ?? "Points",
5268
+ name: reward.name ?? t("community_points"),
4994
5269
  icon: reward.icon,
4995
5270
  totalEarned,
4996
5271
  communityInfo
@@ -5048,12 +5323,12 @@ function DialogRewardCard({
5048
5323
  const statusNode = showPeriodicCountdown ? renderPeriodicCountdown() : renderStatus ? renderStatus() : renderDefaultStatus();
5049
5324
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-reward-card", children: [
5050
5325
  claimLimit > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-max-claim", children: [
5051
- "Max. Claims",
5326
+ t("max_claim_num"),
5052
5327
  " ",
5053
5328
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-max-claim--highlight", children: claimLimit })
5054
5329
  ] }),
5055
5330
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-row", children: [
5056
- /* @__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") }),
5057
5332
  (statusPrefixNode || statusNode) && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-right", children: [
5058
5333
  statusPrefixNode,
5059
5334
  statusNode
@@ -5069,6 +5344,7 @@ function CloseIn({
5069
5344
  onClose
5070
5345
  }) {
5071
5346
  const [countdown, setCountdown] = useState(seconds);
5347
+ const { t } = useCommunityTaskLocale();
5072
5348
  const timerRef = useRef(null);
5073
5349
  const handleClose = useCallback(() => {
5074
5350
  onClose();
@@ -5094,11 +5370,7 @@ function CloseIn({
5094
5370
  }
5095
5371
  };
5096
5372
  }, [handleClose]);
5097
- return /* @__PURE__ */ jsxs("div", { className: "taskon-close-in", children: [
5098
- "Closing in ",
5099
- countdown,
5100
- "s"
5101
- ] });
5373
+ return /* @__PURE__ */ jsx("div", { className: "taskon-close-in", children: t("close_in", { val: countdown }) });
5102
5374
  }
5103
5375
  function BaseDialogLayout({
5104
5376
  recurrence,
@@ -5135,7 +5407,8 @@ function BaseDialogLayout({
5135
5407
  onCloseInClose
5136
5408
  }) {
5137
5409
  var _a;
5138
- const recurrenceLabel = getRecurrenceLabel(recurrence);
5410
+ const { t } = useCommunityTaskLocale();
5411
+ const recurrenceLabel = getRecurrenceLabel(t, recurrence);
5139
5412
  const shouldShowEligibilityMask = Boolean(
5140
5413
  ((_a = eligibilityTask == null ? void 0 : eligibilityTask.eligiblity) == null ? void 0 : _a.length) && (eligibilityConditions == null ? void 0 : eligibilityConditions.length)
5141
5414
  );
@@ -5149,7 +5422,7 @@ function BaseDialogLayout({
5149
5422
  ] }) });
5150
5423
  }
5151
5424
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-valid-time", children: [
5152
- /* @__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") }),
5153
5426
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-value", children: validTime.endTime })
5154
5427
  ] });
5155
5428
  };
@@ -5228,6 +5501,7 @@ function TemplateDialogContent({
5228
5501
  }) {
5229
5502
  var _a, _b, _c, _d;
5230
5503
  const userStatus = task.user_status;
5504
+ const { t } = useCommunityTaskLocale();
5231
5505
  const { showToast } = useToast();
5232
5506
  const { getChainType } = useChainMap();
5233
5507
  const { communityInfo } = useTaskOnContext();
@@ -5251,7 +5525,7 @@ function TemplateDialogContent({
5251
5525
  );
5252
5526
  const coolDown = sharedCoolDown ?? localCoolDown;
5253
5527
  const taskTitle = useMemo(() => {
5254
- if (!info) return "Task";
5528
+ if (!info) return t("task_up");
5255
5529
  const { template, name } = info;
5256
5530
  if (name !== template.template_name) {
5257
5531
  return name;
@@ -5263,7 +5537,7 @@ function TemplateDialogContent({
5263
5537
  return null;
5264
5538
  }
5265
5539
  return name;
5266
- }, [info, params.custom_title, params.title_express]);
5540
+ }, [info, params.custom_title, params.title_express, t]);
5267
5541
  const titleContent = useMemo(() => {
5268
5542
  if (taskTitle) return taskTitle;
5269
5543
  if (params.title_express) {
@@ -5274,8 +5548,8 @@ function TemplateDialogContent({
5274
5548
  }
5275
5549
  );
5276
5550
  }
5277
- return (info == null ? void 0 : info.name) || "Task";
5278
- }, [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]);
5279
5553
  const validationTimeFrame = useMemo(() => {
5280
5554
  if (!(info == null ? void 0 : info.template)) return void 0;
5281
5555
  const { class_type, is_hold } = info.template;
@@ -5311,8 +5585,8 @@ function TemplateDialogContent({
5311
5585
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5312
5586
  }, [sharedOnCoolDownComplete]);
5313
5587
  const handleBindFailed = useCallback(
5314
- (error) => {
5315
- showToast(error, "error");
5588
+ (error2) => {
5589
+ showToast(error2, "error");
5316
5590
  },
5317
5591
  [showToast]
5318
5592
  );
@@ -5339,7 +5613,7 @@ function TemplateDialogContent({
5339
5613
  }
5340
5614
  }, [params.action_link, params.action_auto_verify, params.is_link_task, handleClaim]);
5341
5615
  if (!info) {
5342
- 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") });
5343
5617
  }
5344
5618
  return /* @__PURE__ */ jsxs(
5345
5619
  BaseDialogLayout,
@@ -5413,6 +5687,7 @@ function PowImageUploader({
5413
5687
  onConfirmed,
5414
5688
  onError
5415
5689
  }) {
5690
+ const { t } = useCommunityTaskLocale();
5416
5691
  const [previewUrl, setPreviewUrl] = useState(defaultUrl);
5417
5692
  const [file, setFile] = useState(null);
5418
5693
  const [progress, setProgress] = useState(0);
@@ -5433,7 +5708,7 @@ function PowImageUploader({
5433
5708
  const selectedFile = (_a = event.target.files) == null ? void 0 : _a[0];
5434
5709
  if (!selectedFile) return;
5435
5710
  if (selectedFile.size > MAX_FILE_SIZE) {
5436
- onError == null ? void 0 : onError("Image size exceeds 10MB limit");
5711
+ onError == null ? void 0 : onError(t("invalid_image_size_10m"));
5437
5712
  return;
5438
5713
  }
5439
5714
  setFile(selectedFile);
@@ -5446,12 +5721,12 @@ function PowImageUploader({
5446
5721
  reader.readAsDataURL(selectedFile);
5447
5722
  await uploadFile(selectedFile);
5448
5723
  },
5449
- [onError]
5724
+ [onError, t]
5450
5725
  );
5451
5726
  const uploadFile = useCallback(
5452
5727
  async (fileToUpload) => {
5453
5728
  if (!client) {
5454
- onError == null ? void 0 : onError("Client not initialized");
5729
+ onError == null ? void 0 : onError(t("client_not_initialized"));
5455
5730
  return;
5456
5731
  }
5457
5732
  try {
@@ -5474,17 +5749,17 @@ function PowImageUploader({
5474
5749
  );
5475
5750
  abortControllerRef.current = null;
5476
5751
  onConfirmed(result.cdn_url);
5477
- } catch (error) {
5478
- if (error instanceof DOMException && error.name === "AbortError") {
5752
+ } catch (error2) {
5753
+ if (error2 instanceof DOMException && error2.name === "AbortError") {
5479
5754
  return;
5480
5755
  }
5481
- const message = error instanceof Error ? error.message : "Upload failed";
5756
+ const message = error2 instanceof Error ? error2.message : t("upload_failed");
5482
5757
  onError == null ? void 0 : onError(message);
5483
5758
  } finally {
5484
5759
  setIsUploading(false);
5485
5760
  }
5486
5761
  },
5487
- [client, onConfirmed, onError]
5762
+ [client, onConfirmed, onError, t]
5488
5763
  );
5489
5764
  const handleClick = useCallback(() => {
5490
5765
  var _a;
@@ -5508,7 +5783,7 @@ function PowImageUploader({
5508
5783
  onKeyDown: handleKeyDown,
5509
5784
  role: "button",
5510
5785
  tabIndex: disabled ? -1 : 0,
5511
- "aria-label": "Upload image",
5786
+ "aria-label": t("upload_image"),
5512
5787
  "aria-disabled": disabled,
5513
5788
  children: [
5514
5789
  /* @__PURE__ */ jsx(
@@ -5527,7 +5802,7 @@ function PowImageUploader({
5527
5802
  "img",
5528
5803
  {
5529
5804
  src: previewUrl,
5530
- alt: "Preview",
5805
+ alt: t("upload_image"),
5531
5806
  className: "taskon-pow-uploader-preview"
5532
5807
  }
5533
5808
  ),
@@ -5561,7 +5836,7 @@ function PowImageUploader({
5561
5836
  ]
5562
5837
  }
5563
5838
  ),
5564
- /* @__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") })
5565
5840
  ] })
5566
5841
  ] }) : (
5567
5842
  /* 无预览时显示上传提示 */
@@ -5595,7 +5870,7 @@ function PowImageUploader({
5595
5870
  ]
5596
5871
  }
5597
5872
  ),
5598
- /* @__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") })
5599
5874
  ] })
5600
5875
  ),
5601
5876
  isUploading && /* @__PURE__ */ jsx("div", { className: "taskon-pow-uploader-progress", children: /* @__PURE__ */ jsx(
@@ -5628,6 +5903,7 @@ function PowTaskDialogContent({
5628
5903
  }) {
5629
5904
  var _a, _b, _c;
5630
5905
  const userStatus = task.user_status;
5906
+ const { t } = useCommunityTaskLocale();
5631
5907
  const { toast } = useToast();
5632
5908
  const { communityInfo } = useTaskOnContext();
5633
5909
  const totalEarned = ((_a = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a.amount) ?? 0;
@@ -5657,7 +5933,7 @@ function PowTaskDialogContent({
5657
5933
  const validateInput = useCallback(() => {
5658
5934
  if (params.type === "Image") {
5659
5935
  if (!answer.trim()) {
5660
- setInputError("Please upload an image");
5936
+ setInputError(t("please_upload_image"));
5661
5937
  return false;
5662
5938
  }
5663
5939
  setInputError(null);
@@ -5665,7 +5941,7 @@ function PowTaskDialogContent({
5665
5941
  }
5666
5942
  if (!answer.trim()) {
5667
5943
  setInputError(
5668
- params.type === "URL" ? "Please enter URL" : "Please enter text"
5944
+ params.type === "URL" ? t("please_enter_url") : t("please_enter_text")
5669
5945
  );
5670
5946
  return false;
5671
5947
  }
@@ -5673,24 +5949,24 @@ function PowTaskDialogContent({
5673
5949
  try {
5674
5950
  new URL(answer);
5675
5951
  } catch {
5676
- setInputError("Please enter a valid url address");
5952
+ setInputError(t("invalid_url"));
5677
5953
  return false;
5678
5954
  }
5679
5955
  }
5680
5956
  setInputError(null);
5681
5957
  return true;
5682
- }, [answer, params.type]);
5958
+ }, [answer, params.type, t]);
5683
5959
  const handleSubmit = useCallback(async () => {
5684
5960
  if (!validateInput()) return;
5685
5961
  await submitTask(answer);
5686
5962
  }, [validateInput, submitTask, answer]);
5687
5963
  const handleResubmit = useCallback(async () => {
5688
5964
  if (!validateInput()) return;
5689
- const success = await submitTask(answer);
5690
- if (success) {
5691
- toast.success("Re-submitted successfully");
5965
+ const result = await submitTask(answer);
5966
+ if (result.successful) {
5967
+ toast.success(t("re_submitted_success"));
5692
5968
  }
5693
- }, [validateInput, submitTask, answer, toast]);
5969
+ }, [validateInput, submitTask, answer, toast, t]);
5694
5970
  const renderInputArea = () => {
5695
5971
  const powType = params.type || "Text";
5696
5972
  if (powType === "URL") {
@@ -5701,7 +5977,7 @@ function PowTaskDialogContent({
5701
5977
  type: "url",
5702
5978
  value: answer,
5703
5979
  onChange: setAnswer,
5704
- placeholder: "Please enter URL",
5980
+ placeholder: t("please_enter_url"),
5705
5981
  maxLength: 2e3,
5706
5982
  disabled: isInputDisabled,
5707
5983
  hasError: !!inputError,
@@ -5718,7 +5994,7 @@ function PowTaskDialogContent({
5718
5994
  {
5719
5995
  value: answer,
5720
5996
  onChange: setAnswer,
5721
- placeholder: "Enter here",
5997
+ placeholder: t("enter_here"),
5722
5998
  maxLength: 500,
5723
5999
  showCount: true,
5724
6000
  disabled: isInputDisabled,
@@ -5740,8 +6016,8 @@ function PowTaskDialogContent({
5740
6016
  setAnswer(url);
5741
6017
  setInputError(null);
5742
6018
  },
5743
- onError: (error) => {
5744
- setInputError(error);
6019
+ onError: (error2) => {
6020
+ setInputError(error2);
5745
6021
  }
5746
6022
  }
5747
6023
  ),
@@ -5750,7 +6026,10 @@ function PowTaskDialogContent({
5750
6026
  };
5751
6027
  const renderActionButton = () => {
5752
6028
  if (state.isWon) {
5753
- 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
+ ] });
5754
6033
  }
5755
6034
  if (isUnderReview || isFailedButCanRetry) {
5756
6035
  return /* @__PURE__ */ jsx(
@@ -5760,7 +6039,7 @@ function PowTaskDialogContent({
5760
6039
  className: "taskon-pow-dialog-submit",
5761
6040
  onClick: handleResubmit,
5762
6041
  disabled: isSubmitting,
5763
- children: isSubmitting ? "Submitting..." : "Re-submit"
6042
+ children: isSubmitting ? t("submitting") : t("resubmit")
5764
6043
  }
5765
6044
  );
5766
6045
  }
@@ -5772,7 +6051,7 @@ function PowTaskDialogContent({
5772
6051
  className: "taskon-pow-dialog-submit",
5773
6052
  onClick: handleSubmit,
5774
6053
  disabled: isSubmitting,
5775
- children: isSubmitting ? "Submitting..." : "Submit"
6054
+ children: isSubmitting ? t("submitting") : t("submit")
5776
6055
  }
5777
6056
  );
5778
6057
  }
@@ -5780,18 +6059,18 @@ function PowTaskDialogContent({
5780
6059
  };
5781
6060
  const renderReviewStatus = useCallback(() => {
5782
6061
  if (state.isWon) {
5783
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
6062
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
5784
6063
  }
5785
6064
  if (isUnderReview) {
5786
- 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") });
5787
6066
  }
5788
6067
  if ((userStatus == null ? void 0 : userStatus.review_result) === TaskReviewResult.Failed) {
5789
- 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") });
5790
6069
  }
5791
6070
  return null;
5792
- }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result]);
6071
+ }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result, t]);
5793
6072
  if (!info) {
5794
- 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") });
5795
6074
  }
5796
6075
  return /* @__PURE__ */ jsxs(
5797
6076
  BaseDialogLayout,
@@ -5847,6 +6126,7 @@ function ContractInteractiveDialogContent({
5847
6126
  }) {
5848
6127
  var _a, _b, _c;
5849
6128
  const userStatus = task.user_status;
6129
+ const { t } = useCommunityTaskLocale();
5850
6130
  const { showToast } = useToast();
5851
6131
  const { getChainType } = useChainMap();
5852
6132
  const { communityInfo } = useTaskOnContext();
@@ -5907,8 +6187,8 @@ function ContractInteractiveDialogContent({
5907
6187
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5908
6188
  }, [sharedOnCoolDownComplete]);
5909
6189
  const handleBindFailed = useCallback(
5910
- (error) => {
5911
- showToast(error, "error");
6190
+ (error2) => {
6191
+ showToast(error2, "error");
5912
6192
  },
5913
6193
  [showToast]
5914
6194
  );
@@ -5922,7 +6202,7 @@ function ContractInteractiveDialogContent({
5922
6202
  }
5923
6203
  }, [params.task_url]);
5924
6204
  if (!info) {
5925
- 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") });
5926
6206
  }
5927
6207
  return /* @__PURE__ */ jsxs(
5928
6208
  BaseDialogLayout,
@@ -5954,13 +6234,16 @@ function ContractInteractiveDialogContent({
5954
6234
  children: [
5955
6235
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
5956
6236
  params.desc && /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) }),
5957
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6237
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
5958
6238
  "button",
5959
6239
  {
5960
6240
  type: "button",
5961
6241
  className: "taskon-task-dialog-action",
5962
6242
  onClick: handleAction,
5963
- children: "👉 Proceed to complete the task"
6243
+ children: [
6244
+ "👉 ",
6245
+ t("proceed_2_complete_the_task")
6246
+ ]
5964
6247
  }
5965
6248
  )
5966
6249
  ]
@@ -5990,6 +6273,7 @@ function SwapDexDialogContent({
5990
6273
  }) {
5991
6274
  var _a, _b, _c;
5992
6275
  const userStatus = task.user_status;
6276
+ const { t } = useCommunityTaskLocale();
5993
6277
  const { showToast } = useToast();
5994
6278
  const { getChainType, chainMap } = useChainMap();
5995
6279
  const { communityInfo } = useTaskOnContext();
@@ -6018,13 +6302,16 @@ function SwapDexDialogContent({
6018
6302
  );
6019
6303
  const coolDown = sharedCoolDown ?? localCoolDown;
6020
6304
  const isFixedRule = params.is_fixed_reward_type;
6021
- const rulePointName = reward.name || "Points";
6305
+ const rulePointName = reward.name || t("community_points");
6022
6306
  const ruleMaxText = useMemo(() => {
6023
6307
  if (typeof params.swap_receive_max_points === "number" && params.swap_receive_max_points >= 0) {
6024
- 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
+ });
6025
6312
  }
6026
6313
  return "";
6027
- }, [params.swap_receive_max_points, rulePointName]);
6314
+ }, [params.swap_receive_max_points, rulePointName, t]);
6028
6315
  const hasRulesText = useMemo(() => {
6029
6316
  return Boolean(params.each_trading_volume && params.each_receive_points);
6030
6317
  }, [params.each_trading_volume, params.each_receive_points]);
@@ -6038,13 +6325,13 @@ function SwapDexDialogContent({
6038
6325
  tokenOutList: params.token_out_list,
6039
6326
  tokenInList: params.token_in_list,
6040
6327
  chainLabel,
6041
- 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"),
6042
6329
  dexLink: params.task_url,
6043
6330
  isFixedReward: params.is_fixed_reward_type || false,
6044
6331
  minTradingVolume: params.min_trading_volume,
6045
6332
  minTradesTimes: params.min_trades_times
6046
6333
  });
6047
- }, [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]);
6048
6335
  const fromTokenDisplay = useMemo(
6049
6336
  () => formatSwapTokensForDisplay(params.token_out_list),
6050
6337
  [params.token_out_list]
@@ -6093,8 +6380,8 @@ function SwapDexDialogContent({
6093
6380
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
6094
6381
  }, [sharedOnCoolDownComplete]);
6095
6382
  const handleBindFailed = useCallback(
6096
- (error) => {
6097
- showToast(error, "error");
6383
+ (error2) => {
6384
+ showToast(error2, "error");
6098
6385
  },
6099
6386
  [showToast]
6100
6387
  );
@@ -6115,22 +6402,23 @@ function SwapDexDialogContent({
6115
6402
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-progress-separator", children: "/" }),
6116
6403
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-progress-total", children: [
6117
6404
  minTimes,
6118
- " Times"
6405
+ " ",
6406
+ t("times")
6119
6407
  ] })
6120
6408
  ] });
6121
6409
  }
6122
6410
  return null;
6123
- }, [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]);
6124
6412
  const renderFixedModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6125
- params.chain && /* @__PURE__ */ jsx(CardField, { label: "Chain: ", value: chainLabel }),
6413
+ params.chain && /* @__PURE__ */ jsx(CardField, { label: t("chain_is"), value: chainLabel }),
6126
6414
  params.token_out_list && params.token_out_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6127
- /* @__PURE__ */ jsx(CardField, { label: "Swap From: ", value: fromTokenDisplay }),
6415
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_from_is"), value: fromTokenDisplay }),
6128
6416
  params.token_out_list.filter(
6129
6417
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6130
6418
  ).map((token) => /* @__PURE__ */ jsx(
6131
6419
  CardField,
6132
6420
  {
6133
- label: `${token.symbol || "Token"} Address: `,
6421
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6134
6422
  value: formatAddress(token.address || ""),
6135
6423
  copy_text: token.address
6136
6424
  },
@@ -6138,13 +6426,13 @@ function SwapDexDialogContent({
6138
6426
  ))
6139
6427
  ] }),
6140
6428
  params.token_in_list && params.token_in_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6141
- /* @__PURE__ */ jsx(CardField, { label: "Swap To: ", value: toTokenDisplay }),
6429
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_to_is"), value: toTokenDisplay }),
6142
6430
  params.token_in_list.filter(
6143
6431
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6144
6432
  ).map((token) => /* @__PURE__ */ jsx(
6145
6433
  CardField,
6146
6434
  {
6147
- label: `${token.symbol || "Token"} Address: `,
6435
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6148
6436
  value: formatAddress(token.address || ""),
6149
6437
  copy_text: token.address
6150
6438
  },
@@ -6152,21 +6440,21 @@ function SwapDexDialogContent({
6152
6440
  ))
6153
6441
  ] }),
6154
6442
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6155
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6443
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6156
6444
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6157
6445
  ] })
6158
6446
  ] });
6159
6447
  const renderDynamicModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6160
6448
  hasRulesText && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6161
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Rules" }),
6449
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("rules") }),
6162
6450
  /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section-content taskon-swap-dialog-section-content--rules", children: [
6163
- /* @__PURE__ */ jsx("span", { children: "Every" }),
6451
+ /* @__PURE__ */ jsx("span", { children: t("every") }),
6164
6452
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-highlight", children: [
6165
6453
  "$",
6166
6454
  params.each_trading_volume || "0",
6167
6455
  " USD"
6168
6456
  ] }),
6169
- /* @__PURE__ */ jsx("span", { children: "will give you" }),
6457
+ /* @__PURE__ */ jsx("span", { children: t("will_give_you") }),
6170
6458
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-rules-highlight", children: params.each_receive_points }),
6171
6459
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-point-name", children: [
6172
6460
  rulePointName,
@@ -6175,12 +6463,12 @@ function SwapDexDialogContent({
6175
6463
  ] })
6176
6464
  ] }),
6177
6465
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6178
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6466
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6179
6467
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6180
6468
  ] })
6181
6469
  ] });
6182
6470
  if (!info) {
6183
- 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") });
6184
6472
  }
6185
6473
  return /* @__PURE__ */ jsxs(
6186
6474
  BaseDialogLayout,
@@ -6213,13 +6501,16 @@ function SwapDexDialogContent({
6213
6501
  children: [
6214
6502
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
6215
6503
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: isFixedRule ? renderFixedModeContent() : renderDynamicModeContent() }),
6216
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6504
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
6217
6505
  "button",
6218
6506
  {
6219
6507
  type: "button",
6220
6508
  className: "taskon-task-dialog-action",
6221
6509
  onClick: handleAction,
6222
- children: "👉 Swap"
6510
+ children: [
6511
+ "👉 ",
6512
+ t("swap")
6513
+ ]
6223
6514
  }
6224
6515
  )
6225
6516
  ]
@@ -6302,15 +6593,17 @@ function getDialogContentComponent(templateId) {
6302
6593
  return TaskDialogContent;
6303
6594
  }
6304
6595
  function DialogLoading() {
6596
+ const { t } = useCommunityTaskLocale();
6305
6597
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-loading", children: [
6306
6598
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-loading-spinner" }),
6307
- /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: "Loading task..." })
6599
+ /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: t("loading_task") })
6308
6600
  ] });
6309
6601
  }
6310
6602
  function DialogError({
6311
6603
  message,
6312
6604
  onRetry
6313
6605
  }) {
6606
+ const { t } = useCommunityTaskLocale();
6314
6607
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-error", children: [
6315
6608
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-error-icon", children: ":(" }),
6316
6609
  /* @__PURE__ */ jsx("p", { className: "taskon-dialog-error-message", children: message }),
@@ -6320,7 +6613,7 @@ function DialogError({
6320
6613
  type: "button",
6321
6614
  className: "taskon-dialog-error-retry",
6322
6615
  onClick: onRetry,
6323
- children: "Retry"
6616
+ children: t("retry")
6324
6617
  }
6325
6618
  )
6326
6619
  ] });
@@ -6340,11 +6633,12 @@ function TaskDialogComponent(props) {
6340
6633
  onCoolDownUpdate,
6341
6634
  onCoolDownComplete
6342
6635
  } = props;
6636
+ const { t } = useCommunityTaskLocale();
6343
6637
  const [justVerified, setJustVerified] = useState(false);
6344
6638
  const {
6345
6639
  data: fetchedTask,
6346
6640
  isLoading,
6347
- error,
6641
+ error: error2,
6348
6642
  refetch
6349
6643
  } = useTaskDetail({
6350
6644
  taskId: task ? null : taskId ?? null
@@ -6395,7 +6689,7 @@ function TaskDialogComponent(props) {
6395
6689
  const templateId = (_a2 = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a2.template_id;
6396
6690
  return getDialogContentComponent(templateId);
6397
6691
  }, [(_a = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a.template_id]);
6398
- const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? "任务详情";
6692
+ const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? t("task_details");
6399
6693
  const isOpen = task !== null || taskId !== null;
6400
6694
  if (typeof document === "undefined") {
6401
6695
  return null;
@@ -6406,14 +6700,14 @@ function TaskDialogComponent(props) {
6406
6700
  open: isOpen,
6407
6701
  onOpenChange: handleOpenChange,
6408
6702
  title: dialogTitle,
6409
- description: "查看任务详情和奖励信息",
6703
+ description: t("task_details_desc"),
6410
6704
  showCloseButton: true,
6411
6705
  bodyPadding: false,
6412
6706
  contentClassName: "taskon-task-dialog",
6413
6707
  maxWidth: rightSlot ? 800 : 480,
6414
6708
  children: [
6415
6709
  !task && isLoading && /* @__PURE__ */ jsx(DialogLoading, {}),
6416
- !task && error && /* @__PURE__ */ jsx(DialogError, { message: error, onRetry: refetch }),
6710
+ !task && error2 && /* @__PURE__ */ jsx(DialogError, { message: error2, onRetry: refetch }),
6417
6711
  taskData && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-wrapper", children: [
6418
6712
  renderContent ? renderContent(taskData) : /* @__PURE__ */ jsx(
6419
6713
  DialogContentComponent,
@@ -6533,12 +6827,13 @@ function CommunityTaskListInner(props) {
6533
6827
  rewardRedirectUrl = ""
6534
6828
  } = props;
6535
6829
  const { client, userToken } = useTaskOnContext();
6830
+ const { t } = useCommunityTaskLocale();
6536
6831
  const [taskCards, setTaskCards] = useState(
6537
6832
  []
6538
6833
  );
6539
6834
  const [selectedSectorId, setSelectedSectorId] = useState(null);
6540
6835
  const [isLoading, setIsLoading] = useState(true);
6541
- const [error, setError] = useState(null);
6836
+ const [error2, setError] = useState(null);
6542
6837
  const [openTask, setOpenTask] = useState(null);
6543
6838
  const [openTaskId, setOpenTaskId] = useState(
6544
6839
  initialTaskId ?? null
@@ -6557,10 +6852,13 @@ function CommunityTaskListInner(props) {
6557
6852
  return next;
6558
6853
  });
6559
6854
  }, []);
6560
- const handleTaskChainOpen = useCallback((taskChainId) => {
6561
- setOpenTaskChainId(taskChainId);
6562
- onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
6563
- }, [onTaskChainOpen]);
6855
+ const handleTaskChainOpen = useCallback(
6856
+ (taskChainId) => {
6857
+ setOpenTaskChainId(taskChainId);
6858
+ onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
6859
+ },
6860
+ [onTaskChainOpen]
6861
+ );
6564
6862
  const handleTaskChainClose = useCallback(() => {
6565
6863
  setOpenTaskChainId(null);
6566
6864
  onTaskChainClose == null ? void 0 : onTaskChainClose();
@@ -6578,7 +6876,7 @@ function CommunityTaskListInner(props) {
6578
6876
  useEffect(() => {
6579
6877
  const loadTasks = async () => {
6580
6878
  if (!client) {
6581
- setError("Client not initialized");
6879
+ setError(t("client_not_initialized"));
6582
6880
  setIsLoading(false);
6583
6881
  return;
6584
6882
  }
@@ -6592,60 +6890,54 @@ function CommunityTaskListInner(props) {
6592
6890
  });
6593
6891
  setTaskCards(data);
6594
6892
  } catch (err) {
6595
- setError(err instanceof Error ? err.message : "Failed to load");
6893
+ setError(err instanceof Error ? err.message : t("failed_to_load"));
6596
6894
  console.error("Failed to load community tasks:", err);
6597
6895
  } finally {
6598
6896
  setIsLoading(false);
6599
6897
  }
6600
6898
  };
6601
6899
  loadTasks();
6602
- }, [client, isPreview, userToken, sectorIds]);
6603
- const selectorOptions = React__default.useMemo(
6604
- () => {
6605
- const sectors = taskCards.map((item) => item.sector);
6606
- let options = sectors.map((sector) => ({
6607
- value: sector.id,
6608
- label: sector.name
6609
- }));
6610
- if (sectorIds && sectorIds.length > 0) {
6611
- const orderMap = new Map(
6612
- sectorIds.map((sectorId, index) => [sectorId, index])
6613
- );
6614
- options = options.filter((option) => orderMap.has(option.value)).sort((a, b) => {
6615
- const aIndex = orderMap.get(a.value) ?? 0;
6616
- const bIndex = orderMap.get(b.value) ?? 0;
6617
- return aIndex - bIndex;
6618
- });
6619
- }
6620
- return options;
6621
- },
6622
- [taskCards, sectorIds]
6623
- );
6624
- const filteredTaskCards = React__default.useMemo(
6625
- () => {
6626
- let result = taskCards;
6627
- if (sectorIds && sectorIds.length > 0) {
6628
- const idSet = new Set(sectorIds);
6629
- const orderMap = new Map(
6630
- sectorIds.map((sectorId, index) => [sectorId, index])
6631
- );
6632
- result = result.filter((item) => idSet.has(item.sector.id));
6633
- result = [...result].sort((a, b) => {
6634
- const aIndex = orderMap.get(a.sector.id);
6635
- const bIndex = orderMap.get(b.sector.id);
6636
- if (aIndex === void 0 && bIndex === void 0) return 0;
6637
- if (aIndex === void 0) return 1;
6638
- if (bIndex === void 0) return -1;
6639
- return aIndex - bIndex;
6640
- });
6641
- }
6642
- if (selectedSectorId !== null) {
6643
- result = result.filter((item) => item.sector.id === selectedSectorId);
6644
- }
6645
- return result;
6646
- },
6647
- [taskCards, selectedSectorId, sectorIds]
6648
- );
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]);
6649
6941
  const taskDependencyIndex = useMemo(() => {
6650
6942
  const index = /* @__PURE__ */ new Map();
6651
6943
  for (const sectorItem of taskCards) {
@@ -6663,7 +6955,9 @@ function CommunityTaskListInner(props) {
6663
6955
  if (eligibility.type !== EligibilityType.CommunityPreTask) {
6664
6956
  continue;
6665
6957
  }
6666
- const preTaskId = parsePreTaskIdFromEligibilityParams(eligibility.params);
6958
+ const preTaskId = parsePreTaskIdFromEligibilityParams(
6959
+ eligibility.params
6960
+ );
6667
6961
  if (!preTaskId || preTaskId === currentTaskId) {
6668
6962
  continue;
6669
6963
  }
@@ -6678,16 +6972,22 @@ function CommunityTaskListInner(props) {
6678
6972
  const handleSelectorChange = (value) => {
6679
6973
  setSelectedSectorId(value ?? null);
6680
6974
  };
6681
- const handleTaskClick = useCallback((taskCard) => {
6682
- setOpenTask(taskCard);
6683
- setOpenTaskId(null);
6684
- onTaskOpen == null ? void 0 : onTaskOpen(taskCard.card_info.id);
6685
- }, [onTaskOpen]);
6686
- const handleEligTaskClick = useCallback((taskId) => {
6687
- setOpenTaskId(taskId);
6688
- setOpenTask(null);
6689
- onTaskOpen == null ? void 0 : onTaskOpen(taskId);
6690
- }, [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
+ );
6691
6991
  const handleDialogClose = useCallback(() => {
6692
6992
  setOpenTask(null);
6693
6993
  setOpenTaskId(null);
@@ -6706,141 +7006,165 @@ function CommunityTaskListInner(props) {
6706
7006
  if (!currentOpenTask) {
6707
7007
  return null;
6708
7008
  }
6709
- const updatedTask = findTaskByIdFromCards(data, currentOpenTask.card_info.id);
7009
+ const updatedTask = findTaskByIdFromCards(
7010
+ data,
7011
+ currentOpenTask.card_info.id
7012
+ );
6710
7013
  return updatedTask ?? currentOpenTask;
6711
7014
  });
6712
7015
  } catch (err) {
6713
7016
  console.error("Failed to refresh tasks:", err);
6714
7017
  }
6715
7018
  }, [client, isPreview, sectorIds]);
6716
- const refreshSingleCard = useCallback(async (cardId, cardType) => {
6717
- if (!client) return;
6718
- try {
6719
- const api = createCommunityTaskApi(client);
6720
- const latestCard = await api.getCommunityTaskCardInfo({
6721
- card_id: cardId,
6722
- card_type: cardType,
6723
- is_preview: isPreview
6724
- });
6725
- setTaskCards((currentCards) => {
6726
- let targetSectorIndex = -1;
6727
- let targetCardIndex = -1;
6728
- for (let sectorIndex = 0; sectorIndex < currentCards.length; sectorIndex += 1) {
6729
- const sectorItem = currentCards[sectorIndex];
6730
- if (!sectorItem) {
6731
- 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
+ }
6732
7045
  }
6733
- const cardIndex = sectorItem.cards.findIndex(
6734
- (card) => card.card_type === cardType && card.card_info.id === cardId
6735
- );
6736
- if (cardIndex !== -1) {
6737
- targetSectorIndex = sectorIndex;
6738
- targetCardIndex = cardIndex;
6739
- break;
7046
+ if (targetSectorIndex === -1 || targetCardIndex === -1) {
7047
+ return currentCards;
6740
7048
  }
6741
- }
6742
- if (targetSectorIndex === -1 || targetCardIndex === -1) {
6743
- return currentCards;
6744
- }
6745
- const nextCards = [...currentCards];
6746
- const targetSector = currentCards[targetSectorIndex];
6747
- if (!targetSector) {
6748
- return currentCards;
6749
- }
6750
- const nextSectorCards = [...targetSector.cards];
6751
- nextSectorCards[targetCardIndex] = latestCard;
6752
- nextCards[targetSectorIndex] = {
6753
- ...targetSector,
6754
- cards: nextSectorCards
6755
- };
6756
- return nextCards;
6757
- });
6758
- if (cardType === TaskCardType.GTCTask) {
6759
- setOpenTask((currentOpenTask) => {
6760
- if (!currentOpenTask || currentOpenTask.card_info.id !== cardId) {
6761
- return currentOpenTask;
7049
+ const nextCards = [...currentCards];
7050
+ const targetSector = currentCards[targetSectorIndex];
7051
+ if (!targetSector) {
7052
+ return currentCards;
6762
7053
  }
6763
- return latestCard;
7054
+ const nextSectorCards = [...targetSector.cards];
7055
+ nextSectorCards[targetCardIndex] = latestCard;
7056
+ nextCards[targetSectorIndex] = {
7057
+ ...targetSector,
7058
+ cards: nextSectorCards
7059
+ };
7060
+ return nextCards;
6764
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);
6765
7072
  }
6766
- } catch (err) {
6767
- console.error(`Failed to refresh card ${cardType}:${cardId}:`, err);
6768
- }
6769
- }, [client, isPreview]);
6770
- const refreshSingleTask = useCallback(async (taskId) => {
6771
- await refreshSingleCard(taskId, TaskCardType.GTCTask);
6772
- }, [refreshSingleCard]);
6773
- const refreshSingleTaskChain = useCallback(async (taskChainId) => {
6774
- await refreshSingleCard(taskChainId, TaskCardType.TaskChain);
6775
- }, [refreshSingleCard]);
6776
- const handleClaimSuccess = useCallback(async (taskId) => {
6777
- if (!client) {
6778
- return;
6779
- }
6780
- if (typeof taskId !== "number") {
6781
- await refreshTaskList();
6782
- return;
6783
- }
6784
- await refreshSingleTask(taskId);
6785
- const dependentTasks = taskDependencyIndex.get(taskId);
6786
- if (dependentTasks && dependentTasks.size > 0) {
6787
- await refreshTaskList();
6788
- }
6789
- }, [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
+ );
6790
7105
  const { toast } = useToast();
6791
- const handleClaimTask = useCallback(async (taskId, token, platform) => {
6792
- if (!client) return { successful: false };
6793
- try {
6794
- const api = createCommunityTaskApi(client);
6795
- const result = await api.submitTask({
6796
- task_id: taskId,
6797
- task_value: token || ""
6798
- });
6799
- if (result.successful) {
6800
- await handleClaimSuccess(taskId);
6801
- return { successful: true };
6802
- } else if (result.cool_down) {
6803
- updateCoolDown(taskId, result.cool_down);
6804
- return { successful: false, cool_down: result.cool_down };
6805
- } else {
6806
- if (platform === "Twitter") {
6807
- toast.error("Oops! Task verification failed. There might be a delay due to Twitter restrictions. Please try again later.");
6808
- } else if (platform === "Discord") {
6809
- toast.error("Oops! Task verification failed. There might be a delay due to Discord restrictions. Please try again later.");
6810
- } else if (platform === "Telegram") {
6811
- 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 };
6812
7121
  } else {
6813
- 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 };
6814
7132
  }
6815
- return { successful: false };
6816
- }
6817
- } catch (err) {
6818
- console.error("Failed to submit task:", err);
6819
- const errorCode = err instanceof ApiError ? err.code : void 0;
6820
- const errorMessage = resolveCommunityTaskSubmitErrorMessage(err, errorCode);
6821
- const errorData = err instanceof ApiError ? err.data : void 0;
6822
- if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
6823
- return { successful: false, errorCode };
6824
- }
6825
- if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
6826
- const { invited = 0, min_required = 0 } = errorData;
6827
- 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);
6828
7156
  return { successful: false, errorCode };
6829
7157
  }
6830
- toast.error(errorMessage);
6831
- return { successful: false, errorCode };
6832
- }
6833
- }, [client, handleClaimSuccess, toast, updateCoolDown]);
7158
+ },
7159
+ [client, handleClaimSuccess, toast, updateCoolDown, t]
7160
+ );
6834
7161
  const isDialogOpen = openTask !== null || openTaskId !== null;
6835
7162
  const currentSelectorValue = selectedSectorId ?? void 0;
6836
- if (error) {
6837
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-error", children: [
6838
- "Error: ",
6839
- error
6840
- ] }) });
7163
+ if (error2) {
7164
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsx("div", { className: "taskon-community-list-error", children: error2 }) });
6841
7165
  }
6842
7166
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-list", children: [
6843
- showSectorTab && /* @__PURE__ */ jsx(
7167
+ showSectorTab && !isLoading && /* @__PURE__ */ jsx(
6844
7168
  CardSelector,
6845
7169
  {
6846
7170
  options: selectorOptions,
@@ -6850,7 +7174,15 @@ function CommunityTaskListInner(props) {
6850
7174
  className: "taskon-community-list-selector"
6851
7175
  }
6852
7176
  ),
6853
- /* @__PURE__ */ jsx("div", { className: "taskon-community-list-content", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-loading", children: "Loading tasks..." }) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: "No tasks available" }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
7177
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-list-content", children: isLoading ? /* @__PURE__ */ jsx(
7178
+ CommunityTaskListSkeleton,
7179
+ {
7180
+ showSectorTab,
7181
+ showSectorName,
7182
+ showSectorDescription,
7183
+ showSectorReward
7184
+ }
7185
+ ) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: t("no_tasks_available") }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
6854
7186
  SectorItem,
6855
7187
  {
6856
7188
  sector: sectorItem,