@medialane/ui 0.39.0 → 0.41.0

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 (35) hide show
  1. package/dist/components/asset-collection-bar.cjs +8 -1
  2. package/dist/components/asset-collection-bar.cjs.map +1 -1
  3. package/dist/components/asset-collection-bar.d.cts +12 -7
  4. package/dist/components/asset-collection-bar.d.ts +12 -7
  5. package/dist/components/asset-collection-bar.js +8 -1
  6. package/dist/components/asset-collection-bar.js.map +1 -1
  7. package/dist/components/asset-license-summary.cjs +1 -1
  8. package/dist/components/asset-license-summary.cjs.map +1 -1
  9. package/dist/components/asset-license-summary.js +1 -1
  10. package/dist/components/asset-license-summary.js.map +1 -1
  11. package/dist/components/asset-marketplace-panel.cjs +18 -16
  12. package/dist/components/asset-marketplace-panel.cjs.map +1 -1
  13. package/dist/components/asset-marketplace-panel.js +18 -16
  14. package/dist/components/asset-marketplace-panel.js.map +1 -1
  15. package/dist/components/asset-markets-tab.cjs +2 -2
  16. package/dist/components/asset-markets-tab.cjs.map +1 -1
  17. package/dist/components/asset-markets-tab.js +2 -2
  18. package/dist/components/asset-markets-tab.js.map +1 -1
  19. package/dist/components/asset-overview-content.cjs +3 -3
  20. package/dist/components/asset-overview-content.cjs.map +1 -1
  21. package/dist/components/asset-overview-content.js +3 -3
  22. package/dist/components/asset-overview-content.js.map +1 -1
  23. package/dist/components/asset-top-sections.cjs +1 -15
  24. package/dist/components/asset-top-sections.cjs.map +1 -1
  25. package/dist/components/asset-top-sections.d.cts +4 -2
  26. package/dist/components/asset-top-sections.d.ts +4 -2
  27. package/dist/components/asset-top-sections.js +1 -15
  28. package/dist/components/asset-top-sections.js.map +1 -1
  29. package/dist/components/rewards/leaderboard-table.cjs +3 -26
  30. package/dist/components/rewards/leaderboard-table.cjs.map +1 -1
  31. package/dist/components/rewards/leaderboard-table.d.cts +7 -3
  32. package/dist/components/rewards/leaderboard-table.d.ts +7 -3
  33. package/dist/components/rewards/leaderboard-table.js +3 -26
  34. package/dist/components/rewards/leaderboard-table.js.map +1 -1
  35. package/package.json +1 -1
@@ -26,15 +26,8 @@ var import_jsx_runtime = require("react/jsx-runtime");
26
26
  var import_cn = require("../../utils/cn.js");
27
27
  var import_address = require("../../utils/address.js");
28
28
  var import_level_badge = require("./level-badge.js");
29
- function rankAccent(rank) {
30
- if (rank === 1) return "#f59e0b";
31
- if (rank === 2) return "#94a3b8";
32
- if (rank === 3) return "#b45309";
33
- return null;
34
- }
35
29
  function LeaderboardTable({ entries, highlightAddress, renderAddress, className }) {
36
30
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("overflow-hidden rounded-xl border border-border", className), children: entries.map((e) => {
37
- const accent = rankAccent(e.rank);
38
31
  const isViewer = highlightAddress != null && e.address === highlightAddress;
39
32
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
40
33
  "div",
@@ -44,14 +37,6 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
44
37
  isViewer && "bg-primary/10"
45
38
  ),
46
39
  children: [
47
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48
- "span",
49
- {
50
- className: "w-8 shrink-0 text-center text-sm font-black tabular-nums",
51
- style: accent ? { color: accent } : void 0,
52
- children: e.rank
53
- }
54
- ),
55
40
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: [
56
41
  renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address),
57
42
  isViewer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-1.5 text-xs text-muted-foreground", children: "(you)" })
@@ -59,7 +44,7 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
59
44
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_level_badge.LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm", className: "hidden sm:inline-flex" }),
60
45
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "shrink-0 text-sm font-semibold tabular-nums", children: [
61
46
  e.totalXp.toLocaleString(),
62
- " XP"
47
+ " pts"
63
48
  ] })
