@taskon/widget-react 0.0.1 → 0.0.2

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 (66) hide show
  1. package/README.md +118 -64
  2. package/dist/CommunityTaskList.css +2694 -2951
  3. package/dist/EligibilityInfo.css +2221 -1332
  4. package/dist/LeaderboardWidget.css +403 -198
  5. package/dist/PageBuilder.css +57 -0
  6. package/dist/Quest.css +1347 -1477
  7. package/dist/TaskOnProvider.css +337 -29
  8. package/dist/ThemeProvider.css +228 -0
  9. package/dist/UserCenterWidget.css +168 -0
  10. package/dist/UserCenterWidget2.css +4917 -0
  11. package/dist/WidgetShell.css +417 -130
  12. package/dist/chunks/{CommunityTaskList-CrH6r4Av.js → CommunityTaskList-2nFy6l6m.js} +2612 -2074
  13. package/dist/chunks/{EligibilityInfo-DesW9-k9.js → EligibilityInfo-CKTl_cdU.js} +2714 -4077
  14. package/dist/chunks/{LeaderboardWidget-BSGpHKTk.js → LeaderboardWidget-DyoiiNS6.js} +288 -349
  15. package/dist/chunks/PageBuilder-DHM3Il6f.js +150 -0
  16. package/dist/chunks/{Quest-uSIVq78I.js → Quest-Dqx4OCat.js} +1380 -726
  17. package/dist/chunks/TaskOnProvider-CxtFIs3n.js +2072 -0
  18. package/dist/chunks/{WidgetShell-NlOgn1x5.js → ThemeProvider-CulHkqqY.js} +1397 -103
  19. package/dist/chunks/UserCenterWidget-SE5hqpnZ.js +8335 -0
  20. package/dist/chunks/UserCenterWidget-XL6LZRZM.js +3259 -0
  21. package/dist/chunks/{Table-CWGf2FKV.js → WidgetShell-8xn-Jivw.js} +237 -27
  22. package/dist/chunks/communitytask-es-CBNnS4o2.js +521 -0
  23. package/dist/chunks/communitytask-ja-GRf9cbdx.js +521 -0
  24. package/dist/chunks/communitytask-ko-Bf24PQKI.js +521 -0
  25. package/dist/chunks/communitytask-ru-CZm2CPoV.js +521 -0
  26. package/dist/chunks/leaderboardwidget-es-vKjrjQaz.js +146 -0
  27. package/dist/chunks/leaderboardwidget-ja-Q6u0HxKG.js +146 -0
  28. package/dist/chunks/leaderboardwidget-ko-CG6SWgxf.js +146 -0
  29. package/dist/chunks/leaderboardwidget-ru-DCcHcJGz.js +146 -0
  30. package/dist/chunks/quest-es-Dyyy0zaw.js +863 -0
  31. package/dist/chunks/quest-ja-Depog33y.js +863 -0
  32. package/dist/chunks/quest-ko-BMu3uRQJ.js +863 -0
  33. package/dist/chunks/quest-ru-xne814Rw.js +863 -0
  34. package/dist/chunks/taskwidget-es-Do9b3Mqw.js +245 -0
  35. package/dist/chunks/taskwidget-ja-CqSu-yWA.js +245 -0
  36. package/dist/chunks/taskwidget-ko-EHgXFV4B.js +245 -0
  37. package/dist/chunks/taskwidget-ru-CMbLQDK4.js +245 -0
  38. package/dist/chunks/useIsMobile-D6Ybur-6.js +30 -0
  39. package/dist/chunks/usercenter-es-Dz3Wp2vV.js +512 -0
  40. package/dist/chunks/usercenter-ja-CKE4DJC6.js +512 -0
  41. package/dist/chunks/usercenter-ko-Dtpkn2qb.js +512 -0
  42. package/dist/chunks/usercenter-ru-DnBGee45.js +512 -0
  43. package/dist/community-task.d.ts +29 -388
  44. package/dist/community-task.js +2 -7
  45. package/dist/core.d.ts +95 -28
  46. package/dist/core.js +11 -12
  47. package/dist/index.d.ts +260 -602
  48. package/dist/index.js +28 -7361
  49. package/dist/leaderboard.d.ts +5 -496
  50. package/dist/leaderboard.js +2 -15
  51. package/dist/page-builder.d.ts +20 -0
  52. package/dist/page-builder.js +4 -0
  53. package/dist/quest.d.ts +20 -292
  54. package/dist/quest.js +2 -5
  55. package/dist/user-center.d.ts +56 -0
  56. package/dist/user-center.js +4 -0
  57. package/package.json +22 -3
  58. package/dist/Table.css +0 -389
  59. package/dist/chunks/TaskOnProvider-QMwxGL44.js +0 -1435
  60. package/dist/chunks/ThemeProvider-Cs8IUVQj.js +0 -1118
  61. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +0 -119
  62. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +0 -119
  63. package/dist/chunks/useWidgetLocale-BVcopbZS.js +0 -74
  64. package/dist/chunks/usercenter-ja-DBj_dtuz.js +0 -329
  65. package/dist/chunks/usercenter-ko-DYTkHAld.js +0 -329
  66. package/dist/index.css +0 -3662
