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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +13 -4
  2. package/dist/CommunityTaskList.css +119 -111
  3. package/dist/EligibilityInfo.css +114 -110
  4. package/dist/LeaderboardWidget.css +73 -71
  5. package/dist/PageBuilder.css +5 -0
  6. package/dist/Quest.css +259 -255
  7. package/dist/TaskOnProvider.css +2 -0
  8. package/dist/UserCenterWidget.css +6 -6
  9. package/dist/UserCenterWidget2.css +1626 -1601
  10. package/dist/{dynamic-import-helper.css → WidgetShell.css} +2 -2
  11. package/dist/chunks/{CommunityTaskList-C9Gv8KOF.js → CommunityTaskList-Hde2OKHH.js} +1070 -580
  12. package/dist/chunks/{EligibilityInfo-D-Fuy9GE.js → EligibilityInfo-BV0Z2TgY.js} +1972 -1028
  13. package/dist/chunks/{LeaderboardWidget-BV2D2q1N.js → LeaderboardWidget-BNGRD5Bu.js} +270 -249
  14. package/dist/chunks/{PageBuilder-DQoU4Mwf.js → PageBuilder-C5DSHiW9.js} +5 -5
  15. package/dist/chunks/{Quest-B5NyVr3o.js → Quest-DG9zfXJo.js} +723 -513
  16. package/dist/chunks/{TaskOnProvider-93UxARFo.js → TaskOnProvider-BhamHIyY.js} +98 -68
  17. package/dist/chunks/{ThemeProvider-CPI_roeh.js → ThemeProvider-mXLdLSkq.js} +107 -20
  18. package/dist/chunks/{UserCenterWidget-cADBSVg7.js → UserCenterWidget-D5ttw4hO.js} +1328 -1337
  19. package/dist/chunks/{UserCenterWidget-BRtigY_S.js → UserCenterWidget-jDO5zTN1.js} +358 -254
  20. package/dist/chunks/{dynamic-import-helper-DwXlQC0S.js → WidgetShell-D7yC894Y.js} +447 -457
  21. package/dist/chunks/communitytask-es-CBNnS4o2.js +521 -0
  22. package/dist/chunks/communitytask-ja-GRf9cbdx.js +521 -0
  23. package/dist/chunks/communitytask-ko-Bf24PQKI.js +521 -0
  24. package/dist/chunks/communitytask-ru-CZm2CPoV.js +521 -0
  25. package/dist/chunks/leaderboardwidget-es-vKjrjQaz.js +146 -0
  26. package/dist/chunks/leaderboardwidget-ja-Q6u0HxKG.js +146 -0
  27. package/dist/chunks/leaderboardwidget-ko-CG6SWgxf.js +146 -0
  28. package/dist/chunks/leaderboardwidget-ru-DCcHcJGz.js +146 -0
  29. package/dist/chunks/quest-es-Dyyy0zaw.js +863 -0
  30. package/dist/chunks/quest-ja-Depog33y.js +863 -0
  31. package/dist/chunks/quest-ko-BMu3uRQJ.js +863 -0
  32. package/dist/chunks/quest-ru-xne814Rw.js +863 -0
  33. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  34. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  35. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  36. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  37. package/dist/chunks/usercenter-es-Dz3Wp2vV.js +512 -0
  38. package/dist/chunks/usercenter-ja-CKE4DJC6.js +512 -0
  39. package/dist/chunks/usercenter-ko-Dtpkn2qb.js +512 -0
  40. package/dist/chunks/usercenter-ru-DnBGee45.js +512 -0
  41. package/dist/community-task.d.ts +0 -390
  42. package/dist/community-task.js +2 -7
  43. package/dist/core.d.ts +46 -10
  44. package/dist/core.js +11 -11
  45. package/dist/index.d.ts +46 -667
  46. package/dist/index.js +19 -28
  47. package/dist/leaderboard.d.ts +0 -498
  48. package/dist/leaderboard.js +2 -16
  49. package/dist/page-builder.js +1 -1
  50. package/dist/quest.d.ts +0 -289
  51. package/dist/quest.js +2 -5
  52. package/dist/user-center.d.ts +0 -1608
  53. package/dist/user-center.js +2 -494
  54. package/package.json +5 -2
  55. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +0 -119
  56. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +0 -119
  57. package/dist/chunks/usercenter-ja-B2465c1O.js +0 -326
  58. package/dist/chunks/usercenter-ko-xAEYxqLg.js +0 -326
@@ -1,11 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import React__default, { useState, useRef, useCallback, useEffect, useContext, useMemo } from "react";
3
- import { isUnauthorizedError, TaskReviewResult, formatLongNumber, EligibilityType, Operator, MeetConditionStatus, RewardType, formatUtcTime, ErrorCode, SnsType, createCommunityTaskApi, ApiError, TaskCardType, ChainType, getSwapDexTitleExpress, UserEligibleStatus, CampaignStatus, MediaType, createQuestApi, CampaignType, formatTokenAmount, TaskTemplateId, EligibilityTemplateId, RecurrenceType, createCommonApi, normalizeTask, formatSwapTokensForDisplay, formatAddress } from "@taskon/core";
4
- import { p as TaskOnContext, d as useTaskOnContext, s as useTaskOnPortalContainer } from "./ThemeProvider-CPI_roeh.js";
5
- import { D as Dialog, a as useResolvedWidgetConfig, W as WidgetShell } from "./dynamic-import-helper-DwXlQC0S.js";
3
+ import { isUnauthorizedError, TaskReviewResult, formatLongNumber, EligibilityType, Operator, MeetConditionStatus, RewardType, formatUtcTime, ErrorCode, SnsType, createCommunityTaskApi, TaskCardType, ChainType, getSwapDexTitleExpress, UserEligibleStatus, CampaignStatus, MediaType, createQuestApi, CampaignType, formatTokenAmount, TaskTemplateId, EligibilityTemplateId, RecurrenceType, createCommonApi, normalizeTask, formatSwapTokensForDisplay, formatAddress } from "@taskon/core";
4
+ import { c as useTranslation, e as createLocaleLoader, v as TaskOnContext, h as useTaskOnContext, x as useTaskOnPortalContainer } from "./ThemeProvider-mXLdLSkq.js";
5
+ import { D as Dialog, u as useResolvedWidgetConfig, W as WidgetShell } from "./WidgetShell-D7yC894Y.js";
6
6
  import { d as useToast } from "./useToast-CaRkylKe.js";
7
- import { u as useBindWallet, T as TitleExpress, a as CardDescExpress, b as useNftClaimFlow, R as RewardModuleDialog, B as BlindBoxDialog, c as TaskItem, E as EligibilityInfo, d as Textarea } from "./EligibilityInfo-D-Fuy9GE.js";
8
- import { g as useBindSocialAccount, B as BindWalletDialog, l as useChainMap, s as TipPopover, k as useIsMobile, I as Input } from "./UserCenterWidget-cADBSVg7.js";
7
+ import { u as useBindWallet, T as TitleExpress, C as CardDescExpress, a as useNftClaimFlow, R as RewardModuleDialog, B as BlindBoxDialog, b as TaskItem, E as EligibilityInfo, c as Textarea } from "./EligibilityInfo-BV0Z2TgY.js";
8
+ import { a as useBindSocialAccount, B as BindWalletDialog, l as useChainMap, q as TipPopover, h as useIsMobile, I as Input } from "./UserCenterWidget-D5ttw4hO.js";
9
9
  import { createPortal } from "react-dom";
10
10
  import '../CommunityTaskList.css';function CardSelector({
11
11
  options,
@@ -39,6 +39,391 @@ import '../CommunityTaskList.css';function CardSelector({
39
39
  );
40
40
  }) });
41
41
  }
42
+ const once_tag = "Once";
43
+ const daily_tag = "Daily";
44
+ const weekly_tag = "Weekly";
45
+ const monthly_tag = "Monthly";
46
+ const unlimited_tag = "Unlimited";
47
+ const verify_claim = "Verify & Claim";
48
+ const claim = "Claim";
49
+ const update = "Update";
50
+ const valid_util_is = "Valid Until:";
51
+ const won = "Won";
52
+ const gift_rewards = "🎁 Rewards";
53
+ const max_claim_num = "Max. Claims";
54
+ const updated_at = "Updated at {val}";
55
+ const oops = "Oops!";
56
+ const verify_failed = "Verification Failed";
57
+ const oops_failed = "Oops, Failed";
58
+ const under_review = "Under Review";
59
+ const failed = "Failed";
60
+ const completed_now = "Task is complete for now.";
61
+ const continue_in = "Continue in";
62
+ const done_today = "Done for today";
63
+ const per_time = "/Time";
64
+ const earned = "Earned";
65
+ const retry_after = "Retry after {val}";
66
+ const task_verify_warning = "This task only verify action during {start} - {end}(UTC)";
67
+ const you_have_completed = "🎉 You have completed";
68
+ const you_not_pass = "Oops! You did not pass this task.";
69
+ const proceed_2_complete_the_task = "Proceed to complete the task";
70
+ 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}.";
71
+ 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}.";
72
+ 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}.";
73
+ const discord_invites_err = "Your Invites: {invited} , {need} more needed. Please invite more friends to join the Discord Server";
74
+ const close_in = "🎉 Congratulations, close in {val}s";
75
+ const check = "Check";
76
+ const level_above = "Reach level {val} or above";
77
+ const level_below = "is lower than level {val}";
78
+ const discord_role_is_val = "Discord role is {val}";
79
+ const discord_role_is_not_val = "Discord role is not {val}";
80
+ const nft_token_label = "Own at least {amt} {token} on {chain}";
81
+ const complete_task = "Completed {val}";
82
+ const not_complete_task = "Not Completed {val}";
83
+ const taskon_community = "TaskOn Community";
84
+ const copy = "copy";
85
+ const copy_success = "Copy success";
86
+ const copy_failed = "Copy failed";
87
+ const invalid_image_size_10m = "Please upload an image below 10M";
88
+ const upload_failed = "Upload Failed, please try again!";
89
+ const please_enter_url = "Please enter URL";
90
+ const please_enter_text = "Please enter text";
91
+ const invalid_url = "Please enter a valid url address";
92
+ const enter_here = "Enter here";
93
+ const resubmit = "Resubmit";
94
+ const re_submitted_success = "Re-submitted Successfully";
95
+ const submit = "Submit";
96
+ const swap = "Swap";
97
+ const chain_is = "Chain:";
98
+ const swap_from_is = "Swap From:";
99
+ const swap_to_is = "Swap To:";
100
+ const rules = "Rules";
101
+ const instructions = "Instructions";
102
+ const times = "Times";
103
+ const address_is = "Address:";
104
+ const only_left = "Hurry up! Only {val} left";
105
+ const task_up = "Task";
106
+ const no_task = "No Task";
107
+ const all = "All";
108
+ const any = "Any";
109
+ const meet_all_conditions_to_unlock = "Meet all conditions to Unlock";
110
+ const meet_any_condition_to_unlock = "Meet any condition to Unlock";
111
+ const contact_to_check_progress = "Contact {name} to check your progress";
112
+ const loading = "Loading...";
113
+ const error = "Something went wrong";
114
+ const retry = "Retry";
115
+ const loading_tasks = "Loading tasks...";
116
+ const no_tasks_available = "No tasks available";
117
+ const loading_task = "Loading task...";
118
+ const task_details = "Task details";
119
+ const task_details_desc = "View task details and reward information";
120
+ const no_task_data = "No task data";
121
+ const client_not_initialized = "Client not initialized";
122
+ const failed_to_load = "Failed to load";
123
+ const submission_failed = "Submission failed";
124
+ const failed_to_submit_task = "Failed to submit task:";
125
+ const join_required_discord_channel = "Please join the required Discord channel and try again.";
126
+ const verification_failed_twitter = "Oops! Task verification failed. There might be a delay due to Twitter restrictions. Please try again later.";
127
+ const verification_failed_discord = "Oops! Task verification failed. There might be a delay due to Discord restrictions. Please try again later.";
128
+ const verification_failed_telegram = "Oops! Task verification failed. There might be a delay due to Telegram restrictions. Please try again later.";
129
+ const verification_failed_generic = "Task verification failed. Please check if you completed the required action.";
130
+ const upload_image = "Upload image";
131
+ const click_to_upload_image = "Click to upload image";
132
+ const please_upload_image = "Please upload an image";
133
+ const submitting = "Submitting...";
134
+ const task_completed = "Task completed";
135
+ const every = "Every";
136
+ const will_give_you = "will give you";
137
+ const copy_to_clipboard = "Copy to clipboard";
138
+ const copied = "Copied!";
139
+ const community_login_first = "Please login first";
140
+ const community_points = "Points";
141
+ const community_token = "Token";
142
+ const community_dex = "DEX";
143
+ const community_rule_max = "(Max {val} {name})";
144
+ const taskchain_event_ended = "Event Ended";
145
+ const taskchain_login_required = "Login Required";
146
+ const taskchain_login_prompt = "Please login to participate in this task chain";
147
+ const taskchain_login_button = "Login";
148
+ const taskchain_not_eligible_title = "Not Eligible";
149
+ const taskchain_not_eligible_desc = "You don't meet the requirements to participate in this task chain.";
150
+ const taskchain_oops = "Oops!";
151
+ const taskchain_error_load_chain = "Failed to load task chain";
152
+ const taskchain_error_load_campaign_info = "Failed to load campaign info";
153
+ const taskchain_error_load_user_status = "Failed to load user status";
154
+ const taskchain_loading = "Loading...";
155
+ const taskchain_back = "Back";
156
+ const taskchain_next = "Next";
157
+ const taskchain_no_task_available = "No task available";
158
+ const taskchain_spots_left = "Spots left";
159
+ const taskchain_won = "Won";
160
+ const taskchain_ended = "Ended";
161
+ const taskchain_locked = "Locked";
162
+ const taskchain_unlock_prefix = "Complete the";
163
+ const taskchain_unlock_day_challenge = "Day {day} challenge";
164
+ const taskchain_unlock_suffix = "then wait until next day to unlock";
165
+ const taskchain_goal = "Goal";
166
+ const taskchain_token_fallback = "Token";
167
+ const taskchain_points_fallback = "Points";
168
+ const taskchain_nft_fallback = "NFT";
169
+ const taskchain_blindbox_submit_failed = "Failed to submit campaign. Please try again.";
170
+ const taskchain_blindbox_claim_failed = "Failed to claim reward. Please try again.";
171
+ const taskchain_blindbox_title_missed = "Oops! Better Luck Next Time!";
172
+ const taskchain_blindbox_title_won = "Congratulations!";
173
+ const taskchain_blindbox_subtitle_missed = "Rewards Missed";
174
+ const taskchain_blindbox_subtitle_won = "You Have Won";
175
+ const taskchain_blindbox_preparing_reward = "Preparing your reward...";
176
+ const taskchain_blindbox_submitting = "Submitting...";
177
+ const taskchain_blindbox_retry_submit = "Retry submit";
178
+ const taskchain_reward_submit_failed = "Failed to submit campaign. Please try again.";
179
+ const taskchain_reward_congratulations = "Congratulations!";
180
+ const taskchain_reward_you_won = "You have won";
181
+ const taskchain_reward_claiming = "Claiming...";
182
+ const taskchain_reward_claim = "Claim Reward";
183
+ const taskchain_nft_claim_failed = "Failed to claim NFT";
184
+ const taskchain_reward_token_label = "Reward Token";
185
+ const taskchain_value_label = "Value";
186
+ const taskchain_reward_type_cap = "Cap";
187
+ const taskchain_reward_type_nft = "NFT";
188
+ const taskchain_nft_cta_mint = "Mint";
189
+ const taskchain_nft_cta_view = "View my NFT";
190
+ const taskchain_nft_claim_not_supported = "NFT claim is not supported for this reward type yet.";
191
+ const taskchain_nft_alt = "NFT";
192
+ const taskchain_chain_alt = "Chain";
193
+ const taskchain_nft_claim_dialog_claim_nft = "Claim NFT";
194
+ const taskchain_nft_claim_dialog_claiming_nft = "Claiming NFT...";
195
+ const taskchain_nft_claim_dialog_connecting_wallet = "Connecting wallet...";
196
+ const taskchain_nft_claim_dialog_switching_network = "Switching network...";
197
+ const taskchain_nft_claim_dialog_getting_signature = "Getting signature...";
198
+ const taskchain_nft_claim_dialog_confirm_in_wallet = "Please confirm in your wallet";
199
+ const taskchain_nft_claim_dialog_tx_pending = "Transaction pending...";
200
+ const taskchain_nft_claim_dialog_success = "Claim successful!";
201
+ const taskchain_nft_claim_dialog_failed = "Claim failed";
202
+ const taskchain_nft_claim_dialog_canceled = "Transaction was rejected by user.";
203
+ const taskchain_nft_claim_dialog_view_explorer = "View on Explorer";
204
+ const taskchain_nft_claim_dialog_retry = "Retry";
205
+ const taskchain_nft_claim_dialog_close = "Close";
206
+ const taskchain_nft_pending_dialog_title = "Pending Transaction";
207
+ const taskchain_nft_pending_dialog_desc = "You have already claimed this NFT, please wait for this transaction to be confirmed.";
208
+ const taskchain_nft_pending_dialog_check_explorer = "You can check this transaction on explorer:";
209
+ const taskchain_nft_pending_dialog_hash_label = "Transaction hash:";
210
+ const taskchain_nft_pending_dialog_claim_again_warn = '"Claim Again" will send a new transaction it is only recommended when you are sure there is something wrong with the current transaction.';
211
+ const taskchain_nft_pending_dialog_receive_address_fixed = "This receive address can't be changed:";
212
+ const taskchain_nft_pending_dialog_claim_again = "Claim Again";
213
+ const taskchain_nft_pending_dialog_continue_waiting = "Continue Waiting";
214
+ const enMessages = {
215
+ once_tag,
216
+ daily_tag,
217
+ weekly_tag,
218
+ monthly_tag,
219
+ unlimited_tag,
220
+ verify_claim,
221
+ claim,
222
+ update,
223
+ valid_util_is,
224
+ won,
225
+ gift_rewards,
226
+ max_claim_num,
227
+ updated_at,
228
+ oops,
229
+ verify_failed,
230
+ oops_failed,
231
+ under_review,
232
+ failed,
233
+ completed_now,
234
+ continue_in,
235
+ done_today,
236
+ per_time,
237
+ earned,
238
+ retry_after,
239
+ task_verify_warning,
240
+ you_have_completed,
241
+ you_not_pass,
242
+ proceed_2_complete_the_task,
243
+ twitter_delay_error,
244
+ discord_delay_error,
245
+ telegram_delay_error,
246
+ discord_invites_err,
247
+ close_in,
248
+ check,
249
+ level_above,
250
+ level_below,
251
+ discord_role_is_val,
252
+ discord_role_is_not_val,
253
+ nft_token_label,
254
+ complete_task,
255
+ not_complete_task,
256
+ taskon_community,
257
+ copy,
258
+ copy_success,
259
+ copy_failed,
260
+ invalid_image_size_10m,
261
+ upload_failed,
262
+ please_enter_url,
263
+ please_enter_text,
264
+ invalid_url,
265
+ enter_here,
266
+ resubmit,
267
+ re_submitted_success,
268
+ submit,
269
+ swap,
270
+ chain_is,
271
+ swap_from_is,
272
+ swap_to_is,
273
+ rules,
274
+ instructions,
275
+ times,
276
+ address_is,
277
+ only_left,
278
+ task_up,
279
+ no_task,
280
+ all,
281
+ any,
282
+ meet_all_conditions_to_unlock,
283
+ meet_any_condition_to_unlock,
284
+ contact_to_check_progress,
285
+ loading,
286
+ error,
287
+ retry,
288
+ loading_tasks,
289
+ no_tasks_available,
290
+ loading_task,
291
+ task_details,
292
+ task_details_desc,
293
+ no_task_data,
294
+ client_not_initialized,
295
+ failed_to_load,
296
+ submission_failed,
297
+ failed_to_submit_task,
298
+ join_required_discord_channel,
299
+ verification_failed_twitter,
300
+ verification_failed_discord,
301
+ verification_failed_telegram,
302
+ verification_failed_generic,
303
+ upload_image,
304
+ click_to_upload_image,
305
+ please_upload_image,
306
+ submitting,
307
+ task_completed,
308
+ every,
309
+ will_give_you,
310
+ copy_to_clipboard,
311
+ copied,
312
+ community_login_first,
313
+ community_points,
314
+ community_token,
315
+ community_dex,
316
+ community_rule_max,
317
+ taskchain_event_ended,
318
+ taskchain_login_required,
319
+ taskchain_login_prompt,
320
+ taskchain_login_button,
321
+ taskchain_not_eligible_title,
322
+ taskchain_not_eligible_desc,
323
+ taskchain_oops,
324
+ taskchain_error_load_chain,
325
+ taskchain_error_load_campaign_info,
326
+ taskchain_error_load_user_status,
327
+ taskchain_loading,
328
+ taskchain_back,
329
+ taskchain_next,
330
+ taskchain_no_task_available,
331
+ taskchain_spots_left,
332
+ taskchain_won,
333
+ taskchain_ended,
334
+ taskchain_locked,
335
+ taskchain_unlock_prefix,
336
+ taskchain_unlock_day_challenge,
337
+ taskchain_unlock_suffix,
338
+ taskchain_goal,
339
+ taskchain_token_fallback,
340
+ taskchain_points_fallback,
341
+ taskchain_nft_fallback,
342
+ taskchain_blindbox_submit_failed,
343
+ taskchain_blindbox_claim_failed,
344
+ taskchain_blindbox_title_missed,
345
+ taskchain_blindbox_title_won,
346
+ taskchain_blindbox_subtitle_missed,
347
+ taskchain_blindbox_subtitle_won,
348
+ taskchain_blindbox_preparing_reward,
349
+ taskchain_blindbox_submitting,
350
+ taskchain_blindbox_retry_submit,
351
+ taskchain_reward_submit_failed,
352
+ taskchain_reward_congratulations,
353
+ taskchain_reward_you_won,
354
+ taskchain_reward_claiming,
355
+ taskchain_reward_claim,
356
+ taskchain_nft_claim_failed,
357
+ taskchain_reward_token_label,
358
+ taskchain_value_label,
359
+ taskchain_reward_type_cap,
360
+ taskchain_reward_type_nft,
361
+ taskchain_nft_cta_mint,
362
+ taskchain_nft_cta_view,
363
+ taskchain_nft_claim_not_supported,
364
+ taskchain_nft_alt,
365
+ taskchain_chain_alt,
366
+ taskchain_nft_claim_dialog_claim_nft,
367
+ taskchain_nft_claim_dialog_claiming_nft,
368
+ taskchain_nft_claim_dialog_connecting_wallet,
369
+ taskchain_nft_claim_dialog_switching_network,
370
+ taskchain_nft_claim_dialog_getting_signature,
371
+ taskchain_nft_claim_dialog_confirm_in_wallet,
372
+ taskchain_nft_claim_dialog_tx_pending,
373
+ taskchain_nft_claim_dialog_success,
374
+ taskchain_nft_claim_dialog_failed,
375
+ taskchain_nft_claim_dialog_canceled,
376
+ taskchain_nft_claim_dialog_view_explorer,
377
+ taskchain_nft_claim_dialog_retry,
378
+ taskchain_nft_claim_dialog_close,
379
+ taskchain_nft_pending_dialog_title,
380
+ taskchain_nft_pending_dialog_desc,
381
+ taskchain_nft_pending_dialog_check_explorer,
382
+ taskchain_nft_pending_dialog_hash_label,
383
+ taskchain_nft_pending_dialog_claim_again_warn,
384
+ taskchain_nft_pending_dialog_receive_address_fixed,
385
+ taskchain_nft_pending_dialog_claim_again,
386
+ taskchain_nft_pending_dialog_continue_waiting
387
+ };
388
+ const loadMessages = createLocaleLoader(
389
+ enMessages,
390
+ {
391
+ ko: () => import("./communitytask-ko-Bf24PQKI.js").then((module) => ({
392
+ default: module.default
393
+ })),
394
+ ja: () => import("./communitytask-ja-GRf9cbdx.js").then((module) => ({
395
+ default: module.default
396
+ })),
397
+ ru: () => import("./communitytask-ru-CZm2CPoV.js").then((module) => ({
398
+ default: module.default
399
+ })),
400
+ es: () => import("./communitytask-es-CBNnS4o2.js").then((module) => ({
401
+ default: module.default
402
+ }))
403
+ }
404
+ );
405
+ function useCommunityTaskLocale() {
406
+ return useTranslation({
407
+ widgetId: "CommunityTask",
408
+ defaultMessages: enMessages,
409
+ loadMessages
410
+ });
411
+ }
412
+ const RECURRENCE_KEY_MAP = {
413
+ Once: "once_tag",
414
+ Daily: "daily_tag",
415
+ Weekly: "weekly_tag",
416
+ Monthly: "monthly_tag",
417
+ Unlimited: "unlimited_tag"
418
+ };
419
+ function getRecurrenceLabel(t, recurrence) {
420
+ const recurrenceCode = recurrence ?? "Once";
421
+ const key = RECURRENCE_KEY_MAP[recurrenceCode];
422
+ if (!key) {
423
+ return recurrenceCode;
424
+ }
425
+ return t(key);
426
+ }
42
427
  function ClaimButton({
43
428
  verifyClaim = false,
44
429
  recurrence,
@@ -55,6 +440,7 @@ function ClaimButton({
55
440
  chainType,
56
441
  onBindFailed
57
442
  }) {
443
+ const { t } = useCommunityTaskLocale();
58
444
  const [internalLoading, setInternalLoading] = useState(false);
59
445
  const [showWalletDialog, setShowWalletDialog] = useState(false);
60
446
  const needBindCheck = !claimDialog;
@@ -104,11 +490,11 @@ function ClaimButton({
104
490
  }, [bindWithProvider]);
105
491
  const buttonLabel = (() => {
106
492
  if (customLabel) return customLabel;
107
- if (mini) return "Update";
493
+ if (mini) return t("update");
108
494
  if (recurrence === "Unlimited") {
109
- return hasPoints ? "Update" : "Claim";
495
+ return hasPoints ? t("update") : t("claim");
110
496
  }
111
- return verifyClaim ? "Verify & Claim" : "Claim";
497
+ return verifyClaim ? t("verify_claim") : t("claim");
112
498
  })();
113
499
  const isDisabled = disabled || isSubmitting || internalLoading || isWaitingAuth || isBindingWallet;
114
500
  const buttonClass = [
@@ -187,7 +573,7 @@ function ClaimButton({
187
573
  }
188
574
  function formatCountdown$1(valueMillSec) {
189
575
  if (valueMillSec <= 0) {
190
- return "0 min";
576
+ return "0s";
191
577
  }
192
578
  const hours = Math.floor(valueMillSec / 1e3 / 60 / 60);
193
579
  const minutes = Math.floor((valueMillSec / 1e3 / 60 / 60 - hours) * 60);
@@ -195,11 +581,11 @@ function formatCountdown$1(valueMillSec) {
195
581
  (valueMillSec / 1e3 / 60 - hours * 60 - minutes) * 60
196
582
  );
197
583
  if (hours > 0) {
198
- return `${hours} hour${hours > 1 ? "s" : ""}`;
584
+ return `${hours}h`;
199
585
  } else if (minutes > 0) {
200
- return `${minutes} min${minutes > 1 ? "s" : ""}`;
586
+ return `${minutes}m`;
201
587
  } else {
202
- return `${seconds} sec${seconds > 1 ? "s" : ""}`;
588
+ return `${seconds}s`;
203
589
  }
204
590
  }
205
591
  function ClaimRetry({
@@ -208,6 +594,7 @@ function ClaimRetry({
208
594
  onComplete
209
595
  }) {
210
596
  const [timeLeft, setTimeLeft] = useState(leftMillSecond);
597
+ const { t } = useCommunityTaskLocale();
211
598
  const onUpdateRef = useRef(onUpdate);
212
599
  const onCompleteRef = useRef(onComplete);
213
600
  useEffect(() => {
@@ -239,25 +626,16 @@ function ClaimRetry({
239
626
  clearInterval(timer);
240
627
  };
241
628
  }, [leftMillSecond]);
242
- return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-retry", children: [
243
- "Retry after ",
244
- formatCountdown$1(timeLeft)
245
- ] });
629
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-retry", children: t("retry_after", { val: formatCountdown$1(timeLeft) }) });
246
630
  }
247
631
  const SECOND = 1e3;
248
632
  const MINUTE = 60 * SECOND;
249
633
  const HOUR = 60 * MINUTE;
250
- const DAY = 24 * HOUR;
251
634
  function prefix(num) {
252
635
  return num < 10 ? `0${num}` : `${num}`;
253
636
  }
254
637
  function formatDurationLabel(from, to) {
255
638
  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
639
  const hours = Math.floor(time / HOUR);
262
640
  const minutes = Math.floor(time % HOUR / MINUTE);
263
641
  const seconds = Math.floor(time % MINUTE / SECOND);
@@ -268,6 +646,7 @@ function DoneCountdown({
268
646
  onComplete
269
647
  }) {
270
648
  const [now, setNow] = useState(Date.now());
649
+ const { t } = useCommunityTaskLocale();
271
650
  const onCompleteRef = useRef(onComplete);
272
651
  useEffect(() => {
273
652
  onCompleteRef.current = onComplete;
@@ -288,9 +667,9 @@ function DoneCountdown({
288
667
  }, [nextTime]);
289
668
  const countdownLabel = now >= nextTime ? "00h : 00m : 00s" : formatDurationLabel(now, nextTime);
290
669
  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." }),
670
+ /* @__PURE__ */ jsx("div", { className: "taskon-community-task-done-countdown-text", children: t("completed_now") }),
292
671
  /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-done-countdown-timer", children: [
293
- /* @__PURE__ */ jsx("span", { children: "Continue in" }),
672
+ /* @__PURE__ */ jsx("span", { children: t("continue_in") }),
294
673
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-done-countdown-time", children: countdownLabel })
295
674
  ] })
296
675
  ] });
@@ -343,26 +722,27 @@ function WarningIcon() {
343
722
  function ValidationTimeTip({
344
723
  timeFrame
345
724
  }) {
725
+ const { t } = useCommunityTaskLocale();
346
726
  const startDate = formatDate$1(normalizeTimestamp(timeFrame.start_time));
347
727
  const endDate = formatDate$1(normalizeTimestamp(timeFrame.end_time));
348
728
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-validation-tip", children: [
349
729
  /* @__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
- ] })
730
+ /* @__PURE__ */ jsx("p", { className: "taskon-community-validation-tip-text", children: t("task_verify_warning", {
731
+ start: startDate,
732
+ end: endDate
733
+ }) })
357
734
  ] });
358
735
  }
359
736
  function CheckProgressTip({
360
737
  communityName,
361
738
  contactLink
362
739
  }) {
740
+ const { t } = useCommunityTaskLocale();
363
741
  if (!communityName) {
364
742
  return null;
365
743
  }
744
+ const textTemplate = t("contact_to_check_progress", { name: "{name}" });
745
+ const [prefixText = "", suffixText = ""] = textTemplate.split("{name}");
366
746
  const handleLinkClick = (e) => {
367
747
  e.stopPropagation();
368
748
  if (contactLink) {
@@ -370,7 +750,7 @@ function CheckProgressTip({
370
750
  }
371
751
  };
372
752
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-progress-tip", children: [
373
- /* @__PURE__ */ jsx("span", { children: "Contact " }),
753
+ /* @__PURE__ */ jsx("span", { children: prefixText }),
374
754
  contactLink ? /* @__PURE__ */ jsx(
375
755
  "span",
376
756
  {
@@ -379,7 +759,7 @@ function CheckProgressTip({
379
759
  children: communityName
380
760
  }
381
761
  ) : /* @__PURE__ */ jsx("span", { className: "taskon-community-task-progress-tip-name", children: communityName }),
382
- /* @__PURE__ */ jsx("span", { children: " to check your progress" })
762
+ /* @__PURE__ */ jsx("span", { children: suffixText })
383
763
  ] });
384
764
  }
385
765
  function ProgressUi({
@@ -472,6 +852,7 @@ function BlingSvg({ className }) {
472
852
  function BaseTask(props) {
473
853
  const authFromContext = useOptionalAuth();
474
854
  const { showToast } = useToast();
855
+ const { t } = useCommunityTaskLocale();
475
856
  const {
476
857
  title,
477
858
  isWon,
@@ -534,6 +915,12 @@ function BaseTask(props) {
534
915
  if (!availableUnit || !totalUnit) return 0;
535
916
  return Number((availableUnit / totalUnit * 100).toFixed(2));
536
917
  }, [reward]);
918
+ const recurrenceBadgeLabel = useMemo(() => {
919
+ if (!recurrenceLabel) {
920
+ return void 0;
921
+ }
922
+ return getRecurrenceLabel(t, recurrenceLabel);
923
+ }, [recurrenceLabel, t]);
537
924
  const handleActionClick = (e) => {
538
925
  e.stopPropagation();
539
926
  if (actionAutoDialog && onClick) {
@@ -557,8 +944,8 @@ function BaseTask(props) {
557
944
  return { successful: false };
558
945
  }, [onClaim, isSubmitting]);
559
946
  const handleBindFailed = useCallback(
560
- (error) => {
561
- showToast(error, "error");
947
+ (error2) => {
948
+ showToast(error2, "error");
562
949
  },
563
950
  [showToast]
564
951
  );
@@ -581,7 +968,7 @@ function BaseTask(props) {
581
968
  ] }) });
582
969
  }
583
970
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-time", children: [
584
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-label", children: "Valid Until:" }),
971
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-label", children: t("valid_util_is") }),
585
972
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-time-value", children: validTime.endTime })
586
973
  ] });