64
49
  ]
65
50
  },
@@ -67,22 +52,14 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
67
52
  );
68
53
  }) });
69
54
  }
70
- function LeaderboardWidget({ entries, title = "Top Creators", href, renderAddress, className }) {
55
+ function LeaderboardWidget({ entries, title = "Community Rewards", href, renderAddress, className }) {
71
56
  if (entries.length === 0) return null;
72
57
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: (0, import_cn.cn)("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
73
58
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-3 flex items-center justify-between", children: [
74
59
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-base font-black", children: title }),
75
- href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View leaderboard \u2192" })
60
+ href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View scoreboard \u2192" })
76
61
  ] }),
77
62
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "space-y-2.5", children: entries.map((e) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "flex items-center gap-2.5", children: [
78
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
79
- "span",
80
- {
81
- className: "w-5 shrink-0 text-center text-sm font-black tabular-nums",
82
- style: rankAccent(e.rank) ? { color: rankAccent(e.rank) } : void 0,
83
- children: e.rank
84
- }
85
- ),
86
63
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address) }),
87
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_level_badge.LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm" })
88
65
  ] }, e.address)) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\nfunction rankAccent(rank: number): string | null {\n if (rank === 1) return \"#f59e0b\";\n if (rank === 2) return \"#94a3b8\";\n if (rank === 3) return \"#b45309\";\n return null;\n}\n\n/** Full leaderboard rows: rank, address, level chip, XP. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const accent = rankAccent(e.rank);\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span\n className=\"w-8 shrink-0 text-center text-sm font-black tabular-nums\"\n style={accent ? { color: accent } : undefined}\n >\n {e.rank}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">{e.totalXp.toLocaleString()} XP</span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full leaderboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact top-N card for homepage/discover rails. */\nexport function LeaderboardWidget({ entries, title = \"Top Creators\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View leaderboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span\n className=\"w-5 shrink-0 text-center text-sm font-black tabular-nums\"\n style={rankAccent(e.rank) ? { color: rankAccent(e.rank)! } : undefined}\n >\n {e.rank}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CY;AA7CZ,gBAAmB;AACnB,qBAA+B;AAC/B,yBAA2B;AAqB3B,SAAS,WAAW,MAA6B;AAC/C,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,SAAO;AACT;AAGO,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,4CAAC,SAAI,eAAW,cAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,SAAS,WAAW,EAAE,IAAI;AAChC,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,eAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,SAAS,EAAE,OAAO,OAAO,IAAI;AAAA,cAEnC,YAAE;AAAA;AAAA,UACL;AAAA,UACA,6CAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,YACnE,YAAY,4CAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,6CAAC,UAAK,WAAU,+CAA+C;AAAA,cAAE,QAAQ,eAAe;AAAA,YAAE;AAAA,aAAG;AAAA;AAAA;AAAA,MAjBxF,EAAE;AAAA,IAkBT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,gBAAgB,MAAM,eAAe,UAAU,GAA2B;AAC7H,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,6CAAC,aAAQ,eAAW,cAAG,sDAAsD,SAAS,GACpF;AAAA,iDAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,4CAAC,OAAE,MAAY,WAAU,iEAAgE,qCAEzF;AAAA,OAEJ;AAAA,IACA,4CAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,6CAAC,QAAmB,WAAU,6BAC5B;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,WAAW,EAAE,IAAI,IAAI,EAAE,OAAO,WAAW,EAAE,IAAI,EAAG,IAAI;AAAA,UAE5D,YAAE;AAAA;AAAA,MACL;AAAA,MACA,4CAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO,GACtE;AAAA,MACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAV1F,EAAE,OAWX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring this celebrates participation, not competition. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">{e.totalXp.toLocaleString()} pts</span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CY;AAzCZ,gBAAmB;AACnB,qBAA+B;AAC/B,yBAA2B;AA0BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,4CAAC,SAAI,eAAW,cAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,eAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA,uDAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,YACnE,YAAY,4CAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,6CAAC,UAAK,WAAU,+CAA+C;AAAA,cAAE,QAAQ,eAAe;AAAA,YAAE;AAAA,aAAI;AAAA;AAAA;AAAA,MAXzF,EAAE;AAAA,IAYT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,6CAAC,aAAQ,eAAW,cAAG,sDAAsD,SAAS,GACpF;AAAA,iDAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,4CAAC,OAAE,MAAY,WAAU,iEAAgE,oCAEzF;AAAA,OAEJ;AAAA,IACA,4CAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,6CAAC,QAAmB,WAAU,6BAC5B;AAAA,kDAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO,GACtE;AAAA,MACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
@@ -2,6 +2,9 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  interface LeaderboardEntryLike {
5
+ /** Kept for API compatibility with the backend's ordered response — not
6
+ * rendered. This is a scoreboard, not a ranking: no "#1/#2/#3", no podium
7
+ * colors. Order in the array is still the sort order the caller gets. */
5
8
  rank: number;
6
9
  address: string;
7
10
  publicId?: string | null;
@@ -18,17 +21,18 @@ interface LeaderboardTableProps {
18
21
  renderAddress?: (address: string) => ReactNode;
19
22
  className?: string;
20
23
  }
21
- /** Full leaderboard rows: rank, address, level chip, XP. */
24
+ /** Scoreboard rows: address, level chip, points. No position number or
25
+ * podium coloring — this celebrates participation, not competition. */
22
26
  declare function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps): react_jsx_runtime.JSX.Element;
23
27
  interface LeaderboardWidgetProps {
24
28
  entries: LeaderboardEntryLike[];
25
29
  title?: string;
26
- /** Link to the full leaderboard ("/rewards"). */
30
+ /** Link to the full scoreboard ("/rewards"). */
27
31
  href?: string;
28
32
  renderAddress?: (address: string) => ReactNode;
29
33
  className?: string;
30
34
  }
31
- /** Compact top-N card for homepage/discover rails. */
35
+ /** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */
32
36
  declare function LeaderboardWidget({ entries, title, href, renderAddress, className }: LeaderboardWidgetProps): react_jsx_runtime.JSX.Element | null;
33
37
 
34
38
  export { type LeaderboardEntryLike, LeaderboardTable, type LeaderboardTableProps, LeaderboardWidget, type LeaderboardWidgetProps };
@@ -2,6 +2,9 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  interface LeaderboardEntryLike {
5
+ /** Kept for API compatibility with the backend's ordered response — not
6
+ * rendered. This is a scoreboard, not a ranking: no "#1/#2/#3", no podium
7
+ * colors. Order in the array is still the sort order the caller gets. */
5
8
  rank: number;
6
9
  address: string;
7
10
  publicId?: string | null;
@@ -18,17 +21,18 @@ interface LeaderboardTableProps {
18
21
  renderAddress?: (address: string) => ReactNode;
19
22
  className?: string;
20
23
  }
21
- /** Full leaderboard rows: rank, address, level chip, XP. */
24
+ /** Scoreboard rows: address, level chip, points. No position number or
25
+ * podium coloring — this celebrates participation, not competition. */
22
26
  declare function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps): react_jsx_runtime.JSX.Element;
23
27
  interface LeaderboardWidgetProps {
24
28
  entries: LeaderboardEntryLike[];
25
29
  title?: string;
26
- /** Link to the full leaderboard ("/rewards"). */
30
+ /** Link to the full scoreboard ("/rewards"). */
27
31
  href?: string;
28
32
  renderAddress?: (address: string) => ReactNode;
29
33
  className?: string;
30
34
  }
31
- /** Compact top-N card for homepage/discover rails. */
35
+ /** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */
32
36
  declare function LeaderboardWidget({ entries, title, href, renderAddress, className }: LeaderboardWidgetProps): react_jsx_runtime.JSX.Element | null;
33
37
 
34
38
  export { type LeaderboardEntryLike, LeaderboardTable, type LeaderboardTableProps, LeaderboardWidget, type LeaderboardWidgetProps };
@@ -2,15 +2,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../../utils/cn.js";
3
3
  import { shortenAddress } from "../../utils/address.js";
4
4
  import { LevelBadge } from "./level-badge.js";
5
- function rankAccent(rank) {
6
- if (rank === 1) return "#f59e0b";
7
- if (rank === 2) return "#94a3b8";
8
- if (rank === 3) return "#b45309";
9
- return null;
10
- }
11
5
  function LeaderboardTable({ entries, highlightAddress, renderAddress, className }) {
12
6
  return /* @__PURE__ */ jsx("div", { className: cn("overflow-hidden rounded-xl border border-border", className), children: entries.map((e) => {
13
- const accent = rankAccent(e.rank);
14
7
  const isViewer = highlightAddress != null && e.address === highlightAddress;
15
8
  return /* @__PURE__ */ jsxs(
16
9
  "div",
@@ -20,14 +13,6 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
20
13
  isViewer && "bg-primary/10"
21
14
  ),
22
15
  children: [
23
- /* @__PURE__ */ jsx(
24
- "span",
25
- {
26
- className: "w-8 shrink-0 text-center text-sm font-black tabular-nums",
27
- style: accent ? { color: accent } : void 0,
28
- children: e.rank
29
- }
30
- ),
31
16
  /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: [
32
17
  renderAddress ? renderAddress(e.address) : shortenAddress(e.address),
33
18
  isViewer && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs text-muted-foreground", children: "(you)" })
@@ -35,7 +20,7 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
35
20
  /* @__PURE__ */ jsx(LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm", className: "hidden sm:inline-flex" }),
36
21
  /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-sm font-semibold tabular-nums", children: [
37
22
  e.totalXp.toLocaleString(),
38
- " XP"
23
+ " pts"
39
24
  ] })
40
25
  ]
41
26
  },
@@ -43,22 +28,14 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, className
43
28
  );
44
29
  }) });
45
30
  }