@@ -1,97 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useState, useMemo, useCallback, useEffect } from "react";
3
- import { createLeaderboardApi, LeaderboardContentType, formatRankRange, RewardsDistributeType, formatRewardText, calculatePrizePool, RewardType, LeaderboardTableColumn, isAllTimeResponse, isCampaignResponse } from "@taskon/core";
4
- import { b as useTaskOnContext } from "./ThemeProvider-Cs8IUVQj.js";
5
- import { D as Dialog, u as useResolvedWidgetConfig, W as WidgetShell } from "./WidgetShell-NlOgn1x5.js";
6
- import { u as useWidgetLocale } from "./useWidgetLocale-BVcopbZS.js";
7
- import { B as Button, T as Table, P as Pagination } from "./Table-CWGf2FKV.js";
8
- import '../LeaderboardWidget.css';function usePagination(options) {
9
- const { total, pageSize, initialPage = 0, mode = "pagination" } = options;
10
- const [page2, setPage] = useState(initialPage);
11
- const totalPages = useMemo(() => {
12
- return Math.max(1, Math.ceil(total / pageSize));
13
- }, [total, pageSize]);
14
- const safePage = useMemo(() => {
15
- return Math.min(page2, totalPages - 1);
16
- }, [page2, totalPages]);
17
- if (safePage !== page2) {
18
- setPage(safePage);
19
- }
20
- const hasPrevious = safePage > 0;
21
- const hasNext = safePage < totalPages - 1;
22
- const goToPage = useCallback(
23
- (targetPage) => {
24
- const validPage = Math.max(0, Math.min(targetPage, totalPages - 1));
25
- setPage(validPage);
26
- },
27
- [totalPages]
28
- );
29
- const goToPrevious = useCallback(() => {
30
- if (hasPrevious) {
31
- setPage((p) => p - 1);
32
- }
33
- }, [hasPrevious]);
34
- const goToNext = useCallback(() => {
35
- if (hasNext) {
36
- setPage((p) => p + 1);
37
- }
38
- }, [hasNext]);
39
- const reset = useCallback(() => {
40
- setPage(0);
41
- }, []);
42
- const startIndex = safePage * pageSize + 1;
43
- const endIndex = Math.min((safePage + 1) * pageSize, total);
44
- const hasMore = useMemo(() => {
45
- if (mode === "infinite") {
46
- return safePage < totalPages - 1;
47
- }
48
- return hasNext;
49
- }, [mode, safePage, totalPages, hasNext]);
50
- const loadedCount = useMemo(() => {
51
- if (mode === "infinite") {
52
- return Math.min((safePage + 1) * pageSize, total);
53
- }
54
- return endIndex - startIndex + 1;
55
- }, [mode, safePage, pageSize, total, startIndex, endIndex]);
56
- const loadMore = useCallback(() => {
57
- if (mode === "infinite" && hasMore) {
58
- setPage((p) => p + 1);
59
- }
60
- }, [mode, hasMore]);
61
- return {
62
- page: safePage,
63
- totalPages,
64
- hasPrevious,
65
- hasNext,
66
- goToPage,
67
- goToPrevious,
68
- goToNext,
69
- reset,
70
- startIndex,
71
- endIndex,
72
- // Infinite 模式专用
73
- loadMore,
74
- hasMore,
75
- loadedCount
76
- };
77
- }
78
- const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
79
- const v = glob[path];
80
- if (v) {
81
- return typeof v === "function" ? v() : Promise.resolve(v);
82
- }
83
- return new Promise((_, reject) => {
84
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
85
- reject.bind(
86
- null,
87
- new Error(
88
- "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
89
- )
90
- )
91
- );
92
- });
93
- };
94
- function useLeaderboard(options) {
2
+ import { useState, useCallback, useEffect, useMemo } from "react";
3
+ import { createLeaderboardApi, LeaderboardContentType, formatRankRange, RewardsDistributeType, formatRewardText, calculatePrizePool, RewardType, LeaderboardTableColumn, truncateAddress, isAllTimeResponse, isCampaignResponse } from "@taskon/core";
4
+ import { h as useTaskOnContext, c as useTranslation, e as createLocaleLoader, D as Dialog } from "./ThemeProvider-CulHkqqY.js";
5
+ import { B as Button, T as Table, P as Pagination, u as useResolvedWidgetConfig, W as WidgetShell, a as usePagination } from "./WidgetShell-8xn-Jivw.js";
6
+ import '../LeaderboardWidget.css';function useLeaderboard(options) {
95
7
  const { client } = useTaskOnContext();
96
8
  const [data, setData] = useState(null);
97
9
  const [loading2, setLoading] = useState(false);
@@ -169,12 +81,12 @@ function useCampaignReward(campaignId) {
169
81
  }, [campaignId, client]);
170
82
  const rewardSummary = useMemo(() => {
171
83
  if (!campaignInfo) return null;
172
- let totalWinners2 = 0;
84
+ let totalWinners = 0;
173
85
  const tiers = [];
174
86
  campaignInfo.winner_rewards.forEach((wr) => {
175
87
  wr.winner_layer_rewards.forEach((wlr, index) => {
176
88
  var _a;
177
- totalWinners2 += wlr.max_winners;
89
+ totalWinners += wlr.max_winners;
178
90
  const { text: rankRangeText, from: rankFrom, to: rankTo } = formatRankRange(wlr, index);
179
91
  const distributeType = ((_a = wlr.rewards[0]) == null ? void 0 : _a.reward_distribute_type) || RewardsDistributeType.Equally;
180
92
  const simpleReward = campaignInfo.winner_rewards_simple[index];
@@ -193,10 +105,10 @@ function useCampaignReward(campaignId) {
193
105
  });
194
106
  });
195
107
  });
196
- const prizePool2 = calculatePrizePool(campaignInfo.winner_rewards_simple);
108
+ const prizePool = calculatePrizePool(campaignInfo.winner_rewards_simple);
197
109
  return {
198
- prizePool: prizePool2,
199
- totalWinners: totalWinners2,
110
+ prizePool,
111
+ totalWinners,
200
112
  tiers,
201
113
  startTime: campaignInfo.start_time,
202
114
  endTime: campaignInfo.end_time,
@@ -213,6 +125,126 @@ function useCampaignReward(campaignId) {
213
125
  refresh: fetchCampaignInfo
214
126
  };
215
127
  }
128
+ const tab_all_time = "All Time";
129
+ const tab_quest = "Quest";
130
+ const tab_event = "Event";
131
+ const tab_sprint = "Sprint";
132
+ const column_rank = "Rank";
133
+ const column_position = "Position";
134
+ const column_user = "User";
135
+ const column_tasks = "Tasks";
136
+ const column_invited_users = "Invited Users";
137
+ const column_current_tier = "Current Tier";
138
+ const column_points = "Points";
139
+ const column_rewards = "Reward";
140
+ const status_ongoing = "Ongoing";
141
+ const status_ended = "Ended";
142
+ const status_upcoming = "Upcoming";
143
+ const participants = "Participants";
144
+ const prize_pool = "Prize Pool";
145
+ const total_winners = "Total Winners";
146
+ const reward_rules = "Reward Rules";
147
+ const reward_rules_title = "Reward Rules";
148
+ const reward_rules_desc = "Rewards will be given based on leaderboard rankings, determined by users' {pointsName} earned during the event.";
149
+ const event_period = "Event Period";
150
+ const reward_details = "Reward Details";
151
+ const each_receives = "Each receives {amount}";
152
+ const randomly_split = "Randomly split {amount}";
153
+ const empty_title = "No Rankings Yet";
154
+ const empty_desc = "Be the first to join and claim the top spot!";
155
+ const page = "Page";
156
+ const of = "of";
157
+ const previous = "Previous";
158
+ const next = "Next";
159
+ const loading = "Loading...";
160
+ const error = "Failed to load leaderboard";
161
+ const retry = "Retry";
162
+ const not_configured = "Not configured";
163
+ const you = "You";
164
+ const unranked = "Unranked";
165
+ const na = "N/A";
166
+ const no_data = "-";
167
+ const whitelist = "Whitelist";
168
+ const reward_type_nft = "NFT:";
169
+ const reward_type_discord_role = "Discord Role:";
170
+ const reward_type_exp = "EXP:";
171
+ const reward_type_token = "Token:";
172
+ const reward_type_cap = "CAP";
173
+ const reward_value_usd_in = "{amount} USD in {symbol}";
174
+ const reward_rank_top = "Top {val}";
175
+ const enMessages = {
176
+ tab_all_time,
177
+ tab_quest,
178
+ tab_event,
179
+ tab_sprint,
180
+ column_rank,
181
+ column_position,
182
+ column_user,
183
+ column_tasks,
184
+ column_invited_users,
185
+ column_current_tier,
186
+ column_points,
187
+ column_rewards,
188
+ status_ongoing,
189
+ status_ended,
190
+ status_upcoming,
191
+ participants,
192
+ prize_pool,
193
+ total_winners,
194
+ reward_rules,
195
+ reward_rules_title,
196
+ reward_rules_desc,
197
+ event_period,
198
+ reward_details,
199
+ each_receives,
200
+ randomly_split,
201
+ empty_title,
202
+ empty_desc,
203
+ page,
204
+ of,
205
+ previous,
206
+ next,
207
+ loading,
208
+ error,
209
+ retry,
210
+ not_configured,
211
+ you,
212
+ unranked,
213
+ na,
214
+ no_data,
215
+ whitelist,
216
+ reward_type_nft,
217
+ reward_type_discord_role,
218
+ reward_type_exp,
219
+ reward_type_token,
220
+ reward_type_cap,
221
+ reward_value_usd_in,
222
+ reward_rank_top
223
+ };
224
+ const loadMessages = createLocaleLoader(
225
+ enMessages,
226
+ {
227
+ ko: () => import("./leaderboardwidget-ko-CG6SWgxf.js").then((module) => ({
228
+ default: module.default
229
+ })),
230
+ ja: () => import("./leaderboardwidget-ja-Q6u0HxKG.js").then((module) => ({
231
+ default: module.default
232
+ })),
233
+ ru: () => import("./leaderboardwidget-ru-DCcHcJGz.js").then((module) => ({
234
+ default: module.default
235
+ })),
236
+ es: () => import("./leaderboardwidget-es-vKjrjQaz.js").then((module) => ({
237
+ default: module.default
238
+ }))
239
+ }
240
+ );
241
+ function useLeaderboardLocale() {
242
+ return useTranslation({
243
+ widgetId: "LeaderboardWidget",
244
+ defaultMessages: enMessages,
245
+ loadMessages
246
+ });
247
+ }
216
248
  function HexagonBadge({
217
249
  rank,
218
250
  colorClass
@@ -240,11 +272,12 @@ function HexagonBadge({
240
272
  ] });
241
273
  }
242
274
  function RankBadge({ rank, isAllTime = false, className = "" }) {
275
+ const { t } = useLeaderboardLocale();
243
276
  if (rank < 0) {
244
- return /* @__PURE__ */ jsx("span", { className: `taskon-leaderboard-rank taskon-leaderboard-rank--na ${className}`, children: "N/A" });
277
+ return /* @__PURE__ */ jsx("span", { className: `taskon-leaderboard-rank taskon-leaderboard-rank--na ${className}`, children: t("na") });
245
278
  }
246
279
  if (rank === 0) {
247
- return /* @__PURE__ */ jsx("span", { className: `taskon-leaderboard-rank taskon-leaderboard-rank--unranked ${className}`, children: "--" });
280
+ return /* @__PURE__ */ jsx("span", { className: `taskon-leaderboard-rank taskon-leaderboard-rank--unranked ${className}`, children: t("unranked") });
248
281
  }
249
282
  if (rank === 1) {
250
283
  return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(HexagonBadge, { rank: 1, colorClass: "gold" }) });
@@ -260,12 +293,13 @@ function RankBadge({ rank, isAllTime = false, className = "" }) {
260
293
  function UserCell({
261
294
  userId,
262
295
  userName,
296
+ displayName,
263
297
  avatar,
264
298
  isCurrentUser = false,
265
- youLabel = "YOU",
266
299
  onUserClick,
267
300
  className = ""
268
301
  }) {
302
+ const { t } = useLeaderboardLocale();
269
303
  const handleClick = () => {
270
304
  if (onUserClick) {
271
305
  onUserClick(userId, userName);
@@ -273,7 +307,13 @@ function UserCell({
273
307
  };
274
308
  const isClickable = !!onUserClick && !isCurrentUser;
275
309
  if (isCurrentUser) {
276
- return /* @__PURE__ */ jsx("div", { className: `taskon-leaderboard-user taskon-leaderboard-user--current ${className}`, children: /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-user__you-badge", children: youLabel }) });
310
+ return /* @__PURE__ */ jsx(
311
+ "div",
312
+ {
313
+ className: `taskon-leaderboard-user taskon-leaderboard-user--current ${className}`,
314
+ children: /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-user__you-badge", children: t("you") })
315
+ }
316
+ );
277
317
  }
278
318
  return /* @__PURE__ */ jsx(
279
319
  "div",
@@ -287,36 +327,36 @@ function UserCell({
287
327
  handleClick();
288
328
  }
289
329
  } : void 0,
290
- children: /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-user__name", children: userName })
330
+ children: /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-user__name", children: displayName ?? userName })
291
331
  }
292
332
  );
293
333
  }
294
- function getRewardTypeLabel(rewardType, rewardPointsName, messages) {
334
+ function getRewardTypeLabel(rewardType, rewardPointsName, t) {
295
335
  if (!rewardType) return null;
296
336
  if (rewardType === RewardType.BMintedNft || rewardType === RewardType.Cap || rewardType === RewardType.Nft) {
297
- return "NFT:";
337
+ return t("reward_type_nft");
298
338
  }
299
339
  if (rewardType === RewardType.DiscordRole) {
300
- return "Discord Role:";
340
+ return t("reward_type_discord_role");
301
341
  }
302
342
  if (rewardType === RewardType.Exp) {
303
- return "EXP:";
343
+ return t("reward_type_exp");
304
344
  }
305
345
  if (rewardType === RewardType.GTCPoints || rewardType === RewardType.Points) {
306
- return `${rewardPointsName || messages.columnPoints}:`;
346
+ return `${rewardPointsName || t("column_points")}:`;
307
347
  }
308
348
  if (rewardType === RewardType.Token) {
309
- return "Token:";
349
+ return t("reward_type_token");
310
350
  }
311
351
  if (rewardType === RewardType.Whitelist) {
312
352
  return null;
313
353
  }
314
354
  return null;
315
355
  }
316
- function getRewardValueLabel(rewardType, rewardAmount, rewardSymbol, chainLabel, isUsdtEqual, messages) {
356
+ function getRewardValueLabel(rewardType, rewardAmount, rewardSymbol, chainLabel, isUsdtEqual, t) {
317
357
  if (!rewardType) {
318
358
  return {
319
- value: rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : messages.noData,
359
+ value: rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : t("no_data"),
320
360
  showChain: !!chainLabel
321
361
  };
322
362
  }
@@ -324,22 +364,31 @@ function getRewardValueLabel(rewardType, rewardAmount, rewardSymbol, chainLabel,
324
364
  return { value: rewardSymbol || "", showChain: false };
325
365
  }
326
366
  if (rewardType === RewardType.Cap) {
327
- return { value: "CAP", showChain: false };
367
+ return { value: t("reward_type_cap"), showChain: false };
328
368
  }
329
369
  if (rewardType === RewardType.GTCPoints || rewardType === RewardType.Points) {
330
370
  return { value: rewardAmount || "", showChain: false };
331
371
  }
332
372
  if (rewardType === RewardType.Token) {
333
373
  if (isUsdtEqual) {
334
- return { value: `${rewardAmount} USD in ${rewardSymbol}`, showChain: false };
374
+ return {
375
+ value: t("reward_value_usd_in", {
376
+ amount: rewardAmount ?? "",
377
+ symbol: rewardSymbol ?? ""
378
+ }),
379
+ showChain: false
380
+ };
335
381
  }
336
- return { value: `${rewardAmount} ${rewardSymbol}`, showChain: !!chainLabel };
382
+ return {
383
+ value: `${rewardAmount} ${rewardSymbol}`,
384
+ showChain: !!chainLabel
385
+ };
337
386
  }
338
387
  if (rewardType === RewardType.Whitelist) {
339
- return { value: messages.whitelist || "Whitelist", showChain: false };
388
+ return { value: t("whitelist"), showChain: false };
340
389
  }
341
390
  return {
342
- value: rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : messages.noData,
391
+ value: rewardAmount ? `${rewardAmount} ${rewardSymbol || ""}` : t("no_data"),
343
392
  showChain: !!chainLabel
344
393
  };
345
394
  }
@@ -350,32 +399,38 @@ function RewardCell({
350
399
  rewardType,
351
400
  rewardPointsName,
352
401
  isUsdtEqual,
353
- messages,
354
402
  isPotential = false,
355
403
  className = ""
356
404
  }) {
405
+ const { t } = useLeaderboardLocale();
357
406
  if (!rewardAmount && !rewardType) {
358
- return /* @__PURE__ */ jsx("span", { className, children: messages.noData });
407
+ return /* @__PURE__ */ jsx("span", { className, children: t("no_data") });
359
408
  }
360
- const typeLabel = getRewardTypeLabel(rewardType, rewardPointsName, messages);
409
+ const typeLabel = getRewardTypeLabel(rewardType, rewardPointsName, t);
361
410
  const { value, showChain } = getRewardValueLabel(
362
411
  rewardType,
363
412
  rewardAmount,
364
413
  rewardSymbol,
365
414
  chainLabel,
366
415
  isUsdtEqual,
367
- messages
416
+ t
368
417
  );
369
418
  const potentialClass = isPotential ? "taskon-leaderboard-table__reward--potential" : "";
370
- return /* @__PURE__ */ jsxs("span", { className: `taskon-leaderboard-table__reward ${potentialClass} ${className}`, children: [
371
- typeLabel && /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-table__reward-type", children: typeLabel }),
372
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-table__reward-value", children: value }),
373
- showChain && chainLabel && /* @__PURE__ */ jsxs("span", { className: "taskon-leaderboard-table__reward-chain", children: [
374
- "(",
375
- chainLabel,
376
- ")"
377
- ] })
378
- ] });
419
+ return /* @__PURE__ */ jsxs(
420
+ "span",
421
+ {
422
+ className: `taskon-leaderboard-table__reward ${potentialClass} ${className}`,
423
+ children: [
424
+ typeLabel && /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-table__reward-type", children: typeLabel }),
425
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-table__reward-value", children: value }),
426
+ showChain && chainLabel && /* @__PURE__ */ jsxs("span", { className: "taskon-leaderboard-table__reward-chain", children: [
427
+ "(",
428
+ chainLabel,
429
+ ")"
430
+ ] })
431
+ ]
432
+ }
433
+ );
379
434
  }
380
435
  function LeaderboardTabs({
381
436
  tabs,
@@ -383,6 +438,21 @@ function LeaderboardTabs({
383
438
  onTabChange,
384
439
  className = ""
385
440
  }) {
441
+ const { t } = useLeaderboardLocale();
442
+ const getFallbackTitle = (tab) => {
443
+ switch (tab.type) {
444
+ case LeaderboardContentType.AllTime:
445
+ return t("tab_all_time");
446
+ case LeaderboardContentType.Quest:
447
+ return t("tab_quest");
448
+ case LeaderboardContentType.Event:
449
+ return t("tab_event");
450
+ case LeaderboardContentType.LeaderboardSprint:
451
+ return t("tab_sprint");
452
+ default:
453
+ return "";
454
+ }
455
+ };
386
456
  if (tabs.length <= 1) {
387
457
  return null;
388
458
  }
@@ -396,7 +466,7 @@ function LeaderboardTabs({
396
466
  "aria-controls": `leaderboard-panel-${tab.id}`,
397
467
  className: `taskon-leaderboard-tabs__tab ${isActive ? "taskon-leaderboard-tabs__tab--active" : ""}`,
398
468
  onClick: () => onTabChange(tab.id),
399
- children: tab.title
469
+ children: tab.title || getFallbackTitle(tab)
400
470
  },
401
471
  tab.id
402
472
  );
@@ -422,36 +492,38 @@ function formatTimeRange(startTime, endTime) {
422
492
  const endMinutes = String(end.getMinutes()).padStart(2, "0");
423
493
  return `(${timezone}) ${startYear}-${startMonth}-${startDay} ${startHours}:${startMinutes} ~ ${endYear}-${endMonth}-${endDay} ${endHours}:${endMinutes}`;
424
494
  }
425
- function getEventStatus(startTime, endTime, messages) {
495
+ function getEventStatus(startTime, endTime, t) {
426
496
  if (!startTime || !endTime) return null;
427
497
  const now = Date.now();
428
498
  if (now < startTime) {
429
- return { label: messages.statusUpcoming, status: "upcoming" };
499
+ return { label: t("status_upcoming"), status: "upcoming" };
430
500
  }
431
501
  if (now > endTime) {
432
- return { label: messages.statusEnded, status: "ended" };
502
+ return { label: t("status_ended"), status: "ended" };
433
503
  }
434
- return { label: messages.statusOngoing, status: "ongoing" };
504
+ return { label: t("status_ongoing"), status: "ongoing" };
435
505
  }
436
506
  function LeaderboardHeader({
437
507
  tabConfig,
438
508
  showTitle,
439
509
  rewardSummary,
440
510
  participantsCount,
441
- messages,
442
511
  onOpenRewardRules,
443
512
  className = ""
444
513
  }) {
514
+ const { t } = useLeaderboardLocale();
445
515
  const isSprint = tabConfig.type === LeaderboardContentType.LeaderboardSprint;
446
- const eventStatus = getEventStatus(tabConfig.startTime, tabConfig.endTime, messages);
516
+ const sprintRewardSummary = isSprint ? rewardSummary ?? null : null;
517
+ const eventStatus = getEventStatus(tabConfig.startTime, tabConfig.endTime, t);
447
518
  const hasTimeRange = tabConfig.startTime && tabConfig.endTime;
448
519
  const hasParticipants = typeof participantsCount === "number";
449
- const hasContent = eventStatus || hasTimeRange || hasParticipants;
450
- if (!hasContent && !showTitle && !isSprint) {
520
+ const shouldShowInfo = Boolean(showTitle && (eventStatus || hasTimeRange || hasParticipants));
521
+ const shouldShowRewardInfo = sprintRewardSummary !== null;
522
+ if (!shouldShowInfo && !shouldShowRewardInfo) {
451
523
  return null;
452
524
  }
453
525
  return /* @__PURE__ */ jsxs("div", { className: `taskon-leaderboard-header ${className}`, children: [
454
- (eventStatus || hasTimeRange || hasParticipants) && /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__info", children: [
526
+ shouldShowInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__info", children: [
455
527
  eventStatus && /* @__PURE__ */ jsx(
456
528
  "span",
457
529
  {
@@ -462,19 +534,19 @@ function LeaderboardHeader({
462
534
  hasTimeRange && /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__time", children: formatTimeRange(tabConfig.startTime, tabConfig.endTime) }),
463
535
  hasParticipants && (eventStatus || hasTimeRange) && /* @__PURE__ */ jsx("div", { className: "taskon-leaderboard-header__separator" }),
464
536
  hasParticipants && /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__participants", children: [
465
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__participants-label", children: messages.participants || "Participants" }),
537
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__participants-label", children: t("participants") }),
466
538
  /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__participants-value", children: participantsCount.toLocaleString() })
467
539
  ] })
468
540
  ] }),
469
- isSprint && rewardSummary && /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__reward-info", children: [
541
+ shouldShowRewardInfo && /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__reward-info", children: [
470
542
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__reward-item", children: [
471
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-label", children: messages.prizePool }),
472
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-value", children: rewardSummary.prizePool || "-" })
543
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-label", children: t("prize_pool") }),
544
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-value", children: sprintRewardSummary.prizePool || t("no_data") })
473
545
  ] }),
474
546
  /* @__PURE__ */ jsx("div", { className: "taskon-leaderboard-header__reward-separator" }),
475
547
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-header__reward-item", children: [
476
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-label", children: messages.totalWinners }),
477
- /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-value", children: rewardSummary.totalWinners })
548
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-label", children: t("total_winners") }),
549
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-header__reward-value", children: sprintRewardSummary.totalWinners })
478
550
  ] }),
479
551
  onOpenRewardRules && /* @__PURE__ */ jsx(
480
552
  Button,
@@ -483,28 +555,28 @@ function LeaderboardHeader({
483
555
  size: "small",
484
556
  onClick: onOpenRewardRules,
485
557
  className: "taskon-leaderboard-header__reward-rules-btn",
486
- children: messages.rewardRules
558
+ children: t("reward_rules")
487
559
  }
488
560
  )
489
561
  ] })
490
562
  ] });
491
563
  }
492
- function getColumnTitle(column, messages, pointsName) {
564
+ function getColumnTitle(column, t, pointsName) {
493
565
  switch (column) {
494
566
  case LeaderboardTableColumn.Rank:
495
- return messages.columnRank;
567
+ return t("column_rank");
496
568
  case LeaderboardTableColumn.User:
497
- return messages.columnUser;
569
+ return t("column_user");
498
570
  case LeaderboardTableColumn.Tasks:
499
- return messages.columnTasks;
571
+ return t("column_tasks");
500
572
  case LeaderboardTableColumn.InvitedUsers:
501
- return messages.columnInvitedUsers;
573
+ return t("column_invited_users");
502
574
  case LeaderboardTableColumn.CurrentTier:
503
- return messages.columnCurrentTier;
575
+ return t("column_current_tier");
504
576
  case LeaderboardTableColumn.Points:
505
- return pointsName || messages.columnPoints;
577
+ return pointsName || t("column_points");
506
578
  case LeaderboardTableColumn.Rewards:
507
- return messages.columnRewards;
579
+ return t("column_rewards");
508
580
  default:
509
581
  return "";
510
582
  }
@@ -553,17 +625,20 @@ function convertCampaignData(data) {
553
625
  };
554
626
  });
555
627
  }
628
+ function formatUserDisplayName(userName) {
629
+ return truncateAddress(userName, 6, 6);
630
+ }
556
631
  function LeaderboardTable({
557
632
  tabConfig,
558
633
  allTimeData,
559
634
  campaignData,
560
635
  currentUserId,
561
- messages,
562
636
  onUserClick,
563
637
  rewardTiers,
564
638
  loading: loading2 = false,
565
639
  className = ""
566
640
  }) {
641
+ const { t } = useLeaderboardLocale();
567
642
  const isAllTime = tabConfig.type === LeaderboardContentType.AllTime;
568
643
  const tableData = useMemo(() => {
569
644
  if (isAllTime && allTimeData) {
@@ -578,7 +653,7 @@ function LeaderboardTable({
578
653
  return tabConfig.columns.map((column) => {
579
654
  const baseColumn = {
580
655
  key: column,
581
- title: getColumnTitle(column, messages, tabConfig.pointsName)
656
+ title: getColumnTitle(column, t, tabConfig.pointsName)
582
657
  };
583
658
  switch (column) {
584
659
  case LeaderboardTableColumn.Rank:
@@ -596,9 +671,9 @@ function LeaderboardTable({
596
671
  {
597
672
  userId: row.userId,
598
673
  userName: row.userName,
674
+ displayName: formatUserDisplayName(row.userName),
599
675
  avatar: row.avatar,
600
676
  isCurrentUser: currentUserId === row.userId,
601
- youLabel: messages.you,
602
677
  onUserClick
603
678
  }
604
679
  )
@@ -607,25 +682,25 @@ function LeaderboardTable({
607
682
  return {
608
683
  ...baseColumn,
609
684
  width: 142,
610
- render: (_, row) => row.tasks ?? messages.noData
685
+ render: (_, row) => row.tasks ?? t("no_data")
611
686
  };
612
687
  case LeaderboardTableColumn.InvitedUsers:
613
688
  return {
614
689
  ...baseColumn,
615
690
  width: 142,
616
- render: (_, row) => row.invitedUsers ?? messages.noData
691
+ render: (_, row) => row.invitedUsers ?? t("no_data")
617
692
  };
618
693
  case LeaderboardTableColumn.CurrentTier:
619
694
  return {
620
695
  ...baseColumn,
621
696
  width: 142,
622
- render: (_, row) => row.currentTier ?? messages.noData
697
+ render: (_, row) => row.currentTier ?? t("no_data")
623
698
  };
624
699
  case LeaderboardTableColumn.Points:
625
700
  return {
626
701
  ...baseColumn,
627
702
  width: 142,
628
- render: (_, row) => row.points && row.points > 0 ? row.points.toLocaleString() : messages.noData
703
+ render: (_, row) => row.points && row.points > 0 ? row.points.toLocaleString() : t("no_data")
629
704
  };
630
705
  case LeaderboardTableColumn.Rewards:
631
706
  return {
@@ -642,8 +717,7 @@ function LeaderboardTable({
642
717
  chainLabel: row.chainLabel,
643
718
  rewardType: row.rewardType,
644
719
  rewardPointsName: row.rewardPointsName,
645
- isUsdtEqual: row.isUsdtEqual,
646
- messages
720
+ isUsdtEqual: row.isUsdtEqual
647
721
  }
648
722
  );
649
723
  }
@@ -655,22 +729,28 @@ function LeaderboardTable({
655
729
  rewardAmount: reward.rewardAmount,
656
730
  rewardSymbol: reward.rewardSymbol,
657
731
  chainLabel: reward.chainLabel,
658
- messages,
659
732
  isPotential: true
660
733
  }
661
734
  );
662
735
  }
663
- return messages.noData;
736
+ return t("no_data");
664
737
  }
665
738
  };
666
739
  default:
667
740
  return {
668
741
  ...baseColumn,
669
- render: () => messages.noData
742
+ render: () => t("no_data")
670
743
  };
671
744
  }
672
745
  });
673
- }, [tabConfig.columns, tabConfig.pointsName, messages, currentUserId, onUserClick, rewardTiers]);
746
+ }, [
747
+ tabConfig.columns,
748
+ tabConfig.pointsName,
749
+ t,
750
+ currentUserId,
751
+ onUserClick,
752
+ rewardTiers
753
+ ]);
674
754
  const rowConfig = useMemo(
675
755
  () => ({
676
756
  getRowKey: (row) => row.id,
@@ -680,10 +760,10 @@ function LeaderboardTable({
680
760
  );
681
761
  const emptyConfig = useMemo(
682
762
  () => ({
683
- title: messages.emptyTitle,
684
- description: messages.emptyDesc
763
+ title: t("empty_title"),
764
+ description: t("empty_desc")
685
765
  }),
686
- [messages.emptyTitle, messages.emptyDesc]
766
+ [t]
687
767
  );
688
768
  return /* @__PURE__ */ jsx(
689
769
  Table,
@@ -692,7 +772,7 @@ function LeaderboardTable({
692
772
  data: tableData,
693
773
  rowConfig,
694
774
  loading: loading2,
695
- loadingText: messages.loading,
775
+ loadingText: t("loading"),
696
776
  empty: emptyConfig,
697
777
  striped: true,
698
778
  className
@@ -707,7 +787,6 @@ function LeaderboardPagination({
707
787
  hasNext,
708
788
  onPrevious,
709
789
  onNext,
710
- messages,
711
790
  className = ""
712
791
  }) {
713
792
  if (totalPages <= 1 || total === 0) {
@@ -731,7 +810,7 @@ function LeaderboardPagination({
731
810
  function formatDate(timestamp) {
732
811
  if (!timestamp) return "";
733
812
  const date = new Date(timestamp);
734
- return date.toLocaleDateString("en-US", {
813
+ return date.toLocaleDateString(void 0, {
735
814
  year: "numeric",
736
815
  month: "short",
737
816
  day: "numeric",
@@ -739,26 +818,23 @@ function formatDate(timestamp) {
739
818
  minute: "2-digit"
740
819
  });
741
820
  }
742
- function getDistributeText(distributeType, messages) {
821
+ function getDistributeText(distributeType, t) {
743
822
  switch (distributeType) {
744
823
  case RewardsDistributeType.Equally:
745
- return "Each receives";
824
+ return t("each_receives", { amount: "{amount}" }).replace("{amount}", "").trim();
746
825
  case RewardsDistributeType.Random:
747
- return "Randomly split";
826
+ return t("randomly_split", { amount: "{amount}" }).replace("{amount}", "").trim();
748
827
  default:
749
828
  return "";
750
829
  }
751
830
  }
752
831
  function TierRow({
753
832
  tier,
754
- messages
833
+ t
755
834
  }) {
756
- const distributeText = getDistributeText(tier.distributeType);
835
+ const distributeText = getDistributeText(tier.distributeType, t);
757
836
  return /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__tier", children: [
758
- /* @__PURE__ */ jsxs("span", { className: "taskon-leaderboard-modal__tier-rank", children: [
759
- "Top ",
760
- tier.rankRangeText
761
- ] }),
837
+ /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-modal__tier-rank", children: t("reward_rank_top", { val: tier.rankRangeText }) }),
762
838
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__tier-reward", children: [
763
839
  distributeText && /* @__PURE__ */ jsx("span", { className: "taskon-leaderboard-modal__tier-distribute", children: distributeText }),
764
840
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__tier-token", children: [
@@ -785,16 +861,15 @@ function RewardRulesModal({
785
861
  isOpen,
786
862
  onClose,
787
863
  rewardSummary,
788
- messages,
789
864
  className = ""
790
865
  }) {
866
+ const { t } = useLeaderboardLocale();
791
867
  if (!rewardSummary) {
792
868
  return null;
793
869
  }
794
- const description = messages.rewardRulesDesc.replace(
795
- "{pointsName}",
796
- rewardSummary.pointsName || "points"
797
- );
870
+ const description = t("reward_rules_desc", {
871
+ pointsName: rewardSummary.pointsName || t("column_points")
872
+ });
798
873
  return /* @__PURE__ */ jsx(
799
874
  Dialog,
800
875
  {
@@ -802,16 +877,16 @@ function RewardRulesModal({
802
877
  onOpenChange: (open) => {
803
878
  if (!open) onClose();
804
879
  },
805
- title: messages.rewardRulesTitle,
880
+ title: t("reward_rules_title"),
806
881
  showCloseButton: true,
807
882
  className,
808
883
  contentClassName: "taskon-leaderboard-modal",
809
884
  maxWidth: 480,
810
885
  children: /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__content", children: [
811
- /* @__PURE__ */ jsx("h2", { className: "taskon-leaderboard-modal__title", children: messages.rewardRulesTitle }),
886
+ /* @__PURE__ */ jsx("h2", { className: "taskon-leaderboard-modal__title", children: t("reward_rules_title") }),
812
887
  /* @__PURE__ */ jsx("p", { className: "taskon-leaderboard-modal__desc", children: description }),
813
888
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__section", children: [
814
- /* @__PURE__ */ jsx("h3", { className: "taskon-leaderboard-modal__section-title", children: messages.eventPeriod }),
889
+ /* @__PURE__ */ jsx("h3", { className: "taskon-leaderboard-modal__section-title", children: t("event_period") }),
815
890
  /* @__PURE__ */ jsxs("p", { className: "taskon-leaderboard-modal__period", children: [
816
891
  formatDate(rewardSummary.startTime),
817
892
  " -",
@@ -820,8 +895,8 @@ function RewardRulesModal({
820
895
  ] })
821
896
  ] }),
822
897
  /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard-modal__section", children: [
823
- /* @__PURE__ */ jsx("h3", { className: "taskon-leaderboard-modal__section-title", children: messages.rewardDetails }),
824
- /* @__PURE__ */ jsx("div", { className: "taskon-leaderboard-modal__tiers", children: rewardSummary.tiers.map((tier) => /* @__PURE__ */ jsx(TierRow, { tier, messages }, tier.tierNo)) })
898
+ /* @__PURE__ */ jsx("h3", { className: "taskon-leaderboard-modal__section-title", children: t("reward_details") }),
899
+ /* @__PURE__ */ jsx("div", { className: "taskon-leaderboard-modal__tiers", children: rewardSummary.tiers.map((tier) => /* @__PURE__ */ jsx(TierRow, { tier, t }, tier.tierNo)) })
825
900
  ] })
826
901
  ] })
827
902
  }
@@ -832,131 +907,9 @@ function mergeLeaderboardConfig(props, cloud) {
832
907
  config: props.config ?? cloud ?? null
833
908
  };
834
909
  }
835
- const tabAllTime = "All Time";
836
- const tabQuest = "Quest";
837
- const tabEvent = "Event";
838
- const tabSprint = "Sprint";
839
- const columnRank = "Rank";
840
- const columnPosition = "Position";
841
- const columnUser = "User";
842
- const columnTasks = "Tasks";
843
- const columnInvitedUsers = "Invited Users";
844
- const columnCurrentTier = "Current Tier";
845
- const columnPoints = "Points";
846
- const columnRewards = "Reward";
847
- const statusOngoing = "Ongoing";
848
- const statusEnded = "Ended";
849
- const statusUpcoming = "Upcoming";
850
- const participants = "Participants";
851
- const prizePool = "Prize Pool";
852
- const totalWinners = "Total Winners";
853
- const rewardRules = "Reward Rules";
854
- const rewardRulesTitle = "Reward Rules";
855
- const rewardRulesDesc = "Rewards will be given based on leaderboard rankings, determined by users' {pointsName} earned during the event.";
856
- const eventPeriod = "Event Period";
857
- const rewardDetails = "Reward Details";
858
- const eachReceives = "Each receives {amount}";
859
- const randomlySplit = "Randomly split {amount}";
860
- const emptyTitle = "No Rankings Yet";
861
- const emptyDesc = "Be the first to join and claim the top spot!";
862
- const page = "Page";
863
- const of = "of";
864
- const previous = "Previous";
865
- const next = "Next";
866
- const loading = "Loading...";
867
- const error = "Failed to load leaderboard";
868
- const retry = "Retry";
869
- const you = "You";
870
- const unranked = "Unranked";
871
- const na = "N/A";
872
- const noData = "-";
873
- const whitelist = "Whitelist";
874
- const enMessages = {
875
- tabAllTime,
876
- tabQuest,
877
- tabEvent,
878
- tabSprint,
879
- columnRank,
880
- columnPosition,
881
- columnUser,
882
- columnTasks,
883
- columnInvitedUsers,
884
- columnCurrentTier,
885
- columnPoints,
886
- columnRewards,
887
- statusOngoing,
888
- statusEnded,
889
- statusUpcoming,
890
- participants,
891
- prizePool,
892
- totalWinners,
893
- rewardRules,
894
- rewardRulesTitle,
895
- rewardRulesDesc,
896
- eventPeriod,
897
- rewardDetails,
898
- eachReceives,
899
- randomlySplit,
900
- emptyTitle,
901
- emptyDesc,
902
- page,
903
- of,
904
- previous,
905
- next,
906
- loading,
907
- error,
908
- retry,
909
- you,
910
- unranked,
911
- na,
912
- noData,
913
- whitelist
914
- };
915
- const en = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
916
- __proto__: null,
917
- columnCurrentTier,
918
- columnInvitedUsers,
919
- columnPoints,
920
- columnPosition,
921
- columnRank,
922
- columnRewards,
923
- columnTasks,
924
- columnUser,
925
- default: enMessages,
926
- eachReceives,
927
- emptyDesc,
928
- emptyTitle,
929
- error,
930
- eventPeriod,
931
- loading,
932
- na,
933
- next,
934
- noData,
935
- of,
936
- page,
937
- participants,
938
- previous,
939
- prizePool,
940
- randomlySplit,
941
- retry,
942
- rewardDetails,
943
- rewardRules,
944
- rewardRulesDesc,
945
- rewardRulesTitle,
946
- statusEnded,
947
- statusOngoing,
948
- statusUpcoming,
949
- tabAllTime,
950
- tabEvent,
951
- tabQuest,
952
- tabSprint,
953
- totalWinners,
954
- unranked,
955
- whitelist,
956
- you
957
- }, Symbol.toStringTag, { value: "Module" }));
958
910
  function LeaderboardWidget(props) {
959
- const { widgetId } = props;
911
+ const { widgetId, themeMode } = props;
912
+ const { t } = useLeaderboardLocale();
960
913
  const { functionConfig, cloudTheme, isConfigLoading, configError } = useResolvedWidgetConfig(widgetId);
961
914
  const mergedConfig = useMemo(() => {
962
915
  return mergeLeaderboardConfig(
@@ -964,21 +917,23 @@ function LeaderboardWidget(props) {
964
917
  functionConfig ?? null
965
918
  );
966
919
  }, [props.config, functionConfig]);
920
+ const isConfigured = !!mergedConfig.config && Array.isArray(mergedConfig.config.leaderboards) && mergedConfig.config.leaderboards.length > 0;
967
921
  return /* @__PURE__ */ jsx(
968
922
  WidgetShell,
969
923
  {
970
924
  widgetId,
971
925
  isConfigLoading,
972
926
  cloudTheme,
927
+ themeMode,
973
928
  className: "taskon-leaderboard",
974
- errorMessage: configError ?? (!mergedConfig.config ? "Leaderboard config is required. Please provide config via props or widgetId." : void 0),
975
- children: /* @__PURE__ */ jsx(
929
+ errorMessage: configError ?? (!isConfigured ? t("not_configured") : void 0),
930
+ children: isConfigured ? /* @__PURE__ */ jsx(
976
931
  LeaderboardWidgetInner,
977
932
  {
978
933
  ...props,
979
934
  config: mergedConfig.config
980
935
  }
981
- )
936
+ ) : null
982
937
  }
983
938
  );
984
939
  }
@@ -992,11 +947,7 @@ function LeaderboardWidgetInner({
992
947
  }) {
993
948
  var _a;
994
949
  const { userId } = useTaskOnContext();
995
- const { messages } = useWidgetLocale({
996
- widgetId: "LeaderboardWidget",
997
- defaultMessages: enMessages,
998
- loadMessages: (locale) => __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./locales/en.json": () => Promise.resolve().then(() => en), "./locales/ja.json": () => import("./leaderboardwidget-ja-Bj6gz6y1.js"), "./locales/ko.json": () => import("./leaderboardwidget-ko-f1cLO9ic.js") }), `./locales/${locale}.json`, 3)
999
- });
950
+ const { t } = useLeaderboardLocale();
1000
951
  const [activeTabId, setActiveTabId] = useState(
1001
952
  defaultTabId || ((_a = config.leaderboards[0]) == null ? void 0 : _a.id) || ""
1002
953
  );
@@ -1004,14 +955,17 @@ function LeaderboardWidgetInner({
1004
955
  const currentTab = useMemo(() => {
1005
956
  return config.leaderboards.find((tab) => tab.id === activeTabId);
1006
957
  }, [config.leaderboards, activeTabId]);
958
+ const [paginationTotal, setPaginationTotal] = useState(0);
1007
959
  const {
1008
960
  page: page2,
961
+ totalPages: actualTotalPages,
962
+ hasPrevious,
963
+ hasNext,
1009
964
  goToPrevious,
1010
965
  goToNext,
1011
966
  reset: resetPagination
1012
967
  } = usePagination({
1013
- total: 0,
1014
- // 初始值,hasPrevious/hasNext 将根据实际 total 重新计算
968
+ total: paginationTotal,
1015
969
  pageSize: config.displayOptions.rows
1016
970
  });
1017
971
  const {
@@ -1025,9 +979,9 @@ function LeaderboardWidgetInner({
1025
979
  page: page2,
1026
980
  pageSize: config.displayOptions.rows
1027
981
  });
1028
- const actualTotalPages = Math.max(1, Math.ceil(total / config.displayOptions.rows));
1029
- const hasPrevious = page2 > 0;
1030
- const hasNext = page2 < actualTotalPages - 1;
982
+ useEffect(() => {
983
+ setPaginationTotal(total);
984
+ }, [total]);
1031
985
  const isSprint = (currentTab == null ? void 0 : currentTab.type) === LeaderboardContentType.LeaderboardSprint;
1032
986
  const { rewardSummary, loading: rewardLoading } = useCampaignReward(
1033
987
  isSprint ? currentTab == null ? void 0 : currentTab.relatedId : void 0
@@ -1066,7 +1020,7 @@ function LeaderboardWidgetInner({
1066
1020
  }, [leaderboardData]);
1067
1021
  if (leaderboardError) {
1068
1022
  return /* @__PURE__ */ jsx("div", { className: `taskon-leaderboard taskon-leaderboard--error ${className}`, style, children: /* @__PURE__ */ jsxs("div", { className: "taskon-leaderboard__error", children: [
1069
- /* @__PURE__ */ jsx("p", { className: "taskon-leaderboard__error-text", children: messages.error }),
1023
+ /* @__PURE__ */ jsx("p", { className: "taskon-leaderboard__error-text", children: t("error") }),
1070
1024
  /* @__PURE__ */ jsx(
1071
1025
  Button,
1072
1026
  {
@@ -1074,7 +1028,7 @@ function LeaderboardWidgetInner({
1074
1028
  size: "medium",
1075
1029
  onClick: refreshLeaderboard,
1076
1030
  className: "taskon-leaderboard__retry-btn",
1077
- children: messages.retry
1031
+ children: t("retry")
1078
1032
  }
1079
1033
  )
1080
1034
  ] }) });
@@ -1098,7 +1052,6 @@ function LeaderboardWidgetInner({
1098
1052
  showTitle: config.displayOptions.showTitle,
1099
1053
  rewardSummary,
1100
1054
  participantsCount,
1101
- messages,
1102
1055
  onOpenRewardRules: isSprint ? handleOpenRewardRules : void 0
1103
1056
  }
1104
1057
  ),
@@ -1109,7 +1062,6 @@ function LeaderboardWidgetInner({
1109
1062
  allTimeData,
1110
1063
  campaignData,
1111
1064
  currentUserId: userId,
1112
- messages,
1113
1065
  onUserClick,
1114
1066
  rewardTiers: rewardSummary == null ? void 0 : rewardSummary.tiers,
1115
1067
  loading: leaderboardLoading || rewardLoading,
@@ -1125,8 +1077,7 @@ function LeaderboardWidgetInner({
1125
1077
  hasPrevious,
1126
1078
  hasNext,
1127
1079
  onPrevious: goToPrevious,
1128
- onNext: goToNext,
1129
- messages
1080
+ onNext: goToNext
1130
1081
  }
1131
1082
  ),
1132
1083
  isSprint && /* @__PURE__ */ jsx(
@@ -1134,23 +1085,11 @@ function LeaderboardWidgetInner({
1134
1085
  {
1135
1086
  isOpen: isRewardModalOpen,
1136
1087
  onClose: handleCloseRewardRules,
1137
- rewardSummary,
1138
- messages
1088
+ rewardSummary
1139
1089
  }
1140
1090
  )
1141
1091
  ] });
1142
1092
  }
1143
1093
  export {
1144
- LeaderboardWidget as L,
1145
- RankBadge as R,
1146
- UserCell as U,
1147
- __variableDynamicImportRuntimeHelper as _,
1148
- useCampaignReward as a,
1149
- usePagination as b,
1150
- LeaderboardTabs as c,
1151
- LeaderboardHeader as d,
1152
- LeaderboardTable as e,
1153
- LeaderboardPagination as f,
1154
- RewardRulesModal as g,
1155
- useLeaderboard as u
1094
+ LeaderboardWidget as L
1156
1095
  };