587
974
  };
@@ -589,7 +976,7 @@ function BaseTask(props) {
589
976
  if (!reward || reward.type === "none") {
590
977
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won", children: [
591
978
  /* @__PURE__ */ jsx(IconCheckedTask, { className: "taskon-community-task-won-checked" }),
592
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-text", children: "Completed" })
979
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-text", children: t("task_completed") })
593
980
  ] });
594
981
  }
595
982
  if (reward.type === "points") {
@@ -598,12 +985,13 @@ function BaseTask(props) {
598
985
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-single", children: reward.amount }),
599
986
  /* @__PURE__ */ jsxs("span", { className: "taskon-community-task-won-label", children: [
600
987
  reward.name,
601
- "/Time"
988
+ t("per_time")
602
989
  ] }),
603
990
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-total", children: reward.totalAmount }),
604
991
  /* @__PURE__ */ jsxs("span", { className: "taskon-community-task-won-earned", children: [
605
992
  reward.name,
606
- " earned"
993
+ " ",
994
+ t("earned")
607
995
  ] })
608
996
  ] });
609
997
  }
@@ -622,7 +1010,7 @@ function BaseTask(props) {
622
1010
  )
623
1011
  ] }),
624
1012
  /* @__PURE__ */ jsx(BlingSvg, { className: "taskon-community-task-won-bling" }),
625
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: "Won" })
1013
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: t("won") })
626
1014
  ] });
627
1015
  }
628
1016
  if (reward.type === "token" && reward.token) {
@@ -630,7 +1018,7 @@ function BaseTask(props) {
630
1018
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won taskon-community-task-won--periodic", children: [
631
1019
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-single", children: reward.token.amount }),
632
1020
  /* @__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" })
1021
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-earned", children: t("earned") })
634
1022
  ] });
635
1023
  }
636
1024
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-task-won", children: [
@@ -638,7 +1026,7 @@ function BaseTask(props) {
638
1026
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-amount", children: reward.token.amount }),
639
1027
  /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-name", children: reward.token.name }),
640
1028
  /* @__PURE__ */ jsx(BlingSvg, { className: "taskon-community-task-won-bling" }),
641
- /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: "Won" })
1029
+ /* @__PURE__ */ jsx("span", { className: "taskon-community-task-won-status", children: t("won") })
642
1030
  ] });
643
1031
  }
644
1032
  return null;