46
- function LeaderboardWidget({ entries, title = "Top Creators", href, renderAddress, className }) {
31
+ function LeaderboardWidget({ entries, title = "Community Rewards", href, renderAddress, className }) {
47
32
  if (entries.length === 0) return null;
48
33
  return /* @__PURE__ */ jsxs("section", { className: cn("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
49
34
  /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between", children: [
50
35
  /* @__PURE__ */ jsx("h2", { className: "text-base font-black", children: title }),
51
- href && /* @__PURE__ */ jsx("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View leaderboard \u2192" })
36
+ href && /* @__PURE__ */ jsx("a", { href, className: "text-xs font-semibold text-muted-foreground active:opacity-70", children: "View scoreboard \u2192" })
52
37
  ] }),
53
38
  /* @__PURE__ */ jsx("ol", { className: "space-y-2.5", children: entries.map((e) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2.5", children: [
54
- /* @__PURE__ */ jsx(
55
- "span",
56
- {
57
- className: "w-5 shrink-0 text-center text-sm font-black tabular-nums",
58
- style: rankAccent(e.rank) ? { color: rankAccent(e.rank) } : void 0,
59
- children: e.rank
60
- }
61
- ),
62
39
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: renderAddress ? renderAddress(e.address) : shortenAddress(e.address) }),
63
40
  /* @__PURE__ */ jsx(LevelBadge, { level: e.currentLevel, name: e.currentLevelName, badgeColor: e.badgeColor, size: "sm" })
64
41
  ] }, e.address)) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\nfunction rankAccent(rank: number): string | null {\n if (rank === 1) return \"#f59e0b\";\n if (rank === 2) return \"#94a3b8\";\n if (rank === 3) return \"#b45309\";\n return null;\n}\n\n/** Full leaderboard rows: rank, address, level chip, XP. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const accent = rankAccent(e.rank);\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span\n className=\"w-8 shrink-0 text-center text-sm font-black tabular-nums\"\n style={accent ? { color: accent } : undefined}\n >\n {e.rank}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">{e.totalXp.toLocaleString()} XP</span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full leaderboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact top-N card for homepage/discover rails. */\nexport function LeaderboardWidget({ entries, title = \"Top Creators\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View leaderboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span\n className=\"w-5 shrink-0 text-center text-sm font-black tabular-nums\"\n style={rankAccent(e.rank) ? { color: rankAccent(e.rank)! } : undefined}\n >\n {e.rank}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":"AA8CY,cAMA,YANA;AA7CZ,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAqB3B,SAAS,WAAW,MAA6B;AAC/C,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,SAAS,EAAG,QAAO;AACvB,SAAO;AACT;AAGO,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,oBAAC,SAAI,WAAW,GAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,SAAS,WAAW,EAAE,IAAI;AAChC,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,SAAS,EAAE,OAAO,OAAO,IAAI;AAAA,cAEnC,YAAE;AAAA;AAAA,UACL;AAAA,UACA,qBAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,YACnE,YAAY,oBAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,qBAAC,UAAK,WAAU,+CAA+C;AAAA,cAAE,QAAQ,eAAe;AAAA,YAAE;AAAA,aAAG;AAAA;AAAA;AAAA,MAjBxF,EAAE;AAAA,IAkBT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,gBAAgB,MAAM,eAAe,UAAU,GAA2B;AAC7H,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,qBAAC,aAAQ,WAAW,GAAG,sDAAsD,SAAS,GACpF;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,oBAAC,OAAE,MAAY,WAAU,iEAAgE,qCAEzF;AAAA,OAEJ;AAAA,IACA,oBAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAmB,WAAU,6BAC5B;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,WAAW,EAAE,IAAI,IAAI,EAAE,OAAO,WAAW,EAAE,IAAI,EAAG,IAAI;AAAA,UAE5D,YAAE;AAAA;AAAA,MACL;AAAA,MACA,oBAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,GACtE;AAAA,MACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAV1F,EAAE,OAWX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n /** Kept for API compatibility with the backend's ordered response — not\n * rendered. This is a scoreboard, not a ranking: no \"#1/#2/#3\", no podium\n * colors. Order in the array is still the sort order the caller gets. */\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n /** The viewer's address — its row gets highlighted. */\n highlightAddress?: string | null;\n /** Render the address cell (e.g. a profile link). Defaults to a shortened address. */\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Scoreboard rows: address, level chip, points. No position number or\n * podium coloring this celebrates participation, not competition. */\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, className }: LeaderboardTableProps) {\n return (\n <div className={cn(\"overflow-hidden rounded-xl border border-border\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-3 border-b border-border/60 bg-card px-3 py-2.5 last:border-b-0 sm:px-4\",\n isViewer && \"bg-primary/10\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs text-muted-foreground\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-semibold tabular-nums\">{e.totalXp.toLocaleString()} pts</span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n /** Link to the full scoreboard (\"/rewards\"). */\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\n/** Compact card for homepage/discover rails — same no-ranking scoreboard rows. */\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-base font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-semibold text-muted-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":"AA0CY,SAEe,KAFf;AAzCZ,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AA0BpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,UAAU,GAA0B;AAC/G,SACE,oBAAC,SAAI,WAAW,GAAG,mDAAmD,SAAS,GAC5E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,QACd;AAAA,QAEA;AAAA,+BAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,YACnE,YAAY,oBAAC,UAAK,WAAU,wCAAuC,mBAAK;AAAA,aAC3E;AAAA,UACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,qBAAC,UAAK,WAAU,+CAA+C;AAAA,cAAE,QAAQ,eAAe;AAAA,YAAE;AAAA,aAAI;AAAA;AAAA;AAAA,MAXzF,EAAE;AAAA,IAYT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAYO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,qBAAC,aAAQ,WAAW,GAAG,sDAAsD,SAAS,GACpF;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,QAAG,WAAU,wBAAwB,iBAAM;AAAA,MAC3C,QACC,oBAAC,OAAE,MAAY,WAAU,iEAAgE,oCAEzF;AAAA,OAEJ;AAAA,IACA,oBAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAmB,WAAU,6BAC5B;AAAA,0BAAC,UAAK,WAAU,+CACb,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,GACtE;AAAA,MACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.39.0",
3
+ "version": "0.41.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",