@@ -646,7 +1034,7 @@ function BaseTask(props) {
646
1034
  const renderRewardInfo = () => {
647
1035
  if (!reward || reward.type === "none") return null;
648
1036
  if (reward.type === "points") {
649
- const nameSuffix = isPeriodic ? "/Time" : "";
1037
+ const nameSuffix = isPeriodic ? t("per_time") : "";
650
1038
  let displayAmount = reward.amount ?? 0;
651
1039
  if (recurrence === "Unlimited") {
652
1040
  const totalAmount = reward.totalAmount ?? 0;
@@ -694,10 +1082,10 @@ function BaseTask(props) {
694
1082
  const renderClaimArea = () => {
695
1083
  if (noClaim) return null;
696
1084
  if (reviewResult === TaskReviewResult.Failed) {
697
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--failed", children: "Oops! Failed" });
1085
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--failed", children: t("oops_failed") });
698
1086
  }
699
1087
  if (reviewResult === TaskReviewResult.UnReviewed) {
700
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--review", children: "Under Review" });
1088
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-task-review-status taskon-community-task-review-status--review", children: t("under_review") });
701
1089
  }
702
1090
  if (coolDown > 0) {
703
1091
  return /* @__PURE__ */ jsx(ClaimRetry, { leftMillSecond: coolDown, onComplete: onCoolDownComplete });
@@ -742,7 +1130,7 @@ function BaseTask(props) {
742
1130
  className: `taskon-community-task ${isCompleted ? "taskon-community-task--won" : ""} ${disabled ? "taskon-community-task--disabled" : ""}`,
743
1131
  onClick: handleCardClick,
744
1132
  children: [
745
- recurrenceLabel && !noRecurrence && /* @__PURE__ */ jsx("div", { className: "taskon-community-task-badge", children: recurrenceLabel }),
1133
+ recurrenceBadgeLabel && !noRecurrence && /* @__PURE__ */ jsx("div", { className: "taskon-community-task-badge", children: recurrenceBadgeLabel }),
746
1134
  disabled && /* @__PURE__ */ jsx(
747
1135
  "div",
748
1136
  {
@@ -862,7 +1250,8 @@ function CardField({
862
1250
  link,
863
1251
  copy_text
864
1252
  }) {
865
- const [copied, setCopied] = useState(false);
1253
+ const [copied2, setCopied] = useState(false);
1254
+ const { t } = useCommunityTaskLocale();
866
1255
  const handleCopy = async (e) => {
867
1256
  e.preventDefault();
868
1257
  e.stopPropagation();
@@ -892,9 +1281,9 @@ function CardField({
892
1281
  "button",
893
1282
  {
894
1283
  type: "button",
895
- className: `taskon-community-task-field-copy ${copied ? "taskon-community-task-field-copy--copied" : ""}`,
1284
+ className: `taskon-community-task-field-copy ${copied2 ? "taskon-community-task-field-copy--copied" : ""}`,
896
1285
  onClick: handleCopy,
897
- title: copied ? "Copied!" : "Copy to clipboard",
1286
+ title: copied2 ? t("copied") : t("copy_to_clipboard"),
898
1287
  children: /* @__PURE__ */ jsx(CopyIcon, { className: "taskon-community-task-field-copy-icon" })
899
1288
  }
900
1289
  )
@@ -1058,6 +1447,7 @@ function ConditionItem({
1058
1447
  condition,
1059
1448
  onTaskClick
1060
1449
  }) {
1450
+ const { t } = useCommunityTaskLocale();
1061
1451
  const payload = useMemo(() => {
1062
1452
  return parseConditionParams(condition.condition_params);
1063
1453
  }, [condition.condition_params]);
@@ -1066,34 +1456,35 @@ function ConditionItem({
1066
1456
  if (type === EligibilityType.CommunityUserLevel) {
1067
1457
  const params = payload;
1068
1458
  if (params.operator === Operator.Gte) {
1069
- return `Reach level ${params.level} or above`;
1459
+ return t("level_above", { val: params.level });
1070
1460
  }
1071
- return `is lower than level ${params.level}`;
1461
+ return t("level_below", { val: params.level });
1072
1462
  }
1073
1463
  if (type === EligibilityType.DiscordRole) {
1074
1464
  const params = payload;
1075
1465
  if (params.operator === Operator.Is) {
1076
- return `Discord role is ${params.role}`;
1466
+ return t("discord_role_is_val", { val: params.role });
1077
1467
  }
1078
- return `Discord role is not ${params.role}`;
1468
+ return t("discord_role_is_not_val", { val: params.role });
1079
1469
  }
1080
1470
  if (type === EligibilityType.TokenBalance) {
1081
1471
  const params = payload;
1082
- return `Own at least ${params.amount} ${params.token_name} on ${params.chain_label}`;
1472
+ return t("nft_token_label", {
1473
+ amt: params.amount,
1474
+ token: params.token_name,
1475
+ chain: params.chain_label
1476
+ });
1083
1477
  }
1084
1478
  if (type === EligibilityType.NftHolder) {
1085
1479
  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 };
1480
+ return t("nft_token_label", {
1481
+ amt: params.amount,
1482
+ token: params.nft_name,
1483
+ chain: params.chain_label
1484
+ });
1094
1485
  }
1095
1486
  return "";
1096
- }, [condition.condition_type, payload]);
1487
+ }, [condition.condition_type, payload, t]);
1097
1488
  const renderStatusIcon = () => {
1098
1489
  switch (condition.status) {
1099
1490
  case MeetConditionStatus.passed:
@@ -1108,7 +1499,8 @@ function ConditionItem({
1108
1499
  if (condition.condition_type === EligibilityType.CommunityPreTask) {
1109
1500
  const params = payload;
1110
1501
  const isCompleted = params.operator === Operator.Is;
1111
- const prefix2 = isCompleted ? "Completed " : "Not Completed ";
1502
+ const template = isCompleted ? t("complete_task", { val: "{val}" }) : t("not_complete_task", { val: "{val}" });
1503
+ const [prefix2 = "", suffix = ""] = template.split("{val}");
1112
1504
  const canClick = onTaskClick && params.task_id;
1113
1505
  return /* @__PURE__ */ jsxs("span", { className: "taskon-eligibility-mask-item-text", children: [
1114
1506
  prefix2,
@@ -1130,15 +1522,13 @@ function ConditionItem({
1130
1522
  },
1131
1523
  children: params.task_name
1132
1524
  }
1133
- ) : /* @__PURE__ */ jsx("span", { children: params.task_name })
1525
+ ) : /* @__PURE__ */ jsx("span", { children: params.task_name }),
1526
+ suffix
1134
1527
  ] });
1135
1528
  }
1136
- if (typeof typeLabel === "string") {
1137
- return /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-item-text", children: typeLabel });
1138
- }
1139
- return null;
1529
+ return /* @__PURE__ */ jsx("span", { className: "taskon-eligibility-mask-item-text", children: typeLabel });
1140
1530
  };
1141
- if (!typeLabel) {
1531
+ if (!typeLabel && condition.condition_type !== EligibilityType.CommunityPreTask) {
1142
1532
  return /* @__PURE__ */ jsx(Fragment, {});
1143
1533
  }
1144
1534
  return /* @__PURE__ */ jsxs("div", { className: "taskon-eligibility-mask-item", children: [
@@ -1152,7 +1542,8 @@ function UserEligibilityMask({
1152
1542
  onCheck,
1153
1543
  onTaskClick
1154
1544
  }) {
1155
- const [loading, setLoading] = useState(false);
1545
+ const { t } = useCommunityTaskLocale();
1546
+ const [loading2, setLoading] = useState(false);
1156
1547
  const rewardInfo = useMemo(() => {
1157
1548
  if (!task.reward || task.reward.length === 0) return null;
1158
1549
  const pointsReward = task.reward.find(
@@ -1176,7 +1567,7 @@ function UserEligibilityMask({
1176
1567
  return null;
1177
1568
  }, [task.reward]);
1178
1569
  const handleCheck = useCallback(async () => {
1179
- if (loading || !onCheck) return;
1570
+ if (loading2 || !onCheck) return;
1180
1571
  const result = onCheck();
1181
1572
  if (result instanceof Promise) {
1182
1573
  setLoading(true);
@@ -1186,7 +1577,7 @@ function UserEligibilityMask({
1186
1577
  setLoading(false);
1187
1578
  }
1188
1579
  }
1189
- }, [loading, onCheck]);
1580
+ }, [loading2, onCheck]);
1190
1581
  const renderRewardInfo = () => {
1191
1582
  if (!rewardInfo) return null;
1192
1583
  if (rewardInfo.type === "points") {
@@ -1209,15 +1600,7 @@ function UserEligibilityMask({
1209
1600
  };
1210
1601
  const renderConditionTitle = () => {
1211
1602
  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
- ] });
1603
+ 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
1604
  };
1222
1605
  return /* @__PURE__ */ jsxs("div", { className: "taskon-eligibility-mask", children: [
1223
1606
  renderRewardInfo(),
@@ -1228,17 +1611,17 @@ function UserEligibilityMask({
1228
1611
  "button",
1229
1612
  {
1230
1613
  type: "button",
1231
- className: `taskon-eligibility-mask-check-btn${loading ? " taskon-eligibility-mask-check-btn--loading" : ""}`,
1614
+ className: `taskon-eligibility-mask-check-btn${loading2 ? " taskon-eligibility-mask-check-btn--loading" : ""}`,
1232
1615
  onClick: handleCheck,
1233
- disabled: loading,
1616
+ disabled: loading2,
1234
1617
  children: [
1235
1618
  /* @__PURE__ */ jsx(
1236
1619
  ReloadIcon,
1237
1620
  {
1238
- className: `taskon-eligibility-mask-reload-icon${loading ? " taskon-eligibility-mask-reload-icon--spinning" : ""}`
1621
+ className: `taskon-eligibility-mask-reload-icon${loading2 ? " taskon-eligibility-mask-reload-icon--spinning" : ""}`
1239
1622
  }
1240
1623
  ),
1241
- "Check"
1624
+ t("check")
1242
1625
  ]
1243
1626
  }
1244
1627
  )
@@ -1275,14 +1658,7 @@ function useTaskState(task, userStatus) {
1275
1658
  }
1276
1659
  const isCompleted = (userStatus == null ? void 0 : userStatus.current_completed) || false;
1277
1660
  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;
1661
+ const recurrenceLabel = task.recurrence;
1286
1662
  let showUnlimitedClaim = true;
1287
1663
  if (task.recurrence === "Unlimited") {
1288
1664
  const totalPointAmount = ((_a = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a.amount) ?? 0;
@@ -1371,22 +1747,25 @@ const isBlankMessage = (message) => {
1371
1747
  const isDiscordNotJoinedError = (errorCode) => {
1372
1748
  return errorCode === ErrorCode.DISCORD_USRE_NOT_IN_GROUP || errorCode === DISCORD_USER_NOT_IN_CHANNEL_CODE;
1373
1749
  };
1374
- const resolveCommunityTaskSubmitErrorMessage = (error, errorCode) => {
1375
- const errorMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "";
1750
+ const resolveCommunityTaskSubmitErrorMessage = (error2, options) => {
1751
+ const errorCode = options == null ? void 0 : options.errorCode;
1752
+ const t = options == null ? void 0 : options.t;
1753
+ const errorMessage = error2 instanceof Error ? error2.message : typeof error2 === "string" ? error2 : "";
1376
1754
  if (!isBlankMessage(errorMessage)) {
1377
1755
  return errorMessage;
1378
1756
  }
1379
1757
  if (isDiscordNotJoinedError(errorCode)) {
1380
- return DISCORD_JOIN_REQUIRED_FALLBACK_MESSAGE;
1758
+ return t ? t("join_required_discord_channel") : DISCORD_JOIN_REQUIRED_FALLBACK_MESSAGE;
1381
1759
  }
1382
- return DEFAULT_SUBMIT_TASK_ERROR_MESSAGE;
1760
+ return t ? t("submission_failed") : DEFAULT_SUBMIT_TASK_ERROR_MESSAGE;
1383
1761
  };
1384
1762
  function useSubmitTask(taskId, onSuccess, platform, options) {
1763
+ const { t } = useCommunityTaskLocale();
1385
1764
  const { refreshOnFail = false } = options ?? {};
1386
1765
  const { client, userToken, userInfo } = useTaskOnContext();
1387
1766
  const { toast } = useToast();
1388
1767
  const [isSubmitting, setIsSubmitting] = useState(false);
1389
- const [error, setError] = useState(null);
1768
+ const [error2, setError] = useState(null);
1390
1769
  const getSnsUserName = useCallback((platformName) => {
1391
1770
  if (!(userInfo == null ? void 0 : userInfo.sns)) return "";
1392
1771
  const snsTypeMap = {
@@ -1407,13 +1786,13 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1407
1786
  }
1408
1787
  };
1409
1788
  if (!userToken) {
1410
- const errorMsg = "Please login first";
1789
+ const errorMsg = t("community_login_first");
1411
1790
  setError(errorMsg);
1412
1791
  toast.error(errorMsg);
1413
1792
  return { successful: false, error: errorMsg };
1414
1793
  }
1415
1794
  if (!client) {
1416
- const errorMsg = "Client not initialized";
1795
+ const errorMsg = t("client_not_initialized");
1417
1796
  setError(errorMsg);
1418
1797
  toast.error(errorMsg);
1419
1798
  return { successful: false, error: errorMsg };
@@ -1438,23 +1817,27 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1438
1817
  } else {
1439
1818
  if (platform === "Twitter") {
1440
1819
  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);
1820
+ toast.error(t("twitter_delay_error", { name }), 1e4);
1442
1821
  } else if (platform === "Discord") {
1443
1822
  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);
1823
+ toast.error(t("discord_delay_error", { name }), 1e4);
1445
1824
  } else if (platform === "Telegram") {
1446
1825
  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);
1826
+ toast.error(t("telegram_delay_error", { name }), 1e4);
1448
1827
  } else {
1449
- toast.error("Oops! You did not pass this task.");
1828
+ toast.error(t("you_not_pass"));
1450
1829
  }
1451
1830
  refreshOnFailure();
1452
1831
  return { successful: false };
1453
1832
  }
1454
1833
  } 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);
1834
+ const apiError = err;
1835
+ const errorCode = apiError == null ? void 0 : apiError.code;
1836
+ const errorData = apiError == null ? void 0 : apiError.data;
1837
+ const errorMsg = resolveCommunityTaskSubmitErrorMessage(err, {
1838
+ errorCode,
1839
+ t
1840
+ });
1458
1841
  setError(errorMsg);
1459
1842
  console.error("Submit task failed:", err);
1460
1843
  if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
@@ -1467,7 +1850,12 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1467
1850
  }
1468
1851
  if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
1469
1852
  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.`);
1853
+ toast.error(
1854
+ t("discord_invites_err", {
1855
+ invited,
1856
+ need: Math.max(min_required - invited, 0)
1857
+ })
1858
+ );
1471
1859
  refreshOnFailure();
1472
1860
  return {
1473
1861
  successful: false,
@@ -1486,7 +1874,7 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1486
1874
  setIsSubmitting(false);
1487
1875
  }
1488
1876
  },
1489
- [taskId, client, userToken, onSuccess, platform, toast, getSnsUserName, refreshOnFail]
1877
+ [taskId, client, userToken, onSuccess, platform, toast, getSnsUserName, refreshOnFail, t]
1490
1878
  );
1491
1879
  return {
1492
1880
  /** 提交任务函数 */
@@ -1494,15 +1882,16 @@ function useSubmitTask(taskId, onSuccess, platform, options) {
1494
1882
  /** 是否正在提交 */
1495
1883
  isSubmitting,
1496
1884
  /** 错误信息 */
1497
- error
1885
+ error: error2
1498
1886
  };
1499
1887
  }
1500
1888
  function useTaskDetail(options) {
1501
1889
  const { taskId } = options;
1890
+ const { t } = useCommunityTaskLocale();
1502
1891
  const { client } = useTaskOnContext();
1503
1892
  const [data, setData] = useState(null);
1504
1893
  const [isLoading, setIsLoading] = useState(false);
1505
- const [error, setError] = useState(null);
1894
+ const [error2, setError] = useState(null);
1506
1895
  const fetchDetail = useCallback(async () => {
1507
1896
  if (!taskId || !client) {
1508
1897
  setData(null);
@@ -1518,19 +1907,19 @@ function useTaskDetail(options) {
1518
1907
  });
1519
1908
  setData(detail);
1520
1909
  } catch (err) {
1521
- setError(err instanceof Error ? err.message : "Failed to load task");
1910
+ setError(err instanceof Error ? err.message : t("failed_to_load"));
1522
1911
  setData(null);
1523
1912
  } finally {
1524
1913
  setIsLoading(false);
1525
1914
  }
1526
- }, [taskId, client]);
1915
+ }, [taskId, client, t]);
1527
1916
  useEffect(() => {
1528
1917
  fetchDetail();
1529
1918
  }, [fetchDetail]);
1530
1919
  return {
1531
1920
  data,
1532
1921
  isLoading,
1533
- error,
1922
+ error: error2,
1534
1923
  refetch: fetchDetail
1535
1924
  };
1536
1925
  }
@@ -1763,6 +2152,7 @@ function PowTask({
1763
2152
  onDoneCountdownComplete
1764
2153
  }) {
1765
2154
  var _a;
2155
+ const { t } = useCommunityTaskLocale();
1766
2156
  const params = useMemo(() => {
1767
2157
  try {
1768
2158
  return JSON.parse(task.template.params);
@@ -1786,9 +2176,9 @@ function PowTask({
1786
2176
  return (userStatus == null ? void 0 : userStatus.current_completed) ?? false;
1787
2177
  }, [userStatus == null ? void 0 : userStatus.current_completed]);
1788
2178
  const actionLabel = useMemo(() => {
1789
- if (isUnderReview || isFailedButCanRetry) return "Re-Submit";
1790
- return "Submit";
1791
- }, [isUnderReview, isFailedButCanRetry]);
2179
+ if (isUnderReview || isFailedButCanRetry) return t("resubmit");
2180
+ return t("submit");
2181
+ }, [isUnderReview, isFailedButCanRetry, t]);
1792
2182
  const alwaysShowAction = useMemo(() => {
1793
2183
  return isUnderReview || isFailedButCanRetry;
1794
2184
  }, [isUnderReview, isFailedButCanRetry]);
@@ -1812,7 +2202,7 @@ function PowTask({
1812
2202
  return {
1813
2203
  type: "points",
1814
2204
  amount: rewardParams.amount || 0,
1815
- name: rewardParams.points_name || "Points",
2205
+ name: rewardParams.points_name || t("community_points"),
1816
2206
  icon: rewardParams.points_icon
1817
2207
  };
1818
2208
  }
@@ -1882,6 +2272,7 @@ function ContractInteractiveTask({
1882
2272
  onDoneCountdownComplete
1883
2273
  }) {
1884
2274
  var _a, _b;
2275
+ const { t } = useCommunityTaskLocale();
1885
2276
  const [localCoolDown, setLocalCoolDown] = useState(
1886
2277
  () => (userStatus == null ? void 0 : userStatus.waiting_cool_down) ?? 0
1887
2278
  );
@@ -1968,7 +2359,7 @@ function ContractInteractiveTask({
1968
2359
  recurrenceLabel: task.recurrence,
1969
2360
  taskId: task.id,
1970
2361
  // 固定按钮文案,复刻原版 t('proceed_2_complete_the_task')
1971
- actionLabel: "Proceed to complete the task",
2362
+ actionLabel: t("proceed_2_complete_the_task"),
1972
2363
  // 使用 task_url 作为按钮链接
1973
2364
  actionLink: params.task_url,
1974
2365
  // 需要验证后才能 Claim
@@ -1989,7 +2380,7 @@ function ContractInteractiveTask({
1989
2380
  return {
1990
2381
  type: "points",
1991
2382
  amount: rewardParams.amount || 0,
1992
- name: rewardParams.points_name || "Points",
2383
+ name: rewardParams.points_name || t("community_points"),
1993
2384
  icon: rewardParams.points_icon,
1994
2385
  totalAmount: (_a2 = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a2.amount
1995
2386
  };
@@ -2059,6 +2450,7 @@ function SwapDexTask({
2059
2450
  onDoneCountdownComplete
2060
2451
  }) {
2061
2452
  var _a, _b;
2453
+ const { t } = useCommunityTaskLocale();
2062
2454
  const [localCoolDown, setLocalCoolDown] = useState(
2063
2455
  () => (userStatus == null ? void 0 : userStatus.waiting_cool_down) ?? 0
2064
2456
  );
@@ -2097,13 +2489,13 @@ function SwapDexTask({
2097
2489
  tokenInList: params.token_in_list,
2098
2490
  chainLabel,
2099
2491
  // 优先使用 task.project_name,其次使用 community name
2100
- dexName: task.project_name || (contextCommunityInfo == null ? void 0 : contextCommunityInfo.name) || "DEX",
2492
+ dexName: task.project_name || (contextCommunityInfo == null ? void 0 : contextCommunityInfo.name) || t("community_dex"),
2101
2493
  dexLink: params.task_url,
2102
2494
  isFixedReward: params.is_fixed_reward_type || false,
2103
2495
  minTradingVolume: params.min_trading_volume,
2104
2496
  minTradesTimes: params.min_trades_times
2105
2497
  });
2106
- }, [params, chainLabel, task.project_name, contextCommunityInfo == null ? void 0 : contextCommunityInfo.name]);
2498
+ }, [params, chainLabel, task.project_name, contextCommunityInfo == null ? void 0 : contextCommunityInfo.name, t]);
2107
2499
  const titleNode = useMemo(() => {
2108
2500
  return /* @__PURE__ */ jsx(TitleExpress, { express: titleExpress });
2109
2501
  }, [titleExpress]);
@@ -2178,7 +2570,7 @@ function SwapDexTask({
2178
2570
  validTime: validTimeProp,
2179
2571
  validationTimeFrame,
2180
2572
  chainType,
2181
- actionLabel: "Swap",
2573
+ actionLabel: t("swap"),
2182
2574
  actionLink: params.task_url,
2183
2575
  verifyClaim: true,
2184
2576
  currentCompleted: userStatus == null ? void 0 : userStatus.current_completed,
@@ -2434,6 +2826,7 @@ function TaskChainCard({
2434
2826
  className = "",
2435
2827
  onOpen
2436
2828
  }) {
2829
+ const { t } = useCommunityTaskLocale();
2437
2830
  const isLocked = useMemo(() => {
2438
2831
  return isLockedByPreDayChallenge(meetConditions);
2439
2832
  }, [meetConditions]);
@@ -2459,10 +2852,10 @@ function TaskChainCard({
2459
2852
  });
2460
2853
  return {
2461
2854
  icon: params.token_icon || TOKEN_ICON,
2462
- name: params.token_name || "",
2855
+ name: params.token_name || t("taskchain_token_fallback"),
2463
2856
  amount
2464
2857
  };
2465
- }, [taskChain.reward_list]);
2858
+ }, [taskChain.reward_list, t]);
2466
2859
  const pointsReward = useMemo(() => {
2467
2860
  const reward = taskChain.reward_list.find(
2468
2861
  (r) => r.reward_type === RewardType.GTCPoints
@@ -2472,10 +2865,10 @@ function TaskChainCard({
2472
2865
  if (!params) return null;
2473
2866
  return {
2474
2867
  icon: params.points_icon || POINTS_ICON,
2475
- name: params.points_name || "Points",
2868
+ name: params.points_name || t("taskchain_points_fallback"),
2476
2869
  amount: params.amount || 0
2477
2870
  };
2478
- }, [taskChain.reward_list]);
2871
+ }, [taskChain.reward_list, t]);
2479
2872
  const nftReward = useMemo(() => {
2480
2873
  const reward = taskChain.reward_list.find(
2481
2874
  (r) => r.reward_type === RewardType.BMintedNft
@@ -2486,9 +2879,9 @@ function TaskChainCard({
2486
2879
  const icon = params.media_type === MediaType.Video || !params.nft_cdn_image ? NFT_ICON$1 : getMiniNftCdnUrl$1(params.nft_cdn_image);
2487
2880
  return {
2488
2881
  icon,
2489
- name: params.nft_collection_name || "NFT"
2882
+ name: params.nft_collection_name || t("taskchain_nft_fallback")
2490
2883
  };
2491
- }, [taskChain.reward_list]);
2884
+ }, [taskChain.reward_list, t]);
2492
2885
  const handleClick = useCallback(() => {
2493
2886
  if (disabled || isEnded || isLocked) return;
2494
2887
  onOpen == null ? void 0 : onOpen(taskChain.id);
@@ -2512,7 +2905,7 @@ function TaskChainCard({
2512
2905
  children: [
2513
2906
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-card-name", children: taskChain.name }),
2514
2907
  taskChain.token_reward_quantity > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-card-spots", children: [
2515
- /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-card-spots-label", children: "Spots left" }),
2908
+ /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-card-spots-label", children: t("taskchain_spots_left") }),
2516
2909
  /* @__PURE__ */ jsxs("span", { children: [
2517
2910
  taskChain.token_reward_left_quantity,
2518
2911
  "/",
@@ -2565,15 +2958,15 @@ function TaskChainCard({
2565
2958
  )
2566
2959
  ] })
2567
2960
  ] }),
2568
- isCompleted && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-card-won", children: "Won" })
2961
+ isCompleted && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-card-won", children: t("taskchain_won") })
2569
2962
  ] }),
2570
- isEnded && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-card-overlay taskon-taskchain-card-overlay--ended", children: /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-card-overlay-text", children: "Ended" }) }),
2963
+ isEnded && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-card-overlay taskon-taskchain-card-overlay--ended", children: /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-card-overlay-text", children: t("taskchain_ended") }) }),
2571
2964
  isLocked && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-card-overlay taskon-taskchain-card-overlay--locked", children: [
2572
2965
  /* @__PURE__ */ jsx(
2573
2966
  "img",
2574
2967
  {
2575
2968
  src: LOCK_ICON,
2576
- alt: "Locked",
2969
+ alt: t("taskchain_locked"),
2577
2970
  className: "taskon-taskchain-card-lock-icon"
2578
2971
  }
2579
2972
  ),
@@ -2582,22 +2975,19 @@ function TaskChainCard({
2582
2975
  "img",
2583
2976
  {
2584
2977
  src: LOCK_ICON,
2585
- alt: "Locked",
2978
+ alt: t("taskchain_locked"),
2586
2979
  className: "taskon-taskchain-card-lock-icon"
2587
2980
  }
2588
2981
  ),
2589
2982
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-card-lock-text", children: [
2590
2983
  /* @__PURE__ */ jsxs("div", { children: [
2591
- "Complete the",
2984
+ t("taskchain_unlock_prefix"),
2592
2985
  " ",
2593
- /* @__PURE__ */ jsxs("span", { className: "taskon-taskchain-card-lock-highlight", children: [
2594
- "Day ",
2595
- previousDayNumber,
2596
- " challenge"
2597
- ] }),
2598
- ","
2986
+ /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-card-lock-highlight", children: t("taskchain_unlock_day_challenge", {
2987
+ day: previousDayNumber
2988
+ }) })
2599
2989
  ] }),
2600
- /* @__PURE__ */ jsx("div", { children: "then wait until next day to unlock" })
2990
+ /* @__PURE__ */ jsx("div", { children: t("taskchain_unlock_suffix") })
2601
2991
  ] })
2602
2992
  ] })
2603
2993
  ] })
@@ -2643,11 +3033,12 @@ function useTaskChainStore(options) {
2643
3033
  function useTaskChainDetail(options) {
2644
3034
  const { campaignId, enabled = true } = options;
2645
3035
  const { client, isLoggedIn } = useTaskOnContext();
3036
+ const { t } = useCommunityTaskLocale();
2646
3037
  const [campaign, setCampaign] = useState(null);
2647
3038
  const [userStatus, setUserStatus] = useState(null);
2648
3039
  const [campaignStatusInfo, setCampaignStatusInfo] = useState(null);
2649
3040
  const [isLoading, setIsLoading] = useState(false);
2650
- const [error, setError] = useState(null);
3041
+ const [error2, setError] = useState(null);
2651
3042
  const api = useMemo(() => {
2652
3043
  if (!client) return null;
2653
3044
  return createQuestApi(client);
@@ -2658,22 +3049,22 @@ function useTaskChainDetail(options) {
2658
3049
  const result = await api.getCampaignInfo({ campaign_id: campaignId });
2659
3050
  setCampaign(result);
2660
3051
  } catch (err) {
2661
- const errorMessage = err instanceof Error ? err.message : "Failed to load campaign info";
3052
+ const errorMessage = err instanceof Error ? err.message : t("taskchain_error_load_campaign_info");
2662
3053
  setError(errorMessage);
2663
3054
  console.error("[useTaskChainDetail] Error loading campaign:", err);
2664
3055
  }
2665
- }, [enabled, api, campaignId]);
3056
+ }, [enabled, api, campaignId, t]);
2666
3057
  const fetchUserStatus = useCallback(async () => {
2667
3058
  if (!enabled || !api || !campaignId || !isLoggedIn) return;
2668
3059
  try {
2669
3060
  const result = await api.getUserCampaignStatus({ campaign_id: campaignId });
2670
3061
  setUserStatus(result);
2671
3062
  } catch (err) {
2672
- const errorMessage = err instanceof Error ? err.message : "Failed to load user status";
3063
+ const errorMessage = err instanceof Error ? err.message : t("taskchain_error_load_user_status");
2673
3064
  setError(errorMessage);
2674
3065
  console.error("[useTaskChainDetail] Error loading user status:", err);
2675
3066
  }
2676
- }, [enabled, api, campaignId, isLoggedIn]);
3067
+ }, [enabled, api, campaignId, isLoggedIn, t]);
2677
3068
  const fetchCampaignStatusInfo = useCallback(async () => {
2678
3069
  if (!enabled || !api || !campaignId) return;
2679
3070
  try {
@@ -2738,7 +3129,7 @@ function useTaskChainDetail(options) {
2738
3129
  userStatus,
2739
3130
  campaignStatusInfo,
2740
3131
  isLoading,
2741
- error,
3132
+ error: error2,
2742
3133
  refetchCampaign: fetchCampaign,
2743
3134
  refetchUserStatus: fetchUserStatus,
2744
3135
  updateTaskStatus
@@ -2751,6 +3142,7 @@ function StepIndicator({
2751
3142
  children,
2752
3143
  className = ""
2753
3144
  }) {
3145
+ const { t } = useCommunityTaskLocale();
2754
3146
  const stepBars = Array.from({ length: count }, (_, index) => {
2755
3147
  const isCompleted = index < currentStep + 1;
2756
3148
  return /* @__PURE__ */ jsx(
@@ -2767,35 +3159,22 @@ function StepIndicator({
2767
3159
  "img",
2768
3160
  {
2769
3161
  src: FLAG_ICON,
2770
- alt: "Goal",
3162
+ alt: t("taskchain_goal"),
2771
3163
  className: "taskon-taskchain-step-indicator-flag"
2772
3164
  }
2773
3165
  ),
2774
3166
  children
2775
3167
  ] });
2776
3168
  }
2777
- function formatDate(timestamp) {
3169
+ function formatDate(timestamp, locale) {
2778
3170
  const ts = typeof timestamp === "string" ? parseInt(timestamp, 10) : timestamp;
2779
3171
  const ms = ts < 1e12 ? ts * 1e3 : ts;
2780
3172
  const date = new Date(ms);
2781
- const months = [
2782
- "Jan",
2783
- "Feb",
2784
- "Mar",
2785
- "Apr",
2786
- "May",
2787
- "Jun",
2788
- "Jul",
2789
- "Aug",
2790
- "Sep",
2791
- "Oct",
2792
- "Nov",
2793
- "Dec"
2794
- ];
2795
- const month = months[date.getMonth()];
2796
- const day = date.getDate().toString().padStart(2, "0");
2797
- const year = date.getFullYear();
2798
- return `${month} ${day}, ${year}`;
3173
+ return new Intl.DateTimeFormat(locale, {
3174
+ year: "numeric",
3175
+ month: "short",
3176
+ day: "2-digit"
3177
+ }).format(date);
2799
3178
  }
2800
3179
  function IconDate() {
2801
3180
  return /* @__PURE__ */ jsxs(
@@ -2833,14 +3212,16 @@ function TaskChainDetailTime({
2833
3212
  campaignStatusInfo,
2834
3213
  className = ""
2835
3214
  }) {
3215
+ const { locale } = useTaskOnContext();
3216
+ const { t } = useCommunityTaskLocale();
2836
3217
  const timeRange = useMemo(() => {
2837
3218
  if (!campaign) return "";
2838
3219
  const { start_time, end_time } = campaign;
2839
3220
  if (!start_time || !end_time) return "";
2840
- const startStr = formatDate(start_time);
2841
- const endStr = formatDate(end_time);
3221
+ const startStr = formatDate(start_time, locale);
3222
+ const endStr = formatDate(end_time, locale);
2842
3223
  return `${startStr} - ${endStr}`;
2843
- }, [campaign]);
3224
+ }, [campaign, locale]);
2844
3225
  const spots = useMemo(() => {
2845
3226
  var _a, _b, _c, _d;
2846
3227
  if (!(campaign == null ? void 0 : campaign.winner_rewards) || !((_a = campaignStatusInfo == null ? void 0 : campaignStatusInfo.statistics) == null ? void 0 : _a.winner_number))
@@ -2879,7 +3260,7 @@ function TaskChainDetailTime({
2879
3260
  ] }),
2880
3261
  timeRange && spots && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-time-divider" }),
2881
3262
  spots && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-time-item", children: [
2882
- /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-time-label", children: "Left Spots" }),
3263
+ /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-time-label", children: t("taskchain_spots_left") }),
2883
3264
  /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-time-value", children: spots })
2884
3265
  ] })
2885
3266
  ] }) });
@@ -2915,6 +3296,7 @@ function RewardDisplay({
2915
3296
  winnerRewardsSimple,
2916
3297
  className = ""
2917
3298
  }) {
3299
+ const { t } = useCommunityTaskLocale();
2918
3300
  const allRewards = useMemo(() => {
2919
3301
  return (winnerRewards == null ? void 0 : winnerRewards.flatMap(
2920
3302
  (reward) => (reward.winner_layer_rewards || []).flatMap((layer) => layer.rewards || [])
@@ -2948,17 +3330,28 @@ function RewardDisplay({
2948
3330
  totalWinners: tokenMaxWinners
2949
3331
  });
2950
3332
  }, [tokenParam, tokenHasBlindBox, tokenMaxWinners]);
3333
+ const tokenName = useMemo(
3334
+ () => (tokenParam == null ? void 0 : tokenParam.token_name) || t("taskchain_token_fallback"),
3335
+ [tokenParam == null ? void 0 : tokenParam.token_name, t]
3336
+ );
2951
3337
  const pointParam = useMemo(() => {
2952
3338
  const target = allRewards.find(
2953
3339
  (reward) => reward.reward_type === RewardType.Points || reward.reward_type === RewardType.GTCPoints
2954
3340
  );
2955
3341
  return (target == null ? void 0 : target.reward_params) || null;
2956
3342
  }, [allRewards]);
3343
+ const pointsName = useMemo(
3344
+ () => (pointParam == null ? void 0 : pointParam.points_name) || t("taskchain_points_fallback"),
3345
+ [pointParam == null ? void 0 : pointParam.points_name, t]
3346
+ );
2957
3347
  const mintedNftReward = useMemo(() => {
2958
3348
  const target = allRewards.find((reward) => reward.reward_type === RewardType.BMintedNft);
2959
3349
  return (target == null ? void 0 : target.reward_params) || null;
2960
3350
  }, [allRewards]);
2961
- const mintedNftName = useMemo(() => (mintedNftReward == null ? void 0 : mintedNftReward.nft_collection_name) || "NFT", [mintedNftReward]);
3351
+ const mintedNftName = useMemo(
3352
+ () => (mintedNftReward == null ? void 0 : mintedNftReward.nft_collection_name) || t("taskchain_nft_fallback"),
3353
+ [mintedNftReward == null ? void 0 : mintedNftReward.nft_collection_name, t]
3354
+ );
2962
3355
  const mintedNftImage = useMemo(() => {
2963
3356
  if (!mintedNftReward) return "";
2964
3357
  if (mintedNftReward.media_type === "video") return "";
@@ -2978,14 +3371,14 @@ function RewardDisplay({
2978
3371
  "img",
2979
3372
  {
2980
3373
  src: tokenParam.token_icon || DEFAULT_TOKEN_ICON$2,
2981
- alt: tokenParam.token_name || "Token",
3374
+ alt: tokenName,
2982
3375
  className: "taskon-taskchain-reward-display-icon"
2983
3376
  }
2984
3377
  ),
2985
3378
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-reward-display-text taskon-taskchain-reward-display-text--token", children: [
2986
3379
  tokenAmountDisplay,
2987
3380
  " ",
2988
- tokenParam.token_name
3381
+ tokenName
2989
3382
  ] })
2990
3383
  ] }),
2991
3384
  pointParam && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-reward-display-item", children: [
@@ -2993,14 +3386,14 @@ function RewardDisplay({
2993
3386
  "img",
2994
3387
  {
2995
3388
  src: pointParam.points_icon,
2996
- alt: pointParam.points_name || "Points",
3389
+ alt: pointsName,
2997
3390
  className: "taskon-taskchain-reward-display-icon"
2998
3391
  }
2999
3392
  ),
3000
3393
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-reward-display-text taskon-taskchain-reward-display-text--points", children: [
3001
3394
  pointParam.amount,
3002
3395
  " ",
3003
- pointParam.points_name
3396
+ pointsName
3004
3397
  ] })
3005
3398
  ] }),
3006
3399
  mintedNftReward && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-reward-display-item", children: [
@@ -3065,33 +3458,39 @@ function getMiniNftCdnUrl(url) {
3065
3458
  const separator = url.includes("?") ? "&" : "?";
3066
3459
  return `${url}${separator}x-oss-process=image/resize,m_fill,h_160,w_160`;
3067
3460
  }
3068
- const TASKCHAIN_NFT_CLAIM_MESSAGES = {
3069
- claimDialog: {
3070
- claimNft: "Claim NFT",
3071
- claimingNft: "Claiming NFT...",
3072
- claimConnectingWallet: "Connecting wallet...",
3073
- claimSwitchingNetwork: "Switching network...",
3074
- claimGettingSignature: "Getting signature...",
3075
- claimConfirmInWallet: "Please confirm in your wallet",
3076
- claimTransactionPending: "Transaction pending...",
3077
- claimSuccess: "Claim successful!",
3078
- claimFailed: "Claim failed",
3079
- claimCanceled: "Transaction was rejected by user.",
3080
- viewOnExplorer: "View on Explorer",
3081
- retry: "Retry",
3082
- close: "Close"
3083
- },
3084
- pendingDialog: {
3085
- pendingTransaction: "Pending Transaction",
3086
- claimPendingTitle: "You have already claimed this NFT, please wait for this transaction to be confirmed.",
3087
- claimPendingCheckExplorer: "You can check this transaction on explorer:",
3088
- claimPendingHashLabel: "Transaction hash:",
3089
- claimPendingClaimAgainWarn: '"Claim Again" will send a new transaction it is only recommended when you are sure there is something wrong with the current transaction.',
3090
- claimPendingReceiveAddressNoChange: "This receive address can’t be changed:",
3091
- claimAgain: "Claim Again",
3092
- continueWaiting: "Continue Waiting"
3093
- }
3094
- };
3461
+ function buildTaskChainNftClaimMessages(t) {
3462
+ return {
3463
+ claimDialog: {
3464
+ claimNft: t("taskchain_nft_claim_dialog_claim_nft"),
3465
+ claimingNft: t("taskchain_nft_claim_dialog_claiming_nft"),
3466
+ claimConnectingWallet: t("taskchain_nft_claim_dialog_connecting_wallet"),
3467
+ claimSwitchingNetwork: t("taskchain_nft_claim_dialog_switching_network"),
3468
+ claimGettingSignature: t("taskchain_nft_claim_dialog_getting_signature"),
3469
+ claimConfirmInWallet: t("taskchain_nft_claim_dialog_confirm_in_wallet"),
3470
+ claimTransactionPending: t("taskchain_nft_claim_dialog_tx_pending"),
3471
+ claimSuccess: t("taskchain_nft_claim_dialog_success"),
3472
+ claimFailed: t("taskchain_nft_claim_dialog_failed"),
3473
+ claimCanceled: t("taskchain_nft_claim_dialog_canceled"),
3474
+ viewOnExplorer: t("taskchain_nft_claim_dialog_view_explorer"),
3475
+ retry: t("taskchain_nft_claim_dialog_retry"),
3476
+ close: t("taskchain_nft_claim_dialog_close")
3477
+ },
3478
+ pendingDialog: {
3479
+ pendingTransaction: t("taskchain_nft_pending_dialog_title"),
3480
+ claimPendingTitle: t("taskchain_nft_pending_dialog_desc"),
3481
+ claimPendingCheckExplorer: t("taskchain_nft_pending_dialog_check_explorer"),
3482
+ claimPendingHashLabel: t("taskchain_nft_pending_dialog_hash_label"),
3483
+ claimPendingClaimAgainWarn: t(
3484
+ "taskchain_nft_pending_dialog_claim_again_warn"
3485
+ ),
3486
+ claimPendingReceiveAddressNoChange: t(
3487
+ "taskchain_nft_pending_dialog_receive_address_fixed"
3488
+ ),
3489
+ claimAgain: t("taskchain_nft_pending_dialog_claim_again"),
3490
+ continueWaiting: t("taskchain_nft_pending_dialog_continue_waiting")
3491
+ }
3492
+ };
3493
+ }
3095
3494
  function RightChevronIcon({ className }) {
3096
3495
  return /* @__PURE__ */ jsx(
3097
3496
  "svg",
@@ -3115,11 +3514,11 @@ function RightChevronIcon({ className }) {
3115
3514
  }
3116
3515
  );
3117
3516
  }
3118
- function getClaimedRewardDisplay(reward) {
3517
+ function getClaimedRewardDisplay(reward, labels) {
3119
3518
  if (reward.reward_type === RewardType.Token) {
3120
3519
  const rewardValue = reward.reward_value;
3121
3520
  const icon = DEFAULT_TOKEN_ICON$1;
3122
- const name = (rewardValue == null ? void 0 : rewardValue.token_name) || "Token";
3521
+ const name = (rewardValue == null ? void 0 : rewardValue.token_name) || labels.token;
3123
3522
  const rawAmount = (rewardValue == null ? void 0 : rewardValue.amount) || "0";
3124
3523
  const amount = formatLongNumber(Number(rawAmount) || 0) || rawAmount;
3125
3524
  return {
@@ -3132,7 +3531,7 @@ function getClaimedRewardDisplay(reward) {
3132
3531
  if (reward.reward_type === RewardType.GTCPoints || reward.reward_type === RewardType.Points) {
3133
3532
  const rewardValue = reward.reward_value;
3134
3533
  const icon = (rewardValue == null ? void 0 : rewardValue.points_icon) || "";
3135
- const name = (rewardValue == null ? void 0 : rewardValue.points_name) || "Points";
3534
+ const name = (rewardValue == null ? void 0 : rewardValue.points_name) || labels.points;
3136
3535
  const amount = (rewardValue == null ? void 0 : rewardValue.amount) != null ? String(rewardValue.amount) : "0";
3137
3536
  return {
3138
3537
  icon,
@@ -3154,8 +3553,20 @@ function TaskChainClaimedRewards({
3154
3553
  className
3155
3554
  }) {
3156
3555
  const { toast } = useToast();
3556
+ const { t } = useCommunityTaskLocale();
3157
3557
  const [isTokenRewardPopupOpen, setIsTokenRewardPopupOpen] = useState(false);
3158
3558
  const [isViewMyNftPopupOpen, setIsViewMyNftPopupOpen] = useState(false);
3559
+ const nftClaimMessages = useMemo(
3560
+ () => buildTaskChainNftClaimMessages(t),
3561
+ [t]
3562
+ );
3563
+ const rewardLabels = useMemo(
3564
+ () => ({
3565
+ token: t("taskchain_token_fallback"),
3566
+ points: t("taskchain_points_fallback")
3567
+ }),
3568
+ [t]
3569
+ );
3159
3570
  const {
3160
3571
  claimNftReward,
3161
3572
  isSupportedNftRewardType,
@@ -3163,12 +3574,12 @@ function TaskChainClaimedRewards({
3163
3574
  } = useNftClaimFlow({
3164
3575
  campaignId,
3165
3576
  targetType: campaignType === CampaignType.Event ? "event" : "campaign",
3166
- messages: TASKCHAIN_NFT_CLAIM_MESSAGES,
3577
+ messages: nftClaimMessages,
3167
3578
  onClaimSuccess: async () => {
3168
3579
  await (onClaimedNft == null ? void 0 : onClaimedNft());
3169
3580
  },
3170
- onClaimError: (error) => {
3171
- toast.error(error.message || "Failed to claim NFT");
3581
+ onClaimError: (error2) => {
3582
+ toast.error(error2.message || t("taskchain_nft_claim_failed"));
3172
3583
  },
3173
3584
  onWalletError: (errorMessage) => {
3174
3585
  toast.error(errorMessage);
@@ -3209,8 +3620,8 @@ function TaskChainClaimedRewards({
3209
3620
  }
3210
3621
  try {
3211
3622
  await claimNftReward(reward);
3212
- } catch (error) {
3213
- console.error("TaskChain NFT claim failed:", error);
3623
+ } catch (error2) {
3624
+ console.error("TaskChain NFT claim failed:", error2);
3214
3625
  }
3215
3626
  },
3216
3627
  [isSupportedNftRewardType, claimNftReward]
@@ -3222,12 +3633,12 @@ function TaskChainClaimedRewards({
3222
3633
  {
3223
3634
  className: `taskon-taskchain-claimed-card ${isMultiClaimed ? "taskon-taskchain-claimed-card--multi" : ""}`,
3224
3635
  children: otherClaimedRewards.map((reward, index) => {
3225
- const display = getClaimedRewardDisplay(reward);
3636
+ const display = getClaimedRewardDisplay(reward, rewardLabels);
3226
3637
  const isToken = reward.reward_type === RewardType.Token;
3227
3638
  if (isToken) {
3228
3639
  const tokenRewardValue = reward.reward_value;
3229
3640
  const rawAmount = (tokenRewardValue == null ? void 0 : tokenRewardValue.amount) || "0";
3230
- const tokenName = (tokenRewardValue == null ? void 0 : tokenRewardValue.token_name) || "Token";
3641
+ const tokenName = (tokenRewardValue == null ? void 0 : tokenRewardValue.token_name) || t("taskchain_token_fallback");
3231
3642
  const formattedAmount = formatLongNumber(Number(rawAmount) || 0) || rawAmount;
3232
3643
  const usdValue = formatTokenAmount(
3233
3644
  Number(rawAmount) * tokenPrice,
@@ -3237,7 +3648,7 @@ function TaskChainClaimedRewards({
3237
3648
  );
3238
3649
  const tooltipContent = /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-token-tooltip", children: [
3239
3650
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-token-tooltip-row", children: [
3240
- /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-token-tooltip-label", children: "Reward Token" }),
3651
+ /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-token-tooltip-label", children: t("taskchain_reward_token_label") }),
3241
3652
  /* @__PURE__ */ jsxs("span", { className: "taskon-taskchain-token-tooltip-value", children: [
3242
3653
  formattedAmount,
3243
3654
  " ",
@@ -3245,7 +3656,7 @@ function TaskChainClaimedRewards({
3245
3656
  ] })
3246
3657
  ] }),
3247
3658
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-token-tooltip-row", children: [
3248
- /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-token-tooltip-label", children: "Value" }),
3659
+ /* @__PURE__ */ jsx("span", { className: "taskon-taskchain-token-tooltip-label", children: t("taskchain_value_label") }),
3249
3660
  /* @__PURE__ */ jsxs("span", { className: "taskon-taskchain-token-tooltip-usd", children: [
3250
3661
  "≈$",
3251
3662
  usdValue
@@ -3316,13 +3727,13 @@ function TaskChainClaimedRewards({
3316
3727
  nftClaimedRewards.length > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-claimed-nft-list", children: nftClaimedRewards.map((reward, index) => {
3317
3728
  var _a;
3318
3729
  const nftValue = reward.reward_value;
3319
- const rewardTypeLabel = reward.reward_type === RewardType.Cap ? "Cap" : "NFT";
3730
+ const rewardTypeLabel = reward.reward_type === RewardType.Cap ? t("taskchain_reward_type_cap") : t("taskchain_reward_type_nft");
3320
3731
  const nftName = (nftValue == null ? void 0 : nftValue.collection_name) || (nftValue == null ? void 0 : nftValue.title) || rewardTypeLabel;
3321
3732
  const nftImage = (nftValue == null ? void 0 : nftValue.media_type) === "video" ? "" : (nftValue == null ? void 0 : nftValue.collection_image) ? getMiniNftCdnUrl(nftValue.collection_image) : "";
3322
3733
  const chainIcon = (nftValue == null ? void 0 : nftValue.chain_icon) || "";
3323
3734
  const claimable = ((_a = reward.reward_value) == null ? void 0 : _a.claimable) ?? false;
3324
3735
  const isNftClaimSupported = isSupportedNftRewardType(reward.reward_type);
3325
- const ctaLabel = claimable ? "Mint" : "View my NFT";
3736
+ const ctaLabel = claimable ? t("taskchain_nft_cta_mint") : t("taskchain_nft_cta_view");
3326
3737
  return /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-claimed-nft-card", children: [
3327
3738
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-claimed-nft-info", children: [
3328
3739
  /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-claimed-nft-image-wrap", children: [
@@ -3330,14 +3741,14 @@ function TaskChainClaimedRewards({
3330
3741
  "img",
3331
3742
  {
3332
3743
  src: nftImage,
3333
- alt: "nft",
3744
+ alt: t("taskchain_nft_alt"),
3334
3745
  className: "taskon-taskchain-claimed-nft-image"
3335
3746
  }
3336
3747
  ) : /* @__PURE__ */ jsx(
3337
3748
  "img",
3338
3749
  {
3339
3750
  src: DEFAULT_NFT_ICON,
3340
- alt: "nft",
3751
+ alt: t("taskchain_nft_alt"),
3341
3752
  className: "taskon-taskchain-claimed-nft-image taskon-taskchain-claimed-nft-image--fallback"
3342
3753
  }
3343
3754
  ),
@@ -3345,7 +3756,7 @@ function TaskChainClaimedRewards({
3345
3756
  "img",
3346
3757
  {
3347
3758
  src: chainIcon,
3348
- alt: "chain",
3759
+ alt: t("taskchain_chain_alt"),
3349
3760
  className: "taskon-taskchain-claimed-nft-chain"
3350
3761
  }
3351
3762
  )
@@ -3362,7 +3773,7 @@ function TaskChainClaimedRewards({
3362
3773
  className: "taskon-taskchain-claimed-nft-btn",
3363
3774
  onClick: () => {
3364
3775
  if (!isNftClaimSupported) {
3365
- toast.info("NFT claim is not supported for this reward type yet.");
3776
+ toast.info(t("taskchain_nft_claim_not_supported"));
3366
3777
  return;
3367
3778
  }
3368
3779
  if (!claimable) {
@@ -3478,13 +3889,13 @@ function triggerConfetti(container) {
3478
3889
  function sleep(ms) {
3479
3890
  return new Promise((resolve) => setTimeout(resolve, ms));
3480
3891
  }
3481
- function getExpectedRewardDisplay(reward) {
3892
+ function getExpectedRewardDisplay(reward, labels) {
3482
3893
  const params = reward.reward_params;
3483
3894
  if (reward.reward_type === RewardType.Token && params) {
3484
3895
  const tokenParams = params;
3485
3896
  const icon = tokenParams.token_icon || DEFAULT_TOKEN_ICON;
3486
3897
  const amount = tokenParams.per_amount || tokenParams.total_amount || "";
3487
- const name = tokenParams.token_name || "";
3898
+ const name = tokenParams.token_name || labels.token;
3488
3899
  return {
3489
3900
  icon,
3490
3901
  text: `+ ${amount} ${name}`.trim(),
@@ -3495,7 +3906,7 @@ function getExpectedRewardDisplay(reward) {
3495
3906
  const pointsParams = params;
3496
3907
  const icon = pointsParams.points_icon || "";
3497
3908
  const amount = pointsParams.amount != null ? String(pointsParams.amount) : "";
3498
- const name = pointsParams.points_name || "Points";
3909
+ const name = pointsParams.points_name || labels.points;
3499
3910
  return {
3500
3911
  icon,
3501
3912
  text: `+ ${amount} ${name}`.trim(),
@@ -3505,7 +3916,7 @@ function getExpectedRewardDisplay(reward) {
3505
3916
  if (reward.reward_type === RewardType.BMintedNft && params) {
3506
3917
  const nftParams = params;
3507
3918
  const icon = nftParams.media_type === "video" ? "" : nftParams.nft_cdn_image || "";
3508
- const name = nftParams.nft_collection_name || "NFT";
3919
+ const name = nftParams.nft_collection_name || labels.nft;
3509
3920
  return { icon, text: name, colorClass: "" };
3510
3921
  }
3511
3922
  return { icon: "", text: "", colorClass: "" };
@@ -3521,6 +3932,7 @@ function TaskChainRewardStep({
3521
3932
  }) {
3522
3933
  const { client } = useTaskOnContext();
3523
3934
  const { toast } = useToast();
3935
+ const { t } = useCommunityTaskLocale();
3524
3936
  const containerRef = useRef(null);
3525
3937
  const isMobile = useIsMobile();
3526
3938
  const initialIsClaimed = useMemo(
@@ -3570,6 +3982,14 @@ function TaskChainRewardStep({
3570
3982
  }
3571
3983
  return 0;
3572
3984
  }, [expectedRewards]);
3985
+ const rewardLabels = useMemo(
3986
+ () => ({
3987
+ token: t("taskchain_token_fallback"),
3988
+ points: t("taskchain_points_fallback"),
3989
+ nft: t("taskchain_nft_fallback")
3990
+ }),
3991
+ [t]
3992
+ );
3573
3993
  const switchToClaimedView = useCallback(async () => {
3574
3994
  setShouldAnimate(true);
3575
3995
  if (containerRef.current) {
@@ -3590,13 +4010,13 @@ function TaskChainRewardStep({
3590
4010
  });
3591
4011
  await refetchUserStatus();
3592
4012
  await switchToClaimedView();
3593
- } catch (error) {
3594
- console.error("Failed to claim reward:", error);
3595
- toast.error("Failed to submit campaign. Please try again.");
4013
+ } catch (error2) {
4014
+ console.error("Failed to claim reward:", error2);
4015
+ toast.error(t("taskchain_reward_submit_failed"));
3596
4016
  } finally {
3597
4017
  setIsLoading(false);
3598
4018
  }
3599
- }, [isLoading, campaign, api, refetchUserStatus, switchToClaimedView, toast]);
4019
+ }, [isLoading, campaign, api, refetchUserStatus, switchToClaimedView, toast, t]);
3600
4020
  const scatterStyles = useMemo(() => {
3601
4021
  const total = expectedRewards.length;
3602
4022
  return expectedRewards.map((_, index) => {
@@ -3611,8 +4031,8 @@ function TaskChainRewardStep({
3611
4031
  });
3612
4032
  }, [expectedRewards, isSpread, isMobile]);
3613
4033
  return /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-reward-step", ref: containerRef, children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-reward-content", children: [
3614
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-reward-title", children: "Congratulations!" }),
3615
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-reward-subtitle", children: "You have won" }),
4034
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-reward-title", children: t("taskchain_reward_congratulations") }),
4035
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-reward-subtitle", children: t("taskchain_reward_you_won") }),
3616
4036
  showClaimedContent && /* @__PURE__ */ jsxs(
3617
4037
  "div",
3618
4038
  {
@@ -3636,7 +4056,7 @@ function TaskChainRewardStep({
3636
4056
  type: "button",
3637
4057
  className: "taskon-taskchain-btn taskon-taskchain-btn--secondary",
3638
4058
  onClick: onClose,
3639
- children: "Back"
4059
+ children: t("taskchain_back")
3640
4060
  }
3641
4061
  ) })
3642
4062
  ]
@@ -3648,7 +4068,7 @@ function TaskChainRewardStep({
3648
4068
  className: `taskon-taskchain-reward-unclaimed ${isClaimAnimating ? "taskon-taskchain-reward-unclaimed--exit" : ""}`,
3649
4069
  children: [
3650
4070
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-win-rewards", children: expectedRewards.map((reward, index) => {
3651
- const display = getExpectedRewardDisplay(reward);
4071
+ const display = getExpectedRewardDisplay(reward, rewardLabels);
3652
4072
  const style = scatterStyles[index];
3653
4073
  return /* @__PURE__ */ jsxs(
3654
4074
  "div",
@@ -3687,7 +4107,7 @@ function TaskChainRewardStep({
3687
4107
  className: "taskon-taskchain-btn taskon-taskchain-btn--primary",
3688
4108
  onClick: handleClaim,
3689
4109
  disabled: isLoading,
3690
- children: isLoading ? "Claiming..." : "Claim Reward"
4110
+ children: isLoading ? t("taskchain_reward_claiming") : t("taskchain_reward_claim")
3691
4111
  }
3692
4112
  ) })
3693
4113
  }
@@ -3746,6 +4166,7 @@ function TaskChainBlindBoxStep({
3746
4166
  }) {
3747
4167
  const { client } = useTaskOnContext();
3748
4168
  const { toast } = useToast();
4169
+ const { t } = useCommunityTaskLocale();
3749
4170
  const blindBoxDialogRef = useRef(null);
3750
4171
  const [isSubmitting, setIsSubmitting] = useState(false);
3751
4172
  const [isClaiming, setIsClaiming] = useState(false);
@@ -3805,9 +4226,9 @@ function TaskChainBlindBoxStep({
3805
4226
  auto_follow_community: false
3806
4227
  });
3807
4228
  await refetchUserStatus();
3808
- } catch (error) {
3809
- console.error("Failed to submit campaign:", error);
3810
- toast.error("Failed to submit campaign. Please try again.");
4229
+ } catch (error2) {
4230
+ console.error("Failed to submit campaign:", error2);
4231
+ toast.error(t("taskchain_blindbox_submit_failed"));
3811
4232
  setShowManualSubmit(true);
3812
4233
  } finally {
3813
4234
  setIsSubmitting(false);
@@ -3815,7 +4236,7 @@ function TaskChainBlindBoxStep({
3815
4236
  }
3816
4237
  })();
3817
4238
  await submitPromiseRef.current;
3818
- }, [campaign, api, isSubmitting, refetchUserStatus, toast]);
4239
+ }, [campaign, api, isSubmitting, refetchUserStatus, toast, t]);
3819
4240
  const handleBlindBoxOpened = useCallback(async () => {
3820
4241
  var _a;
3821
4242
  if (!campaign || !api || isClaiming) return;
@@ -3826,14 +4247,14 @@ function TaskChainBlindBoxStep({
3826
4247
  }
3827
4248
  await api.claimBlindBoxRewards({ campaign_id: campaign.id });
3828
4249
  await refetchUserStatus();
3829
- } catch (error) {
3830
- console.error("Failed to claim blind box:", error);
3831
- toast.error("Failed to claim reward. Please try again.");
4250
+ } catch (error2) {
4251
+ console.error("Failed to claim blind box:", error2);
4252
+ toast.error(t("taskchain_blindbox_claim_failed"));
3832
4253
  (_a = blindBoxDialogRef.current) == null ? void 0 : _a.resetToUnopened();
3833
4254
  } finally {
3834
4255
  setIsClaiming(false);
3835
4256
  }
3836
- }, [campaign, api, isClaiming, refetchUserStatus, toast]);
4257
+ }, [campaign, api, isClaiming, refetchUserStatus, toast, t]);
3837
4258
  useEffect(() => {
3838
4259
  var _a;
3839
4260
  const isQualifier = ((_a = userStatus == null ? void 0 : userStatus.user_status) == null ? void 0 : _a.is_qualifier) ?? false;
@@ -3842,8 +4263,8 @@ function TaskChainBlindBoxStep({
3842
4263
  }
3843
4264
  }, [campaign, api]);
3844
4265
  if (userBlindBoxStatus === "claimed") {
3845
- const title = isOpenedButNotWon ? "Oops! Better Luck Next Time!" : "Congratulations!";
3846
- const subtitle = isOpenedButNotWon ? "Rewards Missed" : "You Have Won";
4266
+ const title = isOpenedButNotWon ? t("taskchain_blindbox_title_missed") : t("taskchain_blindbox_title_won");
4267
+ const subtitle = isOpenedButNotWon ? t("taskchain_blindbox_subtitle_missed") : t("taskchain_blindbox_subtitle_won");
3847
4268
  const displayRewards = emptyReward ? [emptyReward, ...userRewards] : userRewards;
3848
4269
  return /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-blindbox-step", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-blindbox-result", children: [
3849
4270
  /* @__PURE__ */ jsx("h2", { className: "taskon-taskchain-blindbox-result-title", children: title }),
@@ -3867,7 +4288,7 @@ function TaskChainBlindBoxStep({
3867
4288
  type: "button",
3868
4289
  className: "taskon-taskchain-btn taskon-taskchain-btn--secondary",
3869
4290
  onClick: onClose,
3870
- children: "Back"
4291
+ children: t("taskchain_back")
3871
4292
  }
3872
4293
  ) })
3873
4294
  ] }) });
@@ -3885,7 +4306,7 @@ function TaskChainBlindBoxStep({
3885
4306
  if (isSubmitting && userBlindBoxStatus === "none") {
3886
4307
  return /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-blindbox-step", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-blindbox-loading", children: [
3887
4308
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-spinner" }),
3888
- /* @__PURE__ */ jsx("div", { children: "Preparing your reward..." })
4309
+ /* @__PURE__ */ jsx("div", { children: t("taskchain_blindbox_preparing_reward") })
3889
4310
  ] }) });
3890
4311
  }
3891
4312
  if (showManualSubmit && userBlindBoxStatus === "none") {
@@ -3896,7 +4317,7 @@ function TaskChainBlindBoxStep({
3896
4317
  className: "taskon-taskchain-blindbox-btn",
3897
4318
  onClick: handleSubmitCampaign,
3898
4319
  disabled: isSubmitting,
3899
- children: isSubmitting ? "Submitting..." : "Retry submit"
4320
+ children: isSubmitting ? t("taskchain_blindbox_submitting") : t("taskchain_blindbox_retry_submit")
3900
4321
  }
3901
4322
  ) }) });
3902
4323
  }
@@ -3920,6 +4341,7 @@ function TaskChainMain({
3920
4341
  rewardDisplayMode,
3921
4342
  rewardRedirectUrl
3922
4343
  }) {
4344
+ const { t } = useCommunityTaskLocale();
3923
4345
  const handleVerifyAttempted = useCallback(
3924
4346
  async (_taskId, success) => {
3925
4347
  if (!task) return;
@@ -3958,7 +4380,7 @@ function TaskChainMain({
3958
4380
  );
3959
4381
  }
3960
4382
  if (!task) {
3961
- return /* @__PURE__ */ jsx("div", { children: "No task available" });
4383
+ return /* @__PURE__ */ jsx("div", { children: t("taskchain_no_task_available") });
3962
4384
  }
3963
4385
  return /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-main", children: /* @__PURE__ */ jsx(
3964
4386
  TaskItem,
@@ -3984,6 +4406,7 @@ function NotEligible({
3984
4406
  className = ""
3985
4407
  }) {
3986
4408
  const { client } = useTaskOnContext();
4409
+ const { t } = useCommunityTaskLocale();
3987
4410
  const [isRefreshing, setIsRefreshing] = useState(false);
3988
4411
  const filteredEligs = useMemo(() => {
3989
4412
  if (!(campaign == null ? void 0 : campaign.eligs)) return [];
@@ -4000,8 +4423,8 @@ function NotEligible({
4000
4423
  if (refetchUserStatus) {
4001
4424
  await refetchUserStatus();
4002
4425
  }
4003
- } catch (error) {
4004
- console.error("Failed to check eligibility:", error);
4426
+ } catch (error2) {
4427
+ console.error("Failed to check eligibility:", error2);
4005
4428
  } finally {
4006
4429
  setIsRefreshing(false);
4007
4430
  }
@@ -4009,12 +4432,12 @@ function NotEligible({
4009
4432
  if (!campaign || !userStatus) {
4010
4433
  return /* @__PURE__ */ jsxs("div", { className: `taskon-taskchain-not-eligible ${className}`, children: [
4011
4434
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-emoji", children: "🔒" }),
4012
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-title", children: "Not Eligible" }),
4013
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-desc", children: "You don't meet the requirements to participate in this task chain." })
4435
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-title", children: t("taskchain_not_eligible_title") }),
4436
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-desc", children: t("taskchain_not_eligible_desc") })
4014
4437
  ] });
4015
4438
  }
4016
4439
  return /* @__PURE__ */ jsxs("div", { className: `taskon-taskchain-not-eligible ${className}`, children: [
4017
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-oops", children: "Oops!" }),
4440
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-oops", children: t("taskchain_oops") }),
4018
4441
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-not-eligible-panel", children: /* @__PURE__ */ jsx(
4019
4442
  EligibilityInfo,
4020
4443
  {
@@ -4037,6 +4460,7 @@ const endedImageUrl = new URL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJ0
4037
4460
  function ActionEndedMask({
4038
4461
  className = ""
4039
4462
  }) {
4463
+ const { t } = useCommunityTaskLocale();
4040
4464
  return /* @__PURE__ */ jsxs("div", { className: `taskon-taskchain-ended-mask ${className}`, children: [
4041
4465
  /* @__PURE__ */ jsx(
4042
4466
  "img",
@@ -4046,13 +4470,14 @@ function ActionEndedMask({
4046
4470
  alt: ""
4047
4471
  }
4048
4472
  ),
4049
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-ended-mask-title", children: "Event Ended" })
4473
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-ended-mask-title", children: t("taskchain_event_ended") })
4050
4474
  ] });
4051
4475
  }
4052
4476
  function NeedLoginMask({
4053
4477
  onRequestLogin,
4054
4478
  className = ""
4055
4479
  }) {
4480
+ const { t } = useCommunityTaskLocale();
4056
4481
  return /* @__PURE__ */ jsxs(
4057
4482
  "div",
4058
4483
  {
@@ -4086,7 +4511,7 @@ function NeedLoginMask({
4086
4511
  color: "var(--taskon-color-text)",
4087
4512
  marginBottom: "8px"
4088
4513
  },
4089
- children: "Login Required"
4514
+ children: t("taskchain_login_required")
4090
4515
  }
4091
4516
  ),
4092
4517
  /* @__PURE__ */ jsx(
@@ -4099,7 +4524,7 @@ function NeedLoginMask({
4099
4524
  maxWidth: "300px",
4100
4525
  lineHeight: 1.5
4101
4526
  },
4102
- children: "Please login to participate in this task chain"
4527
+ children: t("taskchain_login_prompt")
4103
4528
  }
4104
4529
  ),
4105
4530
  /* @__PURE__ */ jsx(
@@ -4124,7 +4549,7 @@ function NeedLoginMask({
4124
4549
  onMouseOut: (e) => {
4125
4550
  e.currentTarget.style.opacity = "1";
4126
4551
  },
4127
- children: "Login"
4552
+ children: t("taskchain_login_button")
4128
4553
  }
4129
4554
  )
4130
4555
  ]
@@ -4149,6 +4574,7 @@ function TaskChainDetail({
4149
4574
  }) {
4150
4575
  var _a, _b;
4151
4576
  const { isLoggedIn, requestLogin, client } = useTaskOnContext();
4577
+ const { t } = useCommunityTaskLocale();
4152
4578
  const wasLoggedInRef = useRef(isLoggedIn);
4153
4579
  const totalSteps = useMemo(() => {
4154
4580
  var _a2;
@@ -4185,24 +4611,33 @@ function TaskChainDetail({
4185
4611
  const shouldShowEndedMask = useMemo(() => {
4186
4612
  return isEnded && !isAllTasksCompleted;
4187
4613
  }, [isEnded, isAllTasksCompleted]);
4614
+ const canShowNavigation = useMemo(() => {
4615
+ return isLoggedIn && !shouldShowEndedMask && isEligible;
4616
+ }, [isLoggedIn, shouldShowEndedMask, isEligible]);
4188
4617
  const showBackButton = useMemo(() => {
4189
- return totalSteps > 1 && stepIndex > 0 && !isRewardStep;
4190
- }, [totalSteps, stepIndex, isRewardStep]);
4618
+ return canShowNavigation && totalSteps > 1 && stepIndex > 0 && !isRewardStep;
4619
+ }, [canShowNavigation, totalSteps, stepIndex, isRewardStep]);
4191
4620
  const showNextButton = useMemo(() => {
4192
4621
  var _a2;
4193
4622
  const taskCount = ((_a2 = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _a2.length) || 0;
4194
- return totalSteps > 1 && stepIndex < taskCount - 1;
4195
- }, [totalSteps, stepIndex, (_b = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _b.length]);
4623
+ return canShowNavigation && totalSteps > 1 && stepIndex < taskCount - 1;
4624
+ }, [canShowNavigation, totalSteps, stepIndex, (_b = campaign == null ? void 0 : campaign.tasks) == null ? void 0 : _b.length]);
4196
4625
  const handleBack = useCallback(() => {
4626
+ if (!canShowNavigation) {
4627
+ return;
4628
+ }
4197
4629
  if (stepIndex > 0) {
4198
4630
  onStepChange(stepIndex - 1);
4199
4631
  }
4200
- }, [stepIndex, onStepChange]);
4632
+ }, [canShowNavigation, stepIndex, onStepChange]);
4201
4633
  const handleNext = useCallback(() => {
4634
+ if (!canShowNavigation) {
4635
+ return;
4636
+ }
4202
4637
  if (stepIndex < totalSteps - 1) {
4203
4638
  onStepChange(stepIndex + 1);
4204
4639
  }
4205
- }, [stepIndex, totalSteps, onStepChange]);
4640
+ }, [canShowNavigation, stepIndex, totalSteps, onStepChange]);
4206
4641
  useEffect(() => {
4207
4642
  if (isAllTasksCompleted && !isRewardStep && campaign) {
4208
4643
  onStepChange(campaign.tasks.length);
@@ -4217,8 +4652,8 @@ function TaskChainDetail({
4217
4652
  const api = createQuestApi(client);
4218
4653
  await api.checkUserCampaignEligibility({ campaign_id: campaign.id });
4219
4654
  await refetchUserStatus();
4220
- } catch (error) {
4221
- console.error("Failed to check eligibility after login:", error);
4655
+ } catch (error2) {
4656
+ console.error("Failed to check eligibility after login:", error2);
4222
4657
  }
4223
4658
  };
4224
4659
  checkEligibility();
@@ -4227,7 +4662,7 @@ function TaskChainDetail({
4227
4662
  if (isLoading) {
4228
4663
  return /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-detail", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-detail-loading", children: [
4229
4664
  /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-spinner" }),
4230
- /* @__PURE__ */ jsx("div", { children: "Loading..." })
4665
+ /* @__PURE__ */ jsx("div", { children: t("taskchain_loading") })
4231
4666
  ] }) });
4232
4667
  }
4233
4668
  const renderContent = () => {
@@ -4312,7 +4747,7 @@ function TaskChainDetail({
4312
4747
  type: "button",
4313
4748
  className: "taskon-taskchain-btn taskon-taskchain-btn--secondary",
4314
4749
  onClick: handleBack,
4315
- children: "Back"
4750
+ children: t("taskchain_back")
4316
4751
  }
4317
4752
  ),
4318
4753
  showNextButton && /* @__PURE__ */ jsx(
@@ -4321,7 +4756,7 @@ function TaskChainDetail({
4321
4756
  type: "button",
4322
4757
  className: "taskon-taskchain-btn taskon-taskchain-btn--primary",
4323
4758
  onClick: handleNext,
4324
- children: "Next"
4759
+ children: t("taskchain_next")
4325
4760
  }
4326
4761
  )
4327
4762
  ] })
@@ -4452,12 +4887,13 @@ function TaskChainDialog({
4452
4887
  rewardRedirectUrl
4453
4888
  }) {
4454
4889
  var _a, _b;
4890
+ const { t } = useCommunityTaskLocale();
4455
4891
  const {
4456
4892
  campaign,
4457
4893
  userStatus,
4458
4894
  campaignStatusInfo,
4459
4895
  isLoading,
4460
- error,
4896
+ error: error2,
4461
4897
  refetchUserStatus
4462
4898
  } = useTaskChainDetail({
4463
4899
  campaignId,
@@ -4514,11 +4950,11 @@ function TaskChainDialog({
4514
4950
  }
4515
4951
  }, [(_b = userStatus == null ? void 0 : userStatus.user_status) == null ? void 0 : _b.is_winner, onUpdate]);
4516
4952
  return /* @__PURE__ */ jsx(BottomDialog, { open, onClose, top: "6vh", children: /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-content", children: [
4517
- error && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4518
- /* @__PURE__ */ jsx("div", { children: "Failed to load task chain" }),
4519
- /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error })
4953
+ error2 && /* @__PURE__ */ jsxs("div", { className: "taskon-taskchain-dialog-error", children: [
4954
+ /* @__PURE__ */ jsx("div", { children: t("taskchain_error_load_chain") }),
4955
+ /* @__PURE__ */ jsx("div", { className: "taskon-taskchain-dialog-error-detail", children: error2 })
4520
4956
  ] }),
4521
- !error && /* @__PURE__ */ jsx(
4957
+ !error2 && /* @__PURE__ */ jsx(
4522
4958
  TaskChainDetail,
4523
4959
  {
4524
4960
  campaign,
@@ -4553,6 +4989,7 @@ function SectorItemComponent({
4553
4989
  onCoolDownComplete,
4554
4990
  onDoneCountdownComplete
4555
4991
  }) {
4992
+ const { t } = useCommunityTaskLocale();
4556
4993
  const hasPeriodicTask = useMemo(() => {
4557
4994
  return sector.cards.some((card) => {
4558
4995
  if (card.card_type !== TaskCardType.GTCTask) return false;
@@ -4635,7 +5072,7 @@ function SectorItemComponent({
4635
5072
  return null;
4636
5073
  }) }),
4637
5074
  completedCards.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
4638
- /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: "🎉 You have completed" }),
5075
+ /* @__PURE__ */ jsx("div", { className: "taskon-sector-completed", children: t("you_have_completed") }),
4639
5076
  /* @__PURE__ */ jsx("div", { className: "taskon-sector-tasks taskon-sector-tasks-completed", children: completedCards.map((card) => {
4640
5077
  const key = getCardKey(card);
4641
5078
  if (card.card_type === TaskCardType.TaskChain) {
@@ -4723,16 +5160,6 @@ function CommunityTaskListSkeleton({
4723
5160
  }
4724
5161
  );
4725
5162
  }
4726
- const RECURRENCE_LABEL_MAP = {
4727
- Once: "Once",
4728
- Daily: "Daily",
4729
- Weekly: "Weekly",
4730
- Monthly: "Monthly",
4731
- Unlimited: "Unlimited"
4732
- };
4733
- function getRecurrenceLabel(recurrence) {
4734
- return RECURRENCE_LABEL_MAP[recurrence || "Once"] || "Once";
4735
- }
4736
5163
  function DialogPointReward({
4737
5164
  isPeriodic,
4738
5165
  recurrence,
@@ -4742,6 +5169,7 @@ function DialogPointReward({
4742
5169
  totalEarned = 0,
4743
5170
  communityInfo
4744
5171
  }) {
5172
+ const { t } = useCommunityTaskLocale();
4745
5173
  const displayAmount = useMemo(() => {
4746
5174
  if (recurrence === RecurrenceType.Unlimited) {
4747
5175
  if (totalEarned) {
@@ -4768,13 +5196,15 @@ function DialogPointReward({
4768
5196
  ] }),
4769
5197
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label", children: [
4770
5198
  name,
4771
- " /Time"
5199
+ " ",
5200
+ t("per_time")
4772
5201
  ] })
4773
5202
  ] }),
4774
5203
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount taskon-task-dialog-period-amount--em", children: totalEarned || 0 }),
4775
5204
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period-label taskon-task-dialog-period-label--em", children: [
4776
5205
  name,
4777
- " earned"
5206
+ " ",
5207
+ t("earned")
4778
5208
  ] })
4779
5209
  ] });
4780
5210
  }
@@ -4827,6 +5257,7 @@ function DialogTokenReward({
4827
5257
  chainIcon,
4828
5258
  communityInfo
4829
5259
  }) {
5260
+ const { t } = useCommunityTaskLocale();
4830
5261
  if (isPeriodic) {
4831
5262
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-period", children: [
4832
5263
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-period-amount", children: amount }),
@@ -4842,7 +5273,7 @@ function DialogTokenReward({
4842
5273
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-period-label", children: name }),
4843
5274
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-period-label taskon-task-dialog-token-period-label--em", children: [
4844
5275
  " ",
4845
- "earned"
5276
+ t("earned")
4846
5277
  ] })
4847
5278
  ] })
4848
5279
  ] });
@@ -4913,18 +5344,13 @@ function TokenStatusLeft({
4913
5344
  totalUnit,
4914
5345
  availableUnit
4915
5346
  }) {
5347
+ const { t } = useCommunityTaskLocale();
4916
5348
  const current = useMemo(
4917
5349
  () => calcCurrent(totalUnit, availableUnit),
4918
5350
  [totalUnit, availableUnit]
4919
5351
  );
4920
5352
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress", children: [
4921
- /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-token-progress__content", children: [
4922
- "Hurry up! Only",
4923
- " ",
4924
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-token-progress__text", children: availableUnit ?? 0 }),
4925
- " ",
4926
- "left"
4927
- ] }),
5353
+ /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__content", children: t("only_left", { val: availableUnit ?? 0 }) }),
4928
5354
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-token-progress__bar", children: /* @__PURE__ */ jsx(ColorfulProgress, { current, total: String(totalUnit) }) })
4929
5355
  ] });
4930
5356
  }
@@ -4939,17 +5365,11 @@ function formatDateTime(timestamp) {
4939
5365
  }
4940
5366
  function formatCountdown(diff) {
4941
5367
  if (diff <= 0) return "00:00:00";
4942
- if (diff / (1e3 * 60 * 60) > 24) {
4943
- const day2 = 24 * 60 * 60 * 1e3;
4944
- const days = Math.ceil(diff / day2);
4945
- return `${days} day${days > 1 ? "s" : ""}`;
4946
- }
4947
- const day = 24 * 60 * 60 * 1e3;
4948
5368
  const hour = 60 * 60 * 1e3;
4949
5369
  const minute = 60 * 1e3;
4950
5370
  const second = 1e3;
4951
5371
  const normalizedDiff = Math.abs(diff);
4952
- const hours = Math.floor(normalizedDiff % day / hour);
5372
+ const hours = Math.floor(normalizedDiff / hour);
4953
5373
  const minutes = Math.floor(normalizedDiff % hour / minute);
4954
5374
  const seconds = Math.floor(normalizedDiff % minute / second);
4955
5375
  const prefix2 = (n) => String(n).padStart(2, "0");
@@ -4977,6 +5397,7 @@ function DialogRewardCard({
4977
5397
  communityInfo,
4978
5398
  latestSubmittedTime = 0
4979
5399
  }) {
5400
+ const { t } = useCommunityTaskLocale();
4980
5401
  const { chains } = useTaskOnContext();
4981
5402
  const tokenChainIcon = useMemo(() => {
4982
5403
  var _a;
@@ -5003,21 +5424,18 @@ function DialogRewardCard({
5003
5424
  const renderPeriodicCountdown = useCallback(() => {
5004
5425
  if (!showPeriodicCountdown) return null;
5005
5426
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-periodic-done", children: [
5006
- /* @__PURE__ */ jsx("span", { children: "Done for today" }),
5427
+ /* @__PURE__ */ jsx("span", { children: t("done_today") }),
5007
5428
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__line" }),
5008
- /* @__PURE__ */ jsx("span", { children: "Continue in" }),
5429
+ /* @__PURE__ */ jsx("span", { children: t("continue_in") }),
5009
5430
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-periodic-done__time", children: countdownLabel })
5010
5431
  ] });
5011
- }, [showPeriodicCountdown, countdownLabel]);
5432
+ }, [showPeriodicCountdown, countdownLabel, t]);
5012
5433
  const renderDefaultStatus = () => {
5013
5434
  if (recurrence === RecurrenceType.Unlimited && latestSubmittedTime && latestSubmittedTime > 0) {
5014
- return /* @__PURE__ */ jsxs("span", { className: "taskon-task-dialog-updated", children: [
5015
- "Updated at ",
5016
- formatDateTime(latestSubmittedTime)
5017
- ] });
5435
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-updated", children: t("updated_at", { val: formatDateTime(latestSubmittedTime) }) });
5018
5436
  }
5019
5437
  if (isWon) {
5020
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
5438
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
5021
5439
  }
5022
5440
  return null;
5023
5441
  };
@@ -5030,7 +5448,7 @@ function DialogRewardCard({
5030
5448
  isPeriodic,
5031
5449
  recurrence,
5032
5450
  amount: reward.amount ?? 0,
5033
- name: reward.name ?? "Points",
5451
+ name: reward.name ?? t("community_points"),
5034
5452
  icon: reward.icon,
5035
5453
  totalEarned,
5036
5454
  communityInfo
@@ -5088,12 +5506,12 @@ function DialogRewardCard({
5088
5506
  const statusNode = showPeriodicCountdown ? renderPeriodicCountdown() : renderStatus ? renderStatus() : renderDefaultStatus();
5089
5507
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-reward-card", children: [
5090
5508
  claimLimit > 0 && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-max-claim", children: [
5091
- "Max. Claims",
5509
+ t("max_claim_num"),
5092
5510
  " ",
5093
5511
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-max-claim--highlight", children: claimLimit })
5094
5512
  ] }),
5095
5513
  /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-row", children: [
5096
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-rewards-label", children: "🎁 Rewards" }),
5514
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-rewards-label", children: t("gift_rewards") }),
5097
5515
  (statusPrefixNode || statusNode) && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-label-right", children: [
5098
5516
  statusPrefixNode,
5099
5517
  statusNode
@@ -5109,6 +5527,7 @@ function CloseIn({
5109
5527
  onClose
5110
5528
  }) {
5111
5529
  const [countdown, setCountdown] = useState(seconds);
5530
+ const { t } = useCommunityTaskLocale();
5112
5531
  const timerRef = useRef(null);
5113
5532
  const handleClose = useCallback(() => {
5114
5533
  onClose();
@@ -5134,11 +5553,7 @@ function CloseIn({
5134
5553
  }
5135
5554
  };
5136
5555
  }, [handleClose]);
5137
- return /* @__PURE__ */ jsxs("div", { className: "taskon-close-in", children: [
5138
- "Closing in ",
5139
- countdown,
5140
- "s"
5141
- ] });
5556
+ return /* @__PURE__ */ jsx("div", { className: "taskon-close-in", children: t("close_in", { val: countdown }) });
5142
5557
  }
5143
5558
  function BaseDialogLayout({
5144
5559
  recurrence,
@@ -5175,7 +5590,8 @@ function BaseDialogLayout({
5175
5590
  onCloseInClose
5176
5591
  }) {
5177
5592
  var _a;
5178
- const recurrenceLabel = getRecurrenceLabel(recurrence);
5593
+ const { t } = useCommunityTaskLocale();
5594
+ const recurrenceLabel = getRecurrenceLabel(t, recurrence);
5179
5595
  const shouldShowEligibilityMask = Boolean(
5180
5596
  ((_a = eligibilityTask == null ? void 0 : eligibilityTask.eligiblity) == null ? void 0 : _a.length) && (eligibilityConditions == null ? void 0 : eligibilityConditions.length)
5181
5597
  );
@@ -5189,7 +5605,7 @@ function BaseDialogLayout({
5189
5605
  ] }) });
5190
5606
  }
5191
5607
  return /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-valid-time", children: [
5192
- /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-label", children: "Valid Until:" }),
5608
+ /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-label", children: t("valid_util_is") }),
5193
5609
  /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-valid-time-value", children: validTime.endTime })
5194
5610
  ] });
5195
5611
  };
@@ -5268,6 +5684,7 @@ function TemplateDialogContent({
5268
5684
  }) {
5269
5685
  var _a, _b, _c, _d;
5270
5686
  const userStatus = task.user_status;
5687
+ const { t } = useCommunityTaskLocale();
5271
5688
  const { showToast } = useToast();
5272
5689
  const { getChainType } = useChainMap();
5273
5690
  const { communityInfo } = useTaskOnContext();
@@ -5291,7 +5708,7 @@ function TemplateDialogContent({
5291
5708
  );
5292
5709
  const coolDown = sharedCoolDown ?? localCoolDown;
5293
5710
  const taskTitle = useMemo(() => {
5294
- if (!info) return "Task";
5711
+ if (!info) return t("task_up");
5295
5712
  const { template, name } = info;
5296
5713
  if (name !== template.template_name) {
5297
5714
  return name;
@@ -5303,7 +5720,7 @@ function TemplateDialogContent({
5303
5720
  return null;
5304
5721
  }
5305
5722
  return name;
5306
- }, [info, params.custom_title, params.title_express]);
5723
+ }, [info, params.custom_title, params.title_express, t]);
5307
5724
  const titleContent = useMemo(() => {
5308
5725
  if (taskTitle) return taskTitle;
5309
5726
  if (params.title_express) {
@@ -5314,8 +5731,8 @@ function TemplateDialogContent({
5314
5731
  }
5315
5732
  );
5316
5733
  }
5317
- return (info == null ? void 0 : info.name) || "Task";
5318
- }, [taskTitle, params.title_express, info == null ? void 0 : info.name]);
5734
+ return (info == null ? void 0 : info.name) || t("task_up");
5735
+ }, [taskTitle, params.title_express, info == null ? void 0 : info.name, t]);
5319
5736
  const validationTimeFrame = useMemo(() => {
5320
5737
  if (!(info == null ? void 0 : info.template)) return void 0;
5321
5738
  const { class_type, is_hold } = info.template;
@@ -5351,8 +5768,8 @@ function TemplateDialogContent({
5351
5768
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5352
5769
  }, [sharedOnCoolDownComplete]);
5353
5770
  const handleBindFailed = useCallback(
5354
- (error) => {
5355
- showToast(error, "error");
5771
+ (error2) => {
5772
+ showToast(error2, "error");
5356
5773
  },
5357
5774
  [showToast]
5358
5775
  );
@@ -5379,7 +5796,7 @@ function TemplateDialogContent({
5379
5796
  }
5380
5797
  }, [params.action_link, params.action_auto_verify, params.is_link_task, handleClaim]);
5381
5798
  if (!info) {
5382
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
5799
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5383
5800
  }
5384
5801
  return /* @__PURE__ */ jsxs(
5385
5802
  BaseDialogLayout,
@@ -5453,6 +5870,7 @@ function PowImageUploader({
5453
5870
  onConfirmed,
5454
5871
  onError
5455
5872
  }) {
5873
+ const { t } = useCommunityTaskLocale();
5456
5874
  const [previewUrl, setPreviewUrl] = useState(defaultUrl);
5457
5875
  const [file, setFile] = useState(null);
5458
5876
  const [progress, setProgress] = useState(0);
@@ -5473,7 +5891,7 @@ function PowImageUploader({
5473
5891
  const selectedFile = (_a = event.target.files) == null ? void 0 : _a[0];
5474
5892
  if (!selectedFile) return;
5475
5893
  if (selectedFile.size > MAX_FILE_SIZE) {
5476
- onError == null ? void 0 : onError("Image size exceeds 10MB limit");
5894
+ onError == null ? void 0 : onError(t("invalid_image_size_10m"));
5477
5895
  return;
5478
5896
  }
5479
5897
  setFile(selectedFile);
@@ -5486,12 +5904,12 @@ function PowImageUploader({
5486
5904
  reader.readAsDataURL(selectedFile);
5487
5905
  await uploadFile(selectedFile);
5488
5906
  },
5489
- [onError]
5907
+ [onError, t]
5490
5908
  );
5491
5909
  const uploadFile = useCallback(
5492
5910
  async (fileToUpload) => {
5493
5911
  if (!client) {
5494
- onError == null ? void 0 : onError("Client not initialized");
5912
+ onError == null ? void 0 : onError(t("client_not_initialized"));
5495
5913
  return;
5496
5914
  }
5497
5915
  try {
@@ -5514,17 +5932,17 @@ function PowImageUploader({
5514
5932
  );
5515
5933
  abortControllerRef.current = null;
5516
5934
  onConfirmed(result.cdn_url);
5517
- } catch (error) {
5518
- if (error instanceof DOMException && error.name === "AbortError") {
5935
+ } catch (error2) {
5936
+ if (error2 instanceof DOMException && error2.name === "AbortError") {
5519
5937
  return;
5520
5938
  }
5521
- const message = error instanceof Error ? error.message : "Upload failed";
5939
+ const message = error2 instanceof Error ? error2.message : t("upload_failed");
5522
5940
  onError == null ? void 0 : onError(message);
5523
5941
  } finally {
5524
5942
  setIsUploading(false);
5525
5943
  }
5526
5944
  },
5527
- [client, onConfirmed, onError]
5945
+ [client, onConfirmed, onError, t]
5528
5946
  );
5529
5947
  const handleClick = useCallback(() => {
5530
5948
  var _a;
@@ -5548,7 +5966,7 @@ function PowImageUploader({
5548
5966
  onKeyDown: handleKeyDown,
5549
5967
  role: "button",
5550
5968
  tabIndex: disabled ? -1 : 0,
5551
- "aria-label": "Upload image",
5969
+ "aria-label": t("upload_image"),
5552
5970
  "aria-disabled": disabled,
5553
5971
  children: [
5554
5972
  /* @__PURE__ */ jsx(
@@ -5567,7 +5985,7 @@ function PowImageUploader({
5567
5985
  "img",
5568
5986
  {
5569
5987
  src: previewUrl,
5570
- alt: "Preview",
5988
+ alt: t("upload_image"),
5571
5989
  className: "taskon-pow-uploader-preview"
5572
5990
  }
5573
5991
  ),
@@ -5601,7 +6019,7 @@ function PowImageUploader({
5601
6019
  ]
5602
6020
  }
5603
6021
  ),
5604
- /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip", children: "Click to upload image" })
6022
+ /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip", children: t("click_to_upload_image") })
5605
6023
  ] })
5606
6024
  ] }) : (
5607
6025
  /* 无预览时显示上传提示 */
@@ -5635,7 +6053,7 @@ function PowImageUploader({
5635
6053
  ]
5636
6054
  }
5637
6055
  ),
5638
- /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip taskon-pow-uploader-tip--empty", children: "Click to upload image" })
6056
+ /* @__PURE__ */ jsx("span", { className: "taskon-pow-uploader-tip taskon-pow-uploader-tip--empty", children: t("click_to_upload_image") })
5639
6057
  ] })
5640
6058
  ),
5641
6059
  isUploading && /* @__PURE__ */ jsx("div", { className: "taskon-pow-uploader-progress", children: /* @__PURE__ */ jsx(
@@ -5668,6 +6086,7 @@ function PowTaskDialogContent({
5668
6086
  }) {
5669
6087
  var _a, _b, _c;
5670
6088
  const userStatus = task.user_status;
6089
+ const { t } = useCommunityTaskLocale();
5671
6090
  const { toast } = useToast();
5672
6091
  const { communityInfo } = useTaskOnContext();
5673
6092
  const totalEarned = ((_a = userStatus == null ? void 0 : userStatus.total_point) == null ? void 0 : _a.amount) ?? 0;
@@ -5697,7 +6116,7 @@ function PowTaskDialogContent({
5697
6116
  const validateInput = useCallback(() => {
5698
6117
  if (params.type === "Image") {
5699
6118
  if (!answer.trim()) {
5700
- setInputError("Please upload an image");
6119
+ setInputError(t("please_upload_image"));
5701
6120
  return false;
5702
6121
  }
5703
6122
  setInputError(null);
@@ -5705,7 +6124,7 @@ function PowTaskDialogContent({
5705
6124
  }
5706
6125
  if (!answer.trim()) {
5707
6126
  setInputError(
5708
- params.type === "URL" ? "Please enter URL" : "Please enter text"
6127
+ params.type === "URL" ? t("please_enter_url") : t("please_enter_text")
5709
6128
  );
5710
6129
  return false;
5711
6130
  }
@@ -5713,24 +6132,24 @@ function PowTaskDialogContent({
5713
6132
  try {
5714
6133
  new URL(answer);
5715
6134
  } catch {
5716
- setInputError("Please enter a valid url address");
6135
+ setInputError(t("invalid_url"));
5717
6136
  return false;
5718
6137
  }
5719
6138
  }
5720
6139
  setInputError(null);
5721
6140
  return true;
5722
- }, [answer, params.type]);
6141
+ }, [answer, params.type, t]);
5723
6142
  const handleSubmit = useCallback(async () => {
5724
6143
  if (!validateInput()) return;
5725
6144
  await submitTask(answer);
5726
6145
  }, [validateInput, submitTask, answer]);
5727
6146
  const handleResubmit = useCallback(async () => {
5728
6147
  if (!validateInput()) return;
5729
- const success = await submitTask(answer);
5730
- if (success) {
5731
- toast.success("Re-submitted successfully");
6148
+ const result = await submitTask(answer);
6149
+ if (result.successful) {
6150
+ toast.success(t("re_submitted_success"));
5732
6151
  }
5733
- }, [validateInput, submitTask, answer, toast]);
6152
+ }, [validateInput, submitTask, answer, toast, t]);
5734
6153
  const renderInputArea = () => {
5735
6154
  const powType = params.type || "Text";
5736
6155
  if (powType === "URL") {
@@ -5741,7 +6160,7 @@ function PowTaskDialogContent({
5741
6160
  type: "url",
5742
6161
  value: answer,
5743
6162
  onChange: setAnswer,
5744
- placeholder: "Please enter URL",
6163
+ placeholder: t("please_enter_url"),
5745
6164
  maxLength: 2e3,
5746
6165
  disabled: isInputDisabled,
5747
6166
  hasError: !!inputError,
@@ -5758,7 +6177,7 @@ function PowTaskDialogContent({
5758
6177
  {
5759
6178
  value: answer,
5760
6179
  onChange: setAnswer,
5761
- placeholder: "Enter here",
6180
+ placeholder: t("enter_here"),
5762
6181
  maxLength: 500,
5763
6182
  showCount: true,
5764
6183
  disabled: isInputDisabled,
@@ -5780,8 +6199,8 @@ function PowTaskDialogContent({
5780
6199
  setAnswer(url);
5781
6200
  setInputError(null);
5782
6201
  },
5783
- onError: (error) => {
5784
- setInputError(error);
6202
+ onError: (error2) => {
6203
+ setInputError(error2);
5785
6204
  }
5786
6205
  }
5787
6206
  ),
@@ -5790,7 +6209,10 @@ function PowTaskDialogContent({
5790
6209
  };
5791
6210
  const renderActionButton = () => {
5792
6211
  if (state.isWon) {
5793
- return /* @__PURE__ */ jsx("div", { className: "taskon-pow-dialog-done", children: "✅ Task completed" });
6212
+ return /* @__PURE__ */ jsxs("div", { className: "taskon-pow-dialog-done", children: [
6213
+ "✅ ",
6214
+ t("task_completed")
6215
+ ] });
5794
6216
  }
5795
6217
  if (isUnderReview || isFailedButCanRetry) {
5796
6218
  return /* @__PURE__ */ jsx(
@@ -5800,7 +6222,7 @@ function PowTaskDialogContent({
5800
6222
  className: "taskon-pow-dialog-submit",
5801
6223
  onClick: handleResubmit,
5802
6224
  disabled: isSubmitting,
5803
- children: isSubmitting ? "Submitting..." : "Re-submit"
6225
+ children: isSubmitting ? t("submitting") : t("resubmit")
5804
6226
  }
5805
6227
  );
5806
6228
  }
@@ -5812,7 +6234,7 @@ function PowTaskDialogContent({
5812
6234
  className: "taskon-pow-dialog-submit",
5813
6235
  onClick: handleSubmit,
5814
6236
  disabled: isSubmitting,
5815
- children: isSubmitting ? "Submitting..." : "Submit"
6237
+ children: isSubmitting ? t("submitting") : t("submit")
5816
6238
  }
5817
6239
  );
5818
6240
  }
@@ -5820,18 +6242,18 @@ function PowTaskDialogContent({
5820
6242
  };
5821
6243
  const renderReviewStatus = useCallback(() => {
5822
6244
  if (state.isWon) {
5823
- return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: "Won" });
6245
+ return /* @__PURE__ */ jsx("span", { className: "taskon-task-dialog-won", children: t("won") });
5824
6246
  }
5825
6247
  if (isUnderReview) {
5826
- return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--review", children: "Under Review" });
6248
+ return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--review", children: t("under_review") });
5827
6249
  }
5828
6250
  if ((userStatus == null ? void 0 : userStatus.review_result) === TaskReviewResult.Failed) {
5829
- return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--failed", children: "Failed" });
6251
+ return /* @__PURE__ */ jsx("span", { className: "taskon-pow-dialog-status--failed", children: t("failed") });
5830
6252
  }
5831
6253
  return null;
5832
- }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result]);
6254
+ }, [state.isWon, isUnderReview, userStatus == null ? void 0 : userStatus.review_result, t]);
5833
6255
  if (!info) {
5834
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6256
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5835
6257
  }
5836
6258
  return /* @__PURE__ */ jsxs(
5837
6259
  BaseDialogLayout,
@@ -5887,6 +6309,7 @@ function ContractInteractiveDialogContent({
5887
6309
  }) {
5888
6310
  var _a, _b, _c;
5889
6311
  const userStatus = task.user_status;
6312
+ const { t } = useCommunityTaskLocale();
5890
6313
  const { showToast } = useToast();
5891
6314
  const { getChainType } = useChainMap();
5892
6315
  const { communityInfo } = useTaskOnContext();
@@ -5947,8 +6370,8 @@ function ContractInteractiveDialogContent({
5947
6370
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
5948
6371
  }, [sharedOnCoolDownComplete]);
5949
6372
  const handleBindFailed = useCallback(
5950
- (error) => {
5951
- showToast(error, "error");
6373
+ (error2) => {
6374
+ showToast(error2, "error");
5952
6375
  },
5953
6376
  [showToast]
5954
6377
  );
@@ -5962,7 +6385,7 @@ function ContractInteractiveDialogContent({
5962
6385
  }
5963
6386
  }, [params.task_url]);
5964
6387
  if (!info) {
5965
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6388
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
5966
6389
  }
5967
6390
  return /* @__PURE__ */ jsxs(
5968
6391
  BaseDialogLayout,
@@ -5994,13 +6417,16 @@ function ContractInteractiveDialogContent({
5994
6417
  children: [
5995
6418
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
5996
6419
  params.desc && /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) }),
5997
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6420
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
5998
6421
  "button",
5999
6422
  {
6000
6423
  type: "button",
6001
6424
  className: "taskon-task-dialog-action",
6002
6425
  onClick: handleAction,
6003
- children: "👉 Proceed to complete the task"
6426
+ children: [
6427
+ "👉 ",
6428
+ t("proceed_2_complete_the_task")
6429
+ ]
6004
6430
  }
6005
6431
  )
6006
6432
  ]
@@ -6030,6 +6456,7 @@ function SwapDexDialogContent({
6030
6456
  }) {
6031
6457
  var _a, _b, _c;
6032
6458
  const userStatus = task.user_status;
6459
+ const { t } = useCommunityTaskLocale();
6033
6460
  const { showToast } = useToast();
6034
6461
  const { getChainType, chainMap } = useChainMap();
6035
6462
  const { communityInfo } = useTaskOnContext();
@@ -6058,13 +6485,16 @@ function SwapDexDialogContent({
6058
6485
  );
6059
6486
  const coolDown = sharedCoolDown ?? localCoolDown;
6060
6487
  const isFixedRule = params.is_fixed_reward_type;
6061
- const rulePointName = reward.name || "Points";
6488
+ const rulePointName = reward.name || t("community_points");
6062
6489
  const ruleMaxText = useMemo(() => {
6063
6490
  if (typeof params.swap_receive_max_points === "number" && params.swap_receive_max_points >= 0) {
6064
- return `(Max ${params.swap_receive_max_points} ${rulePointName})`;
6491
+ return t("community_rule_max", {
6492
+ val: params.swap_receive_max_points,
6493
+ name: rulePointName
6494
+ });
6065
6495
  }
6066
6496
  return "";
6067
- }, [params.swap_receive_max_points, rulePointName]);
6497
+ }, [params.swap_receive_max_points, rulePointName, t]);
6068
6498
  const hasRulesText = useMemo(() => {
6069
6499
  return Boolean(params.each_trading_volume && params.each_receive_points);
6070
6500
  }, [params.each_trading_volume, params.each_receive_points]);
@@ -6078,13 +6508,13 @@ function SwapDexDialogContent({
6078
6508
  tokenOutList: params.token_out_list,
6079
6509
  tokenInList: params.token_in_list,
6080
6510
  chainLabel,
6081
- dexName: (info == null ? void 0 : info.project_name) || (communityInfo == null ? void 0 : communityInfo.name) || "DEX",
6511
+ dexName: (info == null ? void 0 : info.project_name) || (communityInfo == null ? void 0 : communityInfo.name) || t("community_dex"),
6082
6512
  dexLink: params.task_url,
6083
6513
  isFixedReward: params.is_fixed_reward_type || false,
6084
6514
  minTradingVolume: params.min_trading_volume,
6085
6515
  minTradesTimes: params.min_trades_times
6086
6516
  });
6087
- }, [params, chainLabel, info == null ? void 0 : info.project_name, communityInfo == null ? void 0 : communityInfo.name]);
6517
+ }, [params, chainLabel, info == null ? void 0 : info.project_name, communityInfo == null ? void 0 : communityInfo.name, t]);
6088
6518
  const fromTokenDisplay = useMemo(
6089
6519
  () => formatSwapTokensForDisplay(params.token_out_list),
6090
6520
  [params.token_out_list]
@@ -6133,8 +6563,8 @@ function SwapDexDialogContent({
6133
6563
  sharedOnCoolDownComplete == null ? void 0 : sharedOnCoolDownComplete();
6134
6564
  }, [sharedOnCoolDownComplete]);
6135
6565
  const handleBindFailed = useCallback(
6136
- (error) => {
6137
- showToast(error, "error");
6566
+ (error2) => {
6567
+ showToast(error2, "error");
6138
6568
  },
6139
6569
  [showToast]
6140
6570
  );
@@ -6155,22 +6585,23 @@ function SwapDexDialogContent({
6155
6585
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-progress-separator", children: "/" }),
6156
6586
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-progress-total", children: [
6157
6587
  minTimes,
6158
- " Times"
6588
+ " ",
6589
+ t("times")
6159
6590
  ] })
6160
6591
  ] });
6161
6592
  }
6162
6593
  return null;
6163
- }, [isDynamicTimes, userStatus == null ? void 0 : userStatus.current_trades_times, params.min_trades_times]);
6594
+ }, [isDynamicTimes, userStatus == null ? void 0 : userStatus.current_trades_times, params.min_trades_times, t]);
6164
6595
  const renderFixedModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6165
- params.chain && /* @__PURE__ */ jsx(CardField, { label: "Chain: ", value: chainLabel }),
6596
+ params.chain && /* @__PURE__ */ jsx(CardField, { label: t("chain_is"), value: chainLabel }),
6166
6597
  params.token_out_list && params.token_out_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6167
- /* @__PURE__ */ jsx(CardField, { label: "Swap From: ", value: fromTokenDisplay }),
6598
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_from_is"), value: fromTokenDisplay }),
6168
6599
  params.token_out_list.filter(
6169
6600
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6170
6601
  ).map((token) => /* @__PURE__ */ jsx(
6171
6602
  CardField,
6172
6603
  {
6173
- label: `${token.symbol || "Token"} Address: `,
6604
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6174
6605
  value: formatAddress(token.address || ""),
6175
6606
  copy_text: token.address
6176
6607
  },
@@ -6178,13 +6609,13 @@ function SwapDexDialogContent({
6178
6609
  ))
6179
6610
  ] }),
6180
6611
  params.token_in_list && params.token_in_list.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
6181
- /* @__PURE__ */ jsx(CardField, { label: "Swap To: ", value: toTokenDisplay }),
6612
+ /* @__PURE__ */ jsx(CardField, { label: t("swap_to_is"), value: toTokenDisplay }),
6182
6613
  params.token_in_list.filter(
6183
6614
  (token) => token.address && token.address !== SWAP_ANY_TOKEN_KEY
6184
6615
  ).map((token) => /* @__PURE__ */ jsx(
6185
6616
  CardField,
6186
6617
  {
6187
- label: `${token.symbol || "Token"} Address: `,
6618
+ label: `${token.symbol || t("community_token")} ${t("address_is")}`,
6188
6619
  value: formatAddress(token.address || ""),
6189
6620
  copy_text: token.address
6190
6621
  },
@@ -6192,21 +6623,21 @@ function SwapDexDialogContent({
6192
6623
  ))
6193
6624
  ] }),
6194
6625
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6195
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6626
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6196
6627
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6197
6628
  ] })
6198
6629
  ] });
6199
6630
  const renderDynamicModeContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
6200
6631
  hasRulesText && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6201
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Rules" }),
6632
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("rules") }),
6202
6633
  /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section-content taskon-swap-dialog-section-content--rules", children: [
6203
- /* @__PURE__ */ jsx("span", { children: "Every" }),
6634
+ /* @__PURE__ */ jsx("span", { children: t("every") }),
6204
6635
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-highlight", children: [
6205
6636
  "$",
6206
6637
  params.each_trading_volume || "0",
6207
6638
  " USD"
6208
6639
  ] }),
6209
- /* @__PURE__ */ jsx("span", { children: "will give you" }),
6640
+ /* @__PURE__ */ jsx("span", { children: t("will_give_you") }),
6210
6641
  /* @__PURE__ */ jsx("span", { className: "taskon-swap-dialog-rules-highlight", children: params.each_receive_points }),
6211
6642
  /* @__PURE__ */ jsxs("span", { className: "taskon-swap-dialog-rules-point-name", children: [
6212
6643
  rulePointName,
@@ -6215,12 +6646,12 @@ function SwapDexDialogContent({
6215
6646
  ] })
6216
6647
  ] }),
6217
6648
  params.desc && /* @__PURE__ */ jsxs("div", { className: "taskon-swap-dialog-section", children: [
6218
- /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: "Instructions" }),
6649
+ /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-title", children: t("instructions") }),
6219
6650
  /* @__PURE__ */ jsx("div", { className: "taskon-swap-dialog-section-content", children: /* @__PURE__ */ jsx(CardDescExpress, { label: params.desc, noMaxHeight: true }) })
6220
6651
  ] })
6221
6652
  ] });
6222
6653
  if (!info) {
6223
- return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: "No task data" });
6654
+ return /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-left", children: t("no_task_data") });
6224
6655
  }
6225
6656
  return /* @__PURE__ */ jsxs(
6226
6657
  BaseDialogLayout,
@@ -6253,13 +6684,16 @@ function SwapDexDialogContent({
6253
6684
  children: [
6254
6685
  validationTimeFrame && /* @__PURE__ */ jsx(ValidationTimeTip, { timeFrame: validationTimeFrame }),
6255
6686
  /* @__PURE__ */ jsx("div", { className: "taskon-task-dialog-desc", children: isFixedRule ? renderFixedModeContent() : renderDynamicModeContent() }),
6256
- params.task_url && !state.isWon && /* @__PURE__ */ jsx(
6687
+ params.task_url && !state.isWon && /* @__PURE__ */ jsxs(
6257
6688
  "button",
6258
6689
  {
6259
6690
  type: "button",
6260
6691
  className: "taskon-task-dialog-action",
6261
6692
  onClick: handleAction,
6262
- children: "👉 Swap"
6693
+ children: [
6694
+ "👉 ",
6695
+ t("swap")
6696
+ ]
6263
6697
  }
6264
6698
  )
6265
6699
  ]
@@ -6342,15 +6776,17 @@ function getDialogContentComponent(templateId) {
6342
6776
  return TaskDialogContent;
6343
6777
  }
6344
6778
  function DialogLoading() {
6779
+ const { t } = useCommunityTaskLocale();
6345
6780
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-loading", children: [
6346
6781
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-loading-spinner" }),
6347
- /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: "Loading task..." })
6782
+ /* @__PURE__ */ jsx("span", { className: "taskon-dialog-loading-text", children: t("loading_task") })
6348
6783
  ] });
6349
6784
  }
6350
6785
  function DialogError({
6351
6786
  message,
6352
6787
  onRetry
6353
6788
  }) {
6789
+ const { t } = useCommunityTaskLocale();
6354
6790
  return /* @__PURE__ */ jsxs("div", { className: "taskon-dialog-error", children: [
6355
6791
  /* @__PURE__ */ jsx("div", { className: "taskon-dialog-error-icon", children: ":(" }),
6356
6792
  /* @__PURE__ */ jsx("p", { className: "taskon-dialog-error-message", children: message }),
@@ -6360,7 +6796,7 @@ function DialogError({
6360
6796
  type: "button",
6361
6797
  className: "taskon-dialog-error-retry",
6362
6798
  onClick: onRetry,
6363
- children: "Retry"
6799
+ children: t("retry")
6364
6800
  }
6365
6801
  )
6366
6802
  ] });
@@ -6380,11 +6816,12 @@ function TaskDialogComponent(props) {
6380
6816
  onCoolDownUpdate,
6381
6817
  onCoolDownComplete
6382
6818
  } = props;
6819
+ const { t } = useCommunityTaskLocale();
6383
6820
  const [justVerified, setJustVerified] = useState(false);
6384
6821
  const {
6385
6822
  data: fetchedTask,
6386
6823
  isLoading,
6387
- error,
6824
+ error: error2,
6388
6825
  refetch
6389
6826
  } = useTaskDetail({
6390
6827
  taskId: task ? null : taskId ?? null
@@ -6435,7 +6872,7 @@ function TaskDialogComponent(props) {
6435
6872
  const templateId = (_a2 = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a2.template_id;
6436
6873
  return getDialogContentComponent(templateId);
6437
6874
  }, [(_a = taskInfo == null ? void 0 : taskInfo.template) == null ? void 0 : _a.template_id]);
6438
- const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? "任务详情";
6875
+ const dialogTitle = (taskInfo == null ? void 0 : taskInfo.name) ?? t("task_details");
6439
6876
  const isOpen = task !== null || taskId !== null;
6440
6877
  if (typeof document === "undefined") {
6441
6878
  return null;
@@ -6446,14 +6883,14 @@ function TaskDialogComponent(props) {
6446
6883
  open: isOpen,
6447
6884
  onOpenChange: handleOpenChange,
6448
6885
  title: dialogTitle,
6449
- description: "查看任务详情和奖励信息",
6886
+ description: t("task_details_desc"),
6450
6887
  showCloseButton: true,
6451
6888
  bodyPadding: false,
6452
6889
  contentClassName: "taskon-task-dialog",
6453
6890
  maxWidth: rightSlot ? 800 : 480,
6454
6891
  children: [
6455
6892
  !task && isLoading && /* @__PURE__ */ jsx(DialogLoading, {}),
6456
- !task && error && /* @__PURE__ */ jsx(DialogError, { message: error, onRetry: refetch }),
6893
+ !task && error2 && /* @__PURE__ */ jsx(DialogError, { message: error2, onRetry: refetch }),
6457
6894
  taskData && /* @__PURE__ */ jsxs("div", { className: "taskon-task-dialog-wrapper", children: [
6458
6895
  renderContent ? renderContent(taskData) : /* @__PURE__ */ jsx(
6459
6896
  DialogContentComponent,
@@ -6491,6 +6928,12 @@ function mergeCommunityTaskConfig(props, cloud) {
6491
6928
  rewardRedirectUrl: props.rewardRedirectUrl ?? (cloud == null ? void 0 : cloud.rewardRedirectUrl) ?? ""
6492
6929
  };
6493
6930
  }
6931
+ function toSectorIdsKey(sectorIds) {
6932
+ if (!sectorIds || sectorIds.length === 0) {
6933
+ return "all";
6934
+ }
6935
+ return sectorIds.join(",");
6936
+ }
6494
6937
  function findTaskByIdFromCards(data, taskId) {
6495
6938
  for (const sectorItem of data) {
6496
6939
  const found = sectorItem.cards.find((card) => card.card_info.id === taskId);
@@ -6572,13 +7015,16 @@ function CommunityTaskListInner(props) {
6572
7015
  rewardDisplayMode = "popup",
6573
7016
  rewardRedirectUrl = ""
6574
7017
  } = props;
6575
- const { client, userToken } = useTaskOnContext();
7018
+ const { client, userToken, isSessionReady } = useTaskOnContext();
7019
+ const { t } = useCommunityTaskLocale();
7020
+ const inFlightLoadKeyRef = useRef(null);
7021
+ const lastSuccessfulLoadKeyRef = useRef(null);
6576
7022
  const [taskCards, setTaskCards] = useState(
6577
7023
  []
6578
7024
  );
6579
7025
  const [selectedSectorId, setSelectedSectorId] = useState(null);
6580
7026
  const [isLoading, setIsLoading] = useState(true);
6581
- const [error, setError] = useState(null);
7027
+ const [error2, setError] = useState(null);
6582
7028
  const [openTask, setOpenTask] = useState(null);
6583
7029
  const [openTaskId, setOpenTaskId] = useState(
6584
7030
  initialTaskId ?? null
@@ -6597,10 +7043,13 @@ function CommunityTaskListInner(props) {
6597
7043
  return next;
6598
7044
  });
6599
7045
  }, []);
6600
- const handleTaskChainOpen = useCallback((taskChainId) => {
6601
- setOpenTaskChainId(taskChainId);
6602
- onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
6603
- }, [onTaskChainOpen]);
7046
+ const handleTaskChainOpen = useCallback(
7047
+ (taskChainId) => {
7048
+ setOpenTaskChainId(taskChainId);
7049
+ onTaskChainOpen == null ? void 0 : onTaskChainOpen(taskChainId);
7050
+ },
7051
+ [onTaskChainOpen]
7052
+ );
6604
7053
  const handleTaskChainClose = useCallback(() => {
6605
7054
  setOpenTaskChainId(null);
6606
7055
  onTaskChainClose == null ? void 0 : onTaskChainClose();
@@ -6617,11 +7066,25 @@ function CommunityTaskListInner(props) {
6617
7066
  }, [initialTaskChainId]);
6618
7067
  useEffect(() => {
6619
7068
  const loadTasks = async () => {
7069
+ if (!isSessionReady) {
7070
+ setError(null);
7071
+ setIsLoading(true);
7072
+ return;
7073
+ }
6620
7074
  if (!client) {
6621
- setError("Client not initialized");
7075
+ setError({ type: "localized", key: "client_not_initialized" });
6622
7076
  setIsLoading(false);
6623
7077
  return;
6624
7078
  }
7079
+ const clientToken = client.getUserToken();
7080
+ const loadKey = [
7081
+ isPreview ? "preview" : "normal",
7082
+ toSectorIdsKey(sectorIds),
7083
+ clientToken ?? "anonymous"
7084
+ ].join("|");
7085
+ if (inFlightLoadKeyRef.current === loadKey) return;
7086
+ if (lastSuccessfulLoadKeyRef.current === loadKey) return;
7087
+ inFlightLoadKeyRef.current = loadKey;
6625
7088
  try {
6626
7089
  setIsLoading(true);
6627
7090
  setError(null);
@@ -6631,61 +7094,61 @@ function CommunityTaskListInner(props) {
6631
7094
  ...sectorIds && sectorIds.length > 0 ? { sector_id: sectorIds } : {}
6632
7095
  });
6633
7096
  setTaskCards(data);
7097
+ lastSuccessfulLoadKeyRef.current = loadKey;
6634
7098
  } catch (err) {
6635
- setError(err instanceof Error ? err.message : "Failed to load");
7099
+ setError(
7100
+ err instanceof Error ? { type: "raw", message: err.message } : { type: "localized", key: "failed_to_load" }
7101
+ );
6636
7102
  console.error("Failed to load community tasks:", err);
6637
7103
  } finally {
7104
+ if (inFlightLoadKeyRef.current === loadKey) {
7105
+ inFlightLoadKeyRef.current = null;
7106
+ }
6638
7107
  setIsLoading(false);
6639
7108
  }
6640
7109
  };
6641
7110
  loadTasks();
6642
- }, [client, isPreview, userToken, sectorIds]);
6643
- const selectorOptions = React__default.useMemo(
6644
- () => {
6645
- const sectors = taskCards.map((item) => item.sector);
6646
- let options = sectors.map((sector) => ({
6647
- value: sector.id,
6648
- label: sector.name
6649
- }));
6650
- if (sectorIds && sectorIds.length > 0) {
6651
- const orderMap = new Map(
6652
- sectorIds.map((sectorId, index) => [sectorId, index])
6653
- );
6654
- options = options.filter((option) => orderMap.has(option.value)).sort((a, b) => {
6655
- const aIndex = orderMap.get(a.value) ?? 0;
6656
- const bIndex = orderMap.get(b.value) ?? 0;
6657
- return aIndex - bIndex;
6658
- });
6659
- }
6660
- return options;
6661
- },
6662
- [taskCards, sectorIds]
6663
- );
6664
- const filteredTaskCards = React__default.useMemo(
6665
- () => {
6666
- let result = taskCards;
6667
- if (sectorIds && sectorIds.length > 0) {
6668
- const idSet = new Set(sectorIds);
6669
- const orderMap = new Map(
6670
- sectorIds.map((sectorId, index) => [sectorId, index])
6671
- );
6672
- result = result.filter((item) => idSet.has(item.sector.id));
6673
- result = [...result].sort((a, b) => {
6674
- const aIndex = orderMap.get(a.sector.id);
6675
- const bIndex = orderMap.get(b.sector.id);
6676
- if (aIndex === void 0 && bIndex === void 0) return 0;
6677
- if (aIndex === void 0) return 1;
6678
- if (bIndex === void 0) return -1;
6679
- return aIndex - bIndex;
6680
- });
6681
- }
6682
- if (selectedSectorId !== null) {
6683
- result = result.filter((item) => item.sector.id === selectedSectorId);
6684
- }
6685
- return result;
6686
- },
6687
- [taskCards, selectedSectorId, sectorIds]
6688
- );
7111
+ }, [client, isSessionReady, isPreview, userToken, sectorIds]);
7112
+ const selectorOptions = React__default.useMemo(() => {
7113
+ const sectors = taskCards.map((item) => item.sector);
7114
+ let options = sectors.map((sector) => ({
7115
+ value: sector.id,
7116
+ label: sector.name
7117
+ }));
7118
+ if (sectorIds && sectorIds.length > 0) {
7119
+ const orderMap = new Map(
7120
+ sectorIds.map((sectorId, index) => [sectorId, index])
7121
+ );
7122
+ options = options.filter((option) => orderMap.has(option.value)).sort((a, b) => {
7123
+ const aIndex = orderMap.get(a.value) ?? 0;
7124
+ const bIndex = orderMap.get(b.value) ?? 0;
7125
+ return aIndex - bIndex;
7126
+ });
7127
+ }
7128
+ return options;
7129
+ }, [taskCards, sectorIds]);
7130
+ const filteredTaskCards = React__default.useMemo(() => {
7131
+ let result = taskCards;
7132
+ if (sectorIds && sectorIds.length > 0) {
7133
+ const idSet = new Set(sectorIds);
7134
+ const orderMap = new Map(
7135
+ sectorIds.map((sectorId, index) => [sectorId, index])
7136
+ );
7137
+ result = result.filter((item) => idSet.has(item.sector.id));
7138
+ result = [...result].sort((a, b) => {
7139
+ const aIndex = orderMap.get(a.sector.id);
7140
+ const bIndex = orderMap.get(b.sector.id);
7141
+ if (aIndex === void 0 && bIndex === void 0) return 0;
7142
+ if (aIndex === void 0) return 1;
7143
+ if (bIndex === void 0) return -1;
7144
+ return aIndex - bIndex;
7145
+ });
7146
+ }
7147
+ if (selectedSectorId !== null) {
7148
+ result = result.filter((item) => item.sector.id === selectedSectorId);
7149
+ }
7150
+ return result;
7151
+ }, [taskCards, selectedSectorId, sectorIds]);
6689
7152
  const taskDependencyIndex = useMemo(() => {
6690
7153
  const index = /* @__PURE__ */ new Map();
6691
7154
  for (const sectorItem of taskCards) {
@@ -6703,7 +7166,9 @@ function CommunityTaskListInner(props) {
6703
7166
  if (eligibility.type !== EligibilityType.CommunityPreTask) {
6704
7167
  continue;
6705
7168
  }
6706
- const preTaskId = parsePreTaskIdFromEligibilityParams(eligibility.params);
7169
+ const preTaskId = parsePreTaskIdFromEligibilityParams(
7170
+ eligibility.params
7171
+ );
6707
7172
  if (!preTaskId || preTaskId === currentTaskId) {
6708
7173
  continue;
6709
7174
  }
@@ -6718,16 +7183,22 @@ function CommunityTaskListInner(props) {
6718
7183
  const handleSelectorChange = (value) => {
6719
7184
  setSelectedSectorId(value ?? null);
6720
7185
  };
6721
- const handleTaskClick = useCallback((taskCard) => {
6722
- setOpenTask(taskCard);
6723
- setOpenTaskId(null);
6724
- onTaskOpen == null ? void 0 : onTaskOpen(taskCard.card_info.id);
6725
- }, [onTaskOpen]);
6726
- const handleEligTaskClick = useCallback((taskId) => {
6727
- setOpenTaskId(taskId);
6728
- setOpenTask(null);
6729
- onTaskOpen == null ? void 0 : onTaskOpen(taskId);
6730
- }, [onTaskOpen]);
7186
+ const handleTaskClick = useCallback(
7187
+ (taskCard) => {
7188
+ setOpenTask(taskCard);
7189
+ setOpenTaskId(null);
7190
+ onTaskOpen == null ? void 0 : onTaskOpen(taskCard.card_info.id);
7191
+ },
7192
+ [onTaskOpen]
7193
+ );
7194
+ const handleEligTaskClick = useCallback(
7195
+ (taskId) => {
7196
+ setOpenTaskId(taskId);
7197
+ setOpenTask(null);
7198
+ onTaskOpen == null ? void 0 : onTaskOpen(taskId);
7199
+ },
7200
+ [onTaskOpen]
7201
+ );
6731
7202
  const handleDialogClose = useCallback(() => {
6732
7203
  setOpenTask(null);
6733
7204
  setOpenTaskId(null);
@@ -6746,138 +7217,163 @@ function CommunityTaskListInner(props) {
6746
7217
  if (!currentOpenTask) {
6747
7218
  return null;
6748
7219
  }
6749
- const updatedTask = findTaskByIdFromCards(data, currentOpenTask.card_info.id);
7220
+ const updatedTask = findTaskByIdFromCards(
7221
+ data,
7222
+ currentOpenTask.card_info.id
7223
+ );
6750
7224
  return updatedTask ?? currentOpenTask;
6751
7225
  });
6752
7226
  } catch (err) {
6753
7227
  console.error("Failed to refresh tasks:", err);
6754
7228
  }
6755
7229
  }, [client, isPreview, sectorIds]);
6756
- const refreshSingleCard = useCallback(async (cardId, cardType) => {
6757
- if (!client) return;
6758
- try {
6759
- const api = createCommunityTaskApi(client);
6760
- const latestCard = await api.getCommunityTaskCardInfo({
6761
- card_id: cardId,
6762
- card_type: cardType,
6763
- is_preview: isPreview
6764
- });
6765
- setTaskCards((currentCards) => {
6766
- let targetSectorIndex = -1;
6767
- let targetCardIndex = -1;
6768
- for (let sectorIndex = 0; sectorIndex < currentCards.length; sectorIndex += 1) {
6769
- const sectorItem = currentCards[sectorIndex];
6770
- if (!sectorItem) {
6771
- continue;
7230
+ const refreshSingleCard = useCallback(
7231
+ async (cardId, cardType) => {
7232
+ if (!client) return;
7233
+ try {
7234
+ const api = createCommunityTaskApi(client);
7235
+ const latestCard = await api.getCommunityTaskCardInfo({
7236
+ card_id: cardId,
7237
+ card_type: cardType,
7238
+ is_preview: isPreview
7239
+ });
7240
+ setTaskCards((currentCards) => {
7241
+ let targetSectorIndex = -1;
7242
+ let targetCardIndex = -1;
7243
+ for (let sectorIndex = 0; sectorIndex < currentCards.length; sectorIndex += 1) {
7244
+ const sectorItem = currentCards[sectorIndex];
7245
+ if (!sectorItem) {
7246
+ continue;
7247
+ }
7248
+ const cardIndex = sectorItem.cards.findIndex(
7249
+ (card) => card.card_type === cardType && card.card_info.id === cardId
7250
+ );
7251
+ if (cardIndex !== -1) {
7252
+ targetSectorIndex = sectorIndex;
7253
+ targetCardIndex = cardIndex;
7254
+ break;
7255
+ }
6772
7256
  }
6773
- const cardIndex = sectorItem.cards.findIndex(
6774
- (card) => card.card_type === cardType && card.card_info.id === cardId
6775
- );
6776
- if (cardIndex !== -1) {
6777
- targetSectorIndex = sectorIndex;
6778
- targetCardIndex = cardIndex;
6779
- break;
7257
+ if (targetSectorIndex === -1 || targetCardIndex === -1) {
7258
+ return currentCards;
6780
7259
  }
6781
- }
6782
- if (targetSectorIndex === -1 || targetCardIndex === -1) {
6783
- return currentCards;
6784
- }
6785
- const nextCards = [...currentCards];
6786
- const targetSector = currentCards[targetSectorIndex];
6787
- if (!targetSector) {
6788
- return currentCards;
6789
- }
6790
- const nextSectorCards = [...targetSector.cards];
6791
- nextSectorCards[targetCardIndex] = latestCard;
6792
- nextCards[targetSectorIndex] = {
6793
- ...targetSector,
6794
- cards: nextSectorCards
6795
- };
6796
- return nextCards;
6797
- });
6798
- if (cardType === TaskCardType.GTCTask) {
6799
- setOpenTask((currentOpenTask) => {
6800
- if (!currentOpenTask || currentOpenTask.card_info.id !== cardId) {
6801
- return currentOpenTask;
7260
+ const nextCards = [...currentCards];
7261
+ const targetSector = currentCards[targetSectorIndex];
7262
+ if (!targetSector) {
7263
+ return currentCards;
6802
7264
  }
6803
- return latestCard;
7265
+ const nextSectorCards = [...targetSector.cards];
7266
+ nextSectorCards[targetCardIndex] = latestCard;
7267
+ nextCards[targetSectorIndex] = {
7268
+ ...targetSector,
7269
+ cards: nextSectorCards
7270
+ };
7271
+ return nextCards;
6804
7272
  });
7273
+ if (cardType === TaskCardType.GTCTask) {
7274
+ setOpenTask((currentOpenTask) => {
7275
+ if (!currentOpenTask || currentOpenTask.card_info.id !== cardId) {
7276
+ return currentOpenTask;
7277
+ }
7278
+ return latestCard;
7279
+ });
7280
+ }
7281
+ } catch (err) {
7282
+ console.error(`Failed to refresh card ${cardType}:${cardId}:`, err);
6805
7283
  }
6806
- } catch (err) {
6807
- console.error(`Failed to refresh card ${cardType}:${cardId}:`, err);
6808
- }
6809
- }, [client, isPreview]);
6810
- const refreshSingleTask = useCallback(async (taskId) => {
6811
- await refreshSingleCard(taskId, TaskCardType.GTCTask);
6812
- }, [refreshSingleCard]);
6813
- const refreshSingleTaskChain = useCallback(async (taskChainId) => {
6814
- await refreshSingleCard(taskChainId, TaskCardType.TaskChain);
6815
- }, [refreshSingleCard]);
6816
- const handleClaimSuccess = useCallback(async (taskId) => {
6817
- if (!client) {
6818
- return;
6819
- }
6820
- if (typeof taskId !== "number") {
6821
- await refreshTaskList();
6822
- return;
6823
- }
6824
- await refreshSingleTask(taskId);
6825
- const dependentTasks = taskDependencyIndex.get(taskId);
6826
- if (dependentTasks && dependentTasks.size > 0) {
6827
- await refreshTaskList();
6828
- }
6829
- }, [client, refreshSingleTask, refreshTaskList, taskDependencyIndex]);
7284
+ },
7285
+ [client, isPreview]
7286
+ );
7287
+ const refreshSingleTask = useCallback(
7288
+ async (taskId) => {
7289
+ await refreshSingleCard(taskId, TaskCardType.GTCTask);
7290
+ },
7291
+ [refreshSingleCard]
7292
+ );
7293
+ const refreshSingleTaskChain = useCallback(
7294
+ async (taskChainId) => {
7295
+ await refreshSingleCard(taskChainId, TaskCardType.TaskChain);
7296
+ },
7297
+ [refreshSingleCard]
7298
+ );
7299
+ const handleClaimSuccess = useCallback(
7300
+ async (taskId) => {
7301
+ if (!client) {
7302
+ return;
7303
+ }
7304
+ if (typeof taskId !== "number") {
7305
+ await refreshTaskList();
7306
+ return;
7307
+ }
7308
+ await refreshSingleTask(taskId);
7309
+ const dependentTasks = taskDependencyIndex.get(taskId);
7310
+ if (dependentTasks && dependentTasks.size > 0) {
7311
+ await refreshTaskList();
7312
+ }
7313
+ },
7314
+ [client, refreshSingleTask, refreshTaskList, taskDependencyIndex]
7315
+ );
6830
7316
  const { toast } = useToast();
6831
- const handleClaimTask = useCallback(async (taskId, token, platform) => {
6832
- if (!client) return { successful: false };
6833
- try {
6834
- const api = createCommunityTaskApi(client);
6835
- const result = await api.submitTask({
6836
- task_id: taskId,
6837
- task_value: token || ""
6838
- });
6839
- if (result.successful) {
6840
- await handleClaimSuccess(taskId);
6841
- return { successful: true };
6842
- } else if (result.cool_down) {
6843
- updateCoolDown(taskId, result.cool_down);
6844
- return { successful: false, cool_down: result.cool_down };
6845
- } else {
6846
- if (platform === "Twitter") {
6847
- toast.error("Oops! Task verification failed. There might be a delay due to Twitter restrictions. Please try again later.");
6848
- } else if (platform === "Discord") {
6849
- toast.error("Oops! Task verification failed. There might be a delay due to Discord restrictions. Please try again later.");
6850
- } else if (platform === "Telegram") {
6851
- toast.error("Oops! Task verification failed. There might be a delay due to Telegram restrictions. Please try again later.");
7317
+ const handleClaimTask = useCallback(
7318
+ async (taskId, token, platform) => {
7319
+ if (!client) return { successful: false };
7320
+ try {
7321
+ const api = createCommunityTaskApi(client);
7322
+ const result = await api.submitTask({
7323
+ task_id: taskId,
7324
+ task_value: token || ""
7325
+ });
7326
+ if (result.successful) {
7327
+ await handleClaimSuccess(taskId);
7328
+ return { successful: true };
7329
+ } else if (result.cool_down) {
7330
+ updateCoolDown(taskId, result.cool_down);
7331
+ return { successful: false, cool_down: result.cool_down };
6852
7332
  } else {
6853
- toast.error("Task verification failed. Please check if you completed the required action.");
7333
+ if (platform === "Twitter") {
7334
+ toast.error(t("verification_failed_twitter"));
7335
+ } else if (platform === "Discord") {
7336
+ toast.error(t("verification_failed_discord"));
7337
+ } else if (platform === "Telegram") {
7338
+ toast.error(t("verification_failed_telegram"));
7339
+ } else {
7340
+ toast.error(t("verification_failed_generic"));
7341
+ }
7342
+ return { successful: false };
6854
7343
  }
6855
- return { successful: false };
6856
- }
6857
- } catch (err) {
6858
- console.error("Failed to submit task:", err);
6859
- const errorCode = err instanceof ApiError ? err.code : void 0;
6860
- const errorMessage = resolveCommunityTaskSubmitErrorMessage(err, errorCode);
6861
- const errorData = err instanceof ApiError ? err.data : void 0;
6862
- if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
6863
- return { successful: false, errorCode };
6864
- }
6865
- if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
6866
- const { invited = 0, min_required = 0 } = errorData;
6867
- toast.error(`You have invited ${invited} users, but need ${min_required - invited} more to complete this task.`);
7344
+ } catch (err) {
7345
+ console.error("Failed to submit task:", err);
7346
+ const apiError = err;
7347
+ const errorCode = apiError == null ? void 0 : apiError.code;
7348
+ const errorMessage = resolveCommunityTaskSubmitErrorMessage(err, {
7349
+ errorCode,
7350
+ t
7351
+ });
7352
+ const errorData = apiError == null ? void 0 : apiError.data;
7353
+ if (errorCode === ErrorCode.TASK_PARTIAL_PASS) {
7354
+ return { successful: false, errorCode };
7355
+ }
7356
+ if (errorCode === ErrorCode.INVITE_JOIN_IS_NOT_REACH && errorData) {
7357
+ const { invited = 0, min_required = 0 } = errorData;
7358
+ toast.error(
7359
+ t("discord_invites_err", {
7360
+ invited,
7361
+ need: Math.max(min_required - invited, 0)
7362
+ })
7363
+ );
7364
+ return { successful: false, errorCode };
7365
+ }
7366
+ toast.error(errorMessage);
6868
7367
  return { successful: false, errorCode };
6869
7368
  }
6870
- toast.error(errorMessage);
6871
- return { successful: false, errorCode };
6872
- }
6873
- }, [client, handleClaimSuccess, toast, updateCoolDown]);
7369
+ },
7370
+ [client, handleClaimSuccess, toast, updateCoolDown, t]
7371
+ );
6874
7372
  const isDialogOpen = openTask !== null || openTaskId !== null;
6875
7373
  const currentSelectorValue = selectedSectorId ?? void 0;
6876
- if (error) {
6877
- return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsxs("div", { className: "taskon-community-list-error", children: [
6878
- "Error: ",
6879
- error
6880
- ] }) });
7374
+ if (error2) {
7375
+ const errorMessage = error2.type === "raw" ? error2.message : t(error2.key);
7376
+ return /* @__PURE__ */ jsx("div", { className: "taskon-community-list", children: /* @__PURE__ */ jsx("div", { className: "taskon-community-list-error", children: errorMessage }) });
6881
7377
  }
6882
7378
  return /* @__PURE__ */ jsxs("div", { className: "taskon-community-list", children: [
6883
7379
  showSectorTab && !isLoading && /* @__PURE__ */ jsx(
@@ -6898,7 +7394,7 @@ function CommunityTaskListInner(props) {
6898
7394
  showSectorDescription,
6899
7395
  showSectorReward
6900
7396
  }
6901
- ) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: "No tasks available" }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
7397
+ ) : filteredTaskCards.length === 0 ? /* @__PURE__ */ jsx("div", { className: "taskon-community-list-empty", children: t("no_tasks_available") }) : filteredTaskCards.map((sectorItem) => /* @__PURE__ */ jsx(
6902
7398
  SectorItem,
6903
7399
  {
6904
7400
  sector: sectorItem,
@@ -6945,11 +7441,5 @@ function CommunityTaskListInner(props) {
6945
7441
  ] });
6946
7442
  }
6947
7443
  export {
6948
- BaseTask as B,
6949
- CardSelector as C,
6950
- TemplateTask as T,
6951
- CommunityTaskList as a,
6952
- useTaskTime as b,
6953
- useSubmitTask as c,
6954
- useTaskReward as u
7444
+ CommunityTaskList as C
6955
7445
  };