@medialane/ui 0.102.0 → 0.104.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.
- package/dist/components/creator-analytics.cjs +170 -0
- package/dist/components/creator-analytics.cjs.map +1 -0
- package/dist/components/creator-analytics.d.cts +10 -0
- package/dist/components/creator-analytics.d.ts +10 -0
- package/dist/components/creator-analytics.js +153 -0
- package/dist/components/creator-analytics.js.map +1 -0
- package/dist/components/dialog.cjs +128 -0
- package/dist/components/dialog.cjs.map +1 -0
- package/dist/components/dialog.d.cts +25 -0
- package/dist/components/dialog.d.ts +25 -0
- package/dist/components/dialog.js +85 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/drop-countdown.cjs +66 -0
- package/dist/components/drop-countdown.cjs.map +1 -0
- package/dist/components/drop-countdown.d.cts +8 -0
- package/dist/components/drop-countdown.d.ts +8 -0
- package/dist/components/drop-countdown.js +42 -0
- package/dist/components/drop-countdown.js.map +1 -0
- package/dist/components/owner-setup-panel.cjs +91 -0
- package/dist/components/owner-setup-panel.cjs.map +1 -0
- package/dist/components/owner-setup-panel.d.cts +10 -0
- package/dist/components/owner-setup-panel.d.ts +10 -0
- package/dist/components/owner-setup-panel.js +57 -0
- package/dist/components/owner-setup-panel.js.map +1 -0
- package/dist/components/portfolio-header.cjs +1 -1
- package/dist/components/portfolio-header.cjs.map +1 -1
- package/dist/components/portfolio-header.d.cts +4 -1
- package/dist/components/portfolio-header.d.ts +4 -1
- package/dist/components/portfolio-header.js +1 -1
- package/dist/components/portfolio-header.js.map +1 -1
- package/dist/index.cjs +49 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +45 -1
- package/dist/index.js.map +1 -1
- package/dist/medialane.css +16 -0
- package/dist/utils/use-creators.cjs +53 -0
- package/dist/utils/use-creators.cjs.map +1 -0
- package/dist/utils/use-creators.d.cts +11 -0
- package/dist/utils/use-creators.d.ts +11 -0
- package/dist/utils/use-creators.js +19 -0
- package/dist/utils/use-creators.js.map +1 -0
- package/dist/utils/use-medialane-client.cjs +33 -0
- package/dist/utils/use-medialane-client.cjs.map +1 -0
- package/dist/utils/use-medialane-client.d.cts +5 -0
- package/dist/utils/use-medialane-client.d.ts +5 -0
- package/dist/utils/use-medialane-client.js +9 -0
- package/dist/utils/use-medialane-client.js.map +1 -0
- package/dist/utils/use-rewards.cjs +100 -0
- package/dist/utils/use-rewards.cjs.map +1 -0
- package/dist/utils/use-rewards.d.cts +61 -0
- package/dist/utils/use-rewards.d.ts +61 -0
- package/dist/utils/use-rewards.js +62 -0
- package/dist/utils/use-rewards.js.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
function useCreators(getClient, search, page = 1, limit = 20) {
|
|
4
|
+
const { data, error, isLoading } = useSWR(
|
|
5
|
+
`creators-${search ?? ""}-${page}-${limit}`,
|
|
6
|
+
() => getClient().api.getCreators({ search, page, limit }),
|
|
7
|
+
{ revalidateOnFocus: false }
|
|
8
|
+
);
|
|
9
|
+
return {
|
|
10
|
+
creators: data?.creators ?? [],
|
|
11
|
+
total: data?.total ?? 0,
|
|
12
|
+
isLoading,
|
|
13
|
+
error
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
useCreators
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=use-creators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-creators.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\n\nexport function useCreators(\n getClient: () => MedialaneClient,\n search?: string,\n page = 1,\n limit = 20\n) {\n const { data, error, isLoading } = useSWR(\n `creators-${search ?? \"\"}-${page}-${limit}`,\n () => getClient().api.getCreators({ search, page, limit }),\n { revalidateOnFocus: false }\n );\n return {\n creators: data?.creators ?? [],\n total: data?.total ?? 0,\n isLoading,\n error,\n };\n}\n"],"mappings":";AAEA,OAAO,YAAY;AAGZ,SAAS,YACd,WACA,QACA,OAAO,GACP,QAAQ,IACR;AACA,QAAM,EAAE,MAAM,OAAO,UAAU,IAAI;AAAA,IACjC,YAAY,UAAU,EAAE,IAAI,IAAI,IAAI,KAAK;AAAA,IACzC,MAAM,UAAU,EAAE,IAAI,YAAY,EAAE,QAAQ,MAAM,MAAM,CAAC;AAAA,IACzD,EAAE,mBAAmB,MAAM;AAAA,EAC7B;AACA,SAAO;AAAA,IACL,UAAU,MAAM,YAAY,CAAC;AAAA,IAC7B,OAAO,MAAM,SAAS;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var use_medialane_client_exports = {};
|
|
21
|
+
__export(use_medialane_client_exports, {
|
|
22
|
+
useMedialaneClient: () => useMedialaneClient
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(use_medialane_client_exports);
|
|
25
|
+
var import_react = require("react");
|
|
26
|
+
function useMedialaneClient(getClient) {
|
|
27
|
+
return (0, import_react.useMemo)(() => getClient(), [getClient]);
|
|
28
|
+
}
|
|
29
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
30
|
+
0 && (module.exports = {
|
|
31
|
+
useMedialaneClient
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=use-medialane-client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-medialane-client.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\n\nexport function useMedialaneClient(getClient: () => MedialaneClient): MedialaneClient {\n return useMemo(() => getClient(), [getClient]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAwB;AAGjB,SAAS,mBAAmB,WAAmD;AACpF,aAAO,sBAAQ,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC;AAC/C;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-medialane-client.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\n\nexport function useMedialaneClient(getClient: () => MedialaneClient): MedialaneClient {\n return useMemo(() => getClient(), [getClient]);\n}\n"],"mappings":";AAEA,SAAS,eAAe;AAGjB,SAAS,mBAAmB,WAAmD;AACpF,SAAO,QAAQ,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC;AAC/C;","names":[]}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var use_rewards_exports = {};
|
|
31
|
+
__export(use_rewards_exports, {
|
|
32
|
+
useLeaderboard: () => useLeaderboard,
|
|
33
|
+
useRewards: () => useRewards,
|
|
34
|
+
useRewardsBatch: () => useRewardsBatch,
|
|
35
|
+
useRewardsConfig: () => useRewardsConfig,
|
|
36
|
+
useRewardsEvents: () => useRewardsEvents
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(use_rewards_exports);
|
|
39
|
+
var import_swr = __toESM(require("swr"), 1);
|
|
40
|
+
function useRewards(getClient, address) {
|
|
41
|
+
return (0, import_swr.default)(
|
|
42
|
+
address ? `rewards:${address}` : null,
|
|
43
|
+
() => getClient().api.getRewards(address),
|
|
44
|
+
{ revalidateOnFocus: false, dedupingInterval: 6e4 }
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function useLeaderboard(getClient, page = 1, limit = 50) {
|
|
48
|
+
return (0, import_swr.default)(
|
|
49
|
+
`rewards-leaderboard:${page}:${limit}`,
|
|
50
|
+
async () => {
|
|
51
|
+
const res = await getClient().api.getRewardsLeaderboard(page, limit);
|
|
52
|
+
return {
|
|
53
|
+
data: res.data,
|
|
54
|
+
meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length }
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
{ revalidateOnFocus: false, dedupingInterval: 12e4 }
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function useRewardsEvents(getClient, address, page = 1, limit = 20) {
|
|
61
|
+
return (0, import_swr.default)(
|
|
62
|
+
address ? `rewards-events:${address}:${page}:${limit}` : null,
|
|
63
|
+
async () => {
|
|
64
|
+
const res = await getClient().api.getRewardsEvents(address, page, limit);
|
|
65
|
+
return {
|
|
66
|
+
data: res.data,
|
|
67
|
+
meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length }
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
{ revalidateOnFocus: false, dedupingInterval: 6e4 }
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
function useRewardsConfig(getClient) {
|
|
74
|
+
return (0, import_swr.default)(
|
|
75
|
+
"rewards-config",
|
|
76
|
+
() => getClient().api.getRewardsConfig(),
|
|
77
|
+
{ revalidateOnFocus: false, dedupingInterval: 3e5 }
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
function useRewardsBatch(getClient, addresses) {
|
|
81
|
+
const unique = [...new Set(addresses)].slice(0, 50);
|
|
82
|
+
const key = unique.length ? `rewards-batch:${[...unique].sort().join(",")}` : null;
|
|
83
|
+
return (0, import_swr.default)(
|
|
84
|
+
key,
|
|
85
|
+
async () => {
|
|
86
|
+
const entries = await getClient().api.getRewardsBatch(unique);
|
|
87
|
+
return new Map(entries.map((e) => [e.address, e]));
|
|
88
|
+
},
|
|
89
|
+
{ revalidateOnFocus: false, dedupingInterval: 12e4 }
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
93
|
+
0 && (module.exports = {
|
|
94
|
+
useLeaderboard,
|
|
95
|
+
useRewards,
|
|
96
|
+
useRewardsBatch,
|
|
97
|
+
useRewardsConfig,
|
|
98
|
+
useRewardsEvents
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=use-rewards.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-rewards.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport type {\n ApiUserRewards,\n ApiRewardsLeaderboardEntry,\n ApiRewardsConfig,\n ApiRewardsBatchEntry,\n ApiPointEvent,\n} from \"@medialane/sdk\";\n\n// Legacy local names — kept so existing consumers compile unchanged.\nexport type UserRewards = ApiUserRewards;\nexport type LeaderboardEntry = ApiRewardsLeaderboardEntry;\nexport type BadgeSummary = ApiUserRewards[\"badges\"][number];\nexport type LevelSummary = NonNullable<ApiUserRewards[\"nextLevel\"]>;\n\n// ── Hooks ─────────────────────────────────────────────────────────────────────\n\nexport function useRewards(getClient: () => MedialaneClient, address: string | null | undefined) {\n return useSWR<ApiUserRewards>(\n address ? `rewards:${address}` : null,\n () => getClient().api.getRewards(address!),\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n}\n\nexport function useLeaderboard(getClient: () => MedialaneClient, page = 1, limit = 50) {\n return useSWR<{ data: ApiRewardsLeaderboardEntry[]; meta: { page: number; limit: number; total: number } }>(\n `rewards-leaderboard:${page}:${limit}`,\n async () => {\n const res = await getClient().api.getRewardsLeaderboard(page, limit);\n return {\n data: res.data,\n meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length },\n };\n },\n { revalidateOnFocus: false, dedupingInterval: 120_000 }\n );\n}\n\nexport function useRewardsEvents(\n getClient: () => MedialaneClient,\n address: string | null | undefined,\n page = 1,\n limit = 20\n) {\n return useSWR<{ data: ApiPointEvent[]; meta: { page: number; limit: number; total: number } }>(\n address ? `rewards-events:${address}:${page}:${limit}` : null,\n async () => {\n const res = await getClient().api.getRewardsEvents(address!, page, limit);\n return {\n data: res.data,\n meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length },\n };\n },\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n}\n\n/** Level ladder + action XP values + badge catalog. Changes rarely. */\nexport function useRewardsConfig(getClient: () => MedialaneClient) {\n return useSWR<ApiRewardsConfig>(\n \"rewards-config\",\n () => getClient().api.getRewardsConfig(),\n { revalidateOnFocus: false, dedupingInterval: 300_000 }\n );\n}\n\n/** Minimal level info for a page of addresses — ONE request per page.\n * Returns a Map keyed by normalized address. Failures resolve to undefined\n * data; list surfaces render nothing rather than an error. */\nexport function useRewardsBatch(getClient: () => MedialaneClient, addresses: string[]) {\n const unique = [...new Set(addresses)].slice(0, 50);\n const key = unique.length ? `rewards-batch:${[...unique].sort().join(\",\")}` : null;\n return useSWR<Map<string, ApiRewardsBatchEntry>>(\n key,\n async () => {\n const entries = await getClient().api.getRewardsBatch(unique);\n return new Map(entries.map((e) => [e.address, e]));\n },\n { revalidateOnFocus: false, dedupingInterval: 120_000 }\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAmB;AAkBZ,SAAS,WAAW,WAAkC,SAAoC;AAC/F,aAAO,WAAAA;AAAA,IACL,UAAU,WAAW,OAAO,KAAK;AAAA,IACjC,MAAM,UAAU,EAAE,IAAI,WAAW,OAAQ;AAAA,IACzC,EAAE,mBAAmB,OAAO,kBAAkB,IAAO;AAAA,EACvD;AACF;AAEO,SAAS,eAAe,WAAkC,OAAO,GAAG,QAAQ,IAAI;AACrF,aAAO,WAAAA;AAAA,IACL,uBAAuB,IAAI,IAAI,KAAK;AAAA,IACpC,YAAY;AACV,YAAM,MAAM,MAAM,UAAU,EAAE,IAAI,sBAAsB,MAAM,KAAK;AACnE,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,EAAE,MAAM,IAAI,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,SAAS,OAAO,OAAO,IAAI,MAAM,SAAS,IAAI,KAAK,OAAO;AAAA,MACnH;AAAA,IACF;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,KAAQ;AAAA,EACxD;AACF;AAEO,SAAS,iBACd,WACA,SACA,OAAO,GACP,QAAQ,IACR;AACA,aAAO,WAAAA;AAAA,IACL,UAAU,kBAAkB,OAAO,IAAI,IAAI,IAAI,KAAK,KAAK;AAAA,IACzD,YAAY;AACV,YAAM,MAAM,MAAM,UAAU,EAAE,IAAI,iBAAiB,SAAU,MAAM,KAAK;AACxE,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,EAAE,MAAM,IAAI,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,SAAS,OAAO,OAAO,IAAI,MAAM,SAAS,IAAI,KAAK,OAAO;AAAA,MACnH;AAAA,IACF;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,IAAO;AAAA,EACvD;AACF;AAGO,SAAS,iBAAiB,WAAkC;AACjE,aAAO,WAAAA;AAAA,IACL;AAAA,IACA,MAAM,UAAU,EAAE,IAAI,iBAAiB;AAAA,IACvC,EAAE,mBAAmB,OAAO,kBAAkB,IAAQ;AAAA,EACxD;AACF;AAKO,SAAS,gBAAgB,WAAkC,WAAqB;AACrF,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE,MAAM,GAAG,EAAE;AAClD,QAAM,MAAM,OAAO,SAAS,iBAAiB,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK;AAC9E,aAAO,WAAAA;AAAA,IACL;AAAA,IACA,YAAY;AACV,YAAM,UAAU,MAAM,UAAU,EAAE,IAAI,gBAAgB,MAAM;AAC5D,aAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,IACnD;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,KAAQ;AAAA,EACxD;AACF;","names":["useSWR"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as swr from 'swr';
|
|
2
|
+
import { MedialaneClient } from '@medialane/sdk/starknet';
|
|
3
|
+
import { ApiUserRewards, ApiRewardsLeaderboardEntry, ApiRewardsBatchEntry, ApiRewardsConfig, ApiPointEvent } from '@medialane/sdk';
|
|
4
|
+
|
|
5
|
+
type UserRewards = ApiUserRewards;
|
|
6
|
+
type LeaderboardEntry = ApiRewardsLeaderboardEntry;
|
|
7
|
+
type BadgeSummary = ApiUserRewards["badges"][number];
|
|
8
|
+
type LevelSummary = NonNullable<ApiUserRewards["nextLevel"]>;
|
|
9
|
+
declare function useRewards(getClient: () => MedialaneClient, address: string | null | undefined): swr.SWRResponse<ApiUserRewards, any, swr.SWRConfiguration<ApiUserRewards, any, swr.BareFetcher<ApiUserRewards>> | undefined>;
|
|
10
|
+
declare function useLeaderboard(getClient: () => MedialaneClient, page?: number, limit?: number): swr.SWRResponse<{
|
|
11
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
12
|
+
meta: {
|
|
13
|
+
page: number;
|
|
14
|
+
limit: number;
|
|
15
|
+
total: number;
|
|
16
|
+
};
|
|
17
|
+
}, any, swr.SWRConfiguration<{
|
|
18
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
19
|
+
meta: {
|
|
20
|
+
page: number;
|
|
21
|
+
limit: number;
|
|
22
|
+
total: number;
|
|
23
|
+
};
|
|
24
|
+
}, any, swr.BareFetcher<{
|
|
25
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
26
|
+
meta: {
|
|
27
|
+
page: number;
|
|
28
|
+
limit: number;
|
|
29
|
+
total: number;
|
|
30
|
+
};
|
|
31
|
+
}>> | undefined>;
|
|
32
|
+
declare function useRewardsEvents(getClient: () => MedialaneClient, address: string | null | undefined, page?: number, limit?: number): swr.SWRResponse<{
|
|
33
|
+
data: ApiPointEvent[];
|
|
34
|
+
meta: {
|
|
35
|
+
page: number;
|
|
36
|
+
limit: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
|
39
|
+
}, any, swr.SWRConfiguration<{
|
|
40
|
+
data: ApiPointEvent[];
|
|
41
|
+
meta: {
|
|
42
|
+
page: number;
|
|
43
|
+
limit: number;
|
|
44
|
+
total: number;
|
|
45
|
+
};
|
|
46
|
+
}, any, swr.BareFetcher<{
|
|
47
|
+
data: ApiPointEvent[];
|
|
48
|
+
meta: {
|
|
49
|
+
page: number;
|
|
50
|
+
limit: number;
|
|
51
|
+
total: number;
|
|
52
|
+
};
|
|
53
|
+
}>> | undefined>;
|
|
54
|
+
/** Level ladder + action XP values + badge catalog. Changes rarely. */
|
|
55
|
+
declare function useRewardsConfig(getClient: () => MedialaneClient): swr.SWRResponse<ApiRewardsConfig, any, swr.SWRConfiguration<ApiRewardsConfig, any, swr.BareFetcher<ApiRewardsConfig>> | undefined>;
|
|
56
|
+
/** Minimal level info for a page of addresses — ONE request per page.
|
|
57
|
+
* Returns a Map keyed by normalized address. Failures resolve to undefined
|
|
58
|
+
* data; list surfaces render nothing rather than an error. */
|
|
59
|
+
declare function useRewardsBatch(getClient: () => MedialaneClient, addresses: string[]): swr.SWRResponse<Map<string, ApiRewardsBatchEntry>, any, swr.SWRConfiguration<Map<string, ApiRewardsBatchEntry>, any, swr.BareFetcher<Map<string, ApiRewardsBatchEntry>>> | undefined>;
|
|
60
|
+
|
|
61
|
+
export { type BadgeSummary, type LeaderboardEntry, type LevelSummary, type UserRewards, useLeaderboard, useRewards, useRewardsBatch, useRewardsConfig, useRewardsEvents };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as swr from 'swr';
|
|
2
|
+
import { MedialaneClient } from '@medialane/sdk/starknet';
|
|
3
|
+
import { ApiUserRewards, ApiRewardsLeaderboardEntry, ApiRewardsBatchEntry, ApiRewardsConfig, ApiPointEvent } from '@medialane/sdk';
|
|
4
|
+
|
|
5
|
+
type UserRewards = ApiUserRewards;
|
|
6
|
+
type LeaderboardEntry = ApiRewardsLeaderboardEntry;
|
|
7
|
+
type BadgeSummary = ApiUserRewards["badges"][number];
|
|
8
|
+
type LevelSummary = NonNullable<ApiUserRewards["nextLevel"]>;
|
|
9
|
+
declare function useRewards(getClient: () => MedialaneClient, address: string | null | undefined): swr.SWRResponse<ApiUserRewards, any, swr.SWRConfiguration<ApiUserRewards, any, swr.BareFetcher<ApiUserRewards>> | undefined>;
|
|
10
|
+
declare function useLeaderboard(getClient: () => MedialaneClient, page?: number, limit?: number): swr.SWRResponse<{
|
|
11
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
12
|
+
meta: {
|
|
13
|
+
page: number;
|
|
14
|
+
limit: number;
|
|
15
|
+
total: number;
|
|
16
|
+
};
|
|
17
|
+
}, any, swr.SWRConfiguration<{
|
|
18
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
19
|
+
meta: {
|
|
20
|
+
page: number;
|
|
21
|
+
limit: number;
|
|
22
|
+
total: number;
|
|
23
|
+
};
|
|
24
|
+
}, any, swr.BareFetcher<{
|
|
25
|
+
data: ApiRewardsLeaderboardEntry[];
|
|
26
|
+
meta: {
|
|
27
|
+
page: number;
|
|
28
|
+
limit: number;
|
|
29
|
+
total: number;
|
|
30
|
+
};
|
|
31
|
+
}>> | undefined>;
|
|
32
|
+
declare function useRewardsEvents(getClient: () => MedialaneClient, address: string | null | undefined, page?: number, limit?: number): swr.SWRResponse<{
|
|
33
|
+
data: ApiPointEvent[];
|
|
34
|
+
meta: {
|
|
35
|
+
page: number;
|
|
36
|
+
limit: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
|
39
|
+
}, any, swr.SWRConfiguration<{
|
|
40
|
+
data: ApiPointEvent[];
|
|
41
|
+
meta: {
|
|
42
|
+
page: number;
|
|
43
|
+
limit: number;
|
|
44
|
+
total: number;
|
|
45
|
+
};
|
|
46
|
+
}, any, swr.BareFetcher<{
|
|
47
|
+
data: ApiPointEvent[];
|
|
48
|
+
meta: {
|
|
49
|
+
page: number;
|
|
50
|
+
limit: number;
|
|
51
|
+
total: number;
|
|
52
|
+
};
|
|
53
|
+
}>> | undefined>;
|
|
54
|
+
/** Level ladder + action XP values + badge catalog. Changes rarely. */
|
|
55
|
+
declare function useRewardsConfig(getClient: () => MedialaneClient): swr.SWRResponse<ApiRewardsConfig, any, swr.SWRConfiguration<ApiRewardsConfig, any, swr.BareFetcher<ApiRewardsConfig>> | undefined>;
|
|
56
|
+
/** Minimal level info for a page of addresses — ONE request per page.
|
|
57
|
+
* Returns a Map keyed by normalized address. Failures resolve to undefined
|
|
58
|
+
* data; list surfaces render nothing rather than an error. */
|
|
59
|
+
declare function useRewardsBatch(getClient: () => MedialaneClient, addresses: string[]): swr.SWRResponse<Map<string, ApiRewardsBatchEntry>, any, swr.SWRConfiguration<Map<string, ApiRewardsBatchEntry>, any, swr.BareFetcher<Map<string, ApiRewardsBatchEntry>>> | undefined>;
|
|
60
|
+
|
|
61
|
+
export { type BadgeSummary, type LeaderboardEntry, type LevelSummary, type UserRewards, useLeaderboard, useRewards, useRewardsBatch, useRewardsConfig, useRewardsEvents };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
function useRewards(getClient, address) {
|
|
4
|
+
return useSWR(
|
|
5
|
+
address ? `rewards:${address}` : null,
|
|
6
|
+
() => getClient().api.getRewards(address),
|
|
7
|
+
{ revalidateOnFocus: false, dedupingInterval: 6e4 }
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
function useLeaderboard(getClient, page = 1, limit = 50) {
|
|
11
|
+
return useSWR(
|
|
12
|
+
`rewards-leaderboard:${page}:${limit}`,
|
|
13
|
+
async () => {
|
|
14
|
+
const res = await getClient().api.getRewardsLeaderboard(page, limit);
|
|
15
|
+
return {
|
|
16
|
+
data: res.data,
|
|
17
|
+
meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length }
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
{ revalidateOnFocus: false, dedupingInterval: 12e4 }
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
function useRewardsEvents(getClient, address, page = 1, limit = 20) {
|
|
24
|
+
return useSWR(
|
|
25
|
+
address ? `rewards-events:${address}:${page}:${limit}` : null,
|
|
26
|
+
async () => {
|
|
27
|
+
const res = await getClient().api.getRewardsEvents(address, page, limit);
|
|
28
|
+
return {
|
|
29
|
+
data: res.data,
|
|
30
|
+
meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length }
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
{ revalidateOnFocus: false, dedupingInterval: 6e4 }
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function useRewardsConfig(getClient) {
|
|
37
|
+
return useSWR(
|
|
38
|
+
"rewards-config",
|
|
39
|
+
() => getClient().api.getRewardsConfig(),
|
|
40
|
+
{ revalidateOnFocus: false, dedupingInterval: 3e5 }
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
function useRewardsBatch(getClient, addresses) {
|
|
44
|
+
const unique = [...new Set(addresses)].slice(0, 50);
|
|
45
|
+
const key = unique.length ? `rewards-batch:${[...unique].sort().join(",")}` : null;
|
|
46
|
+
return useSWR(
|
|
47
|
+
key,
|
|
48
|
+
async () => {
|
|
49
|
+
const entries = await getClient().api.getRewardsBatch(unique);
|
|
50
|
+
return new Map(entries.map((e) => [e.address, e]));
|
|
51
|
+
},
|
|
52
|
+
{ revalidateOnFocus: false, dedupingInterval: 12e4 }
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
useLeaderboard,
|
|
57
|
+
useRewards,
|
|
58
|
+
useRewardsBatch,
|
|
59
|
+
useRewardsConfig,
|
|
60
|
+
useRewardsEvents
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=use-rewards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-rewards.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport type {\n ApiUserRewards,\n ApiRewardsLeaderboardEntry,\n ApiRewardsConfig,\n ApiRewardsBatchEntry,\n ApiPointEvent,\n} from \"@medialane/sdk\";\n\n// Legacy local names — kept so existing consumers compile unchanged.\nexport type UserRewards = ApiUserRewards;\nexport type LeaderboardEntry = ApiRewardsLeaderboardEntry;\nexport type BadgeSummary = ApiUserRewards[\"badges\"][number];\nexport type LevelSummary = NonNullable<ApiUserRewards[\"nextLevel\"]>;\n\n// ── Hooks ─────────────────────────────────────────────────────────────────────\n\nexport function useRewards(getClient: () => MedialaneClient, address: string | null | undefined) {\n return useSWR<ApiUserRewards>(\n address ? `rewards:${address}` : null,\n () => getClient().api.getRewards(address!),\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n}\n\nexport function useLeaderboard(getClient: () => MedialaneClient, page = 1, limit = 50) {\n return useSWR<{ data: ApiRewardsLeaderboardEntry[]; meta: { page: number; limit: number; total: number } }>(\n `rewards-leaderboard:${page}:${limit}`,\n async () => {\n const res = await getClient().api.getRewardsLeaderboard(page, limit);\n return {\n data: res.data,\n meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length },\n };\n },\n { revalidateOnFocus: false, dedupingInterval: 120_000 }\n );\n}\n\nexport function useRewardsEvents(\n getClient: () => MedialaneClient,\n address: string | null | undefined,\n page = 1,\n limit = 20\n) {\n return useSWR<{ data: ApiPointEvent[]; meta: { page: number; limit: number; total: number } }>(\n address ? `rewards-events:${address}:${page}:${limit}` : null,\n async () => {\n const res = await getClient().api.getRewardsEvents(address!, page, limit);\n return {\n data: res.data,\n meta: { page: res.meta?.page ?? page, limit: res.meta?.limit ?? limit, total: res.meta?.total ?? res.data.length },\n };\n },\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n}\n\n/** Level ladder + action XP values + badge catalog. Changes rarely. */\nexport function useRewardsConfig(getClient: () => MedialaneClient) {\n return useSWR<ApiRewardsConfig>(\n \"rewards-config\",\n () => getClient().api.getRewardsConfig(),\n { revalidateOnFocus: false, dedupingInterval: 300_000 }\n );\n}\n\n/** Minimal level info for a page of addresses — ONE request per page.\n * Returns a Map keyed by normalized address. Failures resolve to undefined\n * data; list surfaces render nothing rather than an error. */\nexport function useRewardsBatch(getClient: () => MedialaneClient, addresses: string[]) {\n const unique = [...new Set(addresses)].slice(0, 50);\n const key = unique.length ? `rewards-batch:${[...unique].sort().join(\",\")}` : null;\n return useSWR<Map<string, ApiRewardsBatchEntry>>(\n key,\n async () => {\n const entries = await getClient().api.getRewardsBatch(unique);\n return new Map(entries.map((e) => [e.address, e]));\n },\n { revalidateOnFocus: false, dedupingInterval: 120_000 }\n );\n}\n"],"mappings":";AAEA,OAAO,YAAY;AAkBZ,SAAS,WAAW,WAAkC,SAAoC;AAC/F,SAAO;AAAA,IACL,UAAU,WAAW,OAAO,KAAK;AAAA,IACjC,MAAM,UAAU,EAAE,IAAI,WAAW,OAAQ;AAAA,IACzC,EAAE,mBAAmB,OAAO,kBAAkB,IAAO;AAAA,EACvD;AACF;AAEO,SAAS,eAAe,WAAkC,OAAO,GAAG,QAAQ,IAAI;AACrF,SAAO;AAAA,IACL,uBAAuB,IAAI,IAAI,KAAK;AAAA,IACpC,YAAY;AACV,YAAM,MAAM,MAAM,UAAU,EAAE,IAAI,sBAAsB,MAAM,KAAK;AACnE,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,EAAE,MAAM,IAAI,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,SAAS,OAAO,OAAO,IAAI,MAAM,SAAS,IAAI,KAAK,OAAO;AAAA,MACnH;AAAA,IACF;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,KAAQ;AAAA,EACxD;AACF;AAEO,SAAS,iBACd,WACA,SACA,OAAO,GACP,QAAQ,IACR;AACA,SAAO;AAAA,IACL,UAAU,kBAAkB,OAAO,IAAI,IAAI,IAAI,KAAK,KAAK;AAAA,IACzD,YAAY;AACV,YAAM,MAAM,MAAM,UAAU,EAAE,IAAI,iBAAiB,SAAU,MAAM,KAAK;AACxE,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,EAAE,MAAM,IAAI,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,SAAS,OAAO,OAAO,IAAI,MAAM,SAAS,IAAI,KAAK,OAAO;AAAA,MACnH;AAAA,IACF;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,IAAO;AAAA,EACvD;AACF;AAGO,SAAS,iBAAiB,WAAkC;AACjE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,UAAU,EAAE,IAAI,iBAAiB;AAAA,IACvC,EAAE,mBAAmB,OAAO,kBAAkB,IAAQ;AAAA,EACxD;AACF;AAKO,SAAS,gBAAgB,WAAkC,WAAqB;AACrF,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE,MAAM,GAAG,EAAE;AAClD,QAAM,MAAM,OAAO,SAAS,iBAAiB,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK;AAC9E,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AACV,YAAM,UAAU,MAAM,UAAU,EAAE,IAAI,gBAAgB,MAAM;AAC5D,aAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,IACnD;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,KAAQ;AAAA,EACxD;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medialane/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.104.0",
|
|
4
4
|
"description": "Shared UI components for Medialane apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@medialane/sdk": ">=0.73.0",
|
|
53
53
|
"@radix-ui/react-checkbox": ">=1.1.0",
|
|
54
54
|
"@radix-ui/react-collapsible": ">=1.1.0",
|
|
55
|
+
"@radix-ui/react-dialog": ">=1.1.0",
|
|
55
56
|
"@radix-ui/react-dropdown-menu": ">=2.1.0",
|
|
56
57
|
"@radix-ui/react-label": ">=2.1.0",
|
|
57
58
|
"@radix-ui/react-popover": ">=1.1.0",
|
|
@@ -69,13 +70,16 @@
|
|
|
69
70
|
"react": ">=18.0.0",
|
|
70
71
|
"react-dom": ">=18.0.0",
|
|
71
72
|
"react-hook-form": ">=7.50.0",
|
|
73
|
+
"recharts": ">=2.0.0",
|
|
72
74
|
"sonner": ">=1.0.0",
|
|
75
|
+
"swr": ">=2.0.0",
|
|
73
76
|
"tailwind-merge": ">=2.0.0"
|
|
74
77
|
},
|
|
75
78
|
"devDependencies": {
|
|
76
79
|
"@medialane/sdk": "0.82.0",
|
|
77
80
|
"@radix-ui/react-checkbox": "^1.3.8",
|
|
78
81
|
"@radix-ui/react-collapsible": "^1.1.17",
|
|
82
|
+
"@radix-ui/react-dialog": "^1.1.20",
|
|
79
83
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
80
84
|
"@radix-ui/react-label": "^2.1.12",
|
|
81
85
|
"@radix-ui/react-popover": "^1.1.20",
|
|
@@ -98,7 +102,9 @@
|
|
|
98
102
|
"react": "^19.0.0",
|
|
99
103
|
"react-dom": "^19.0.0",
|
|
100
104
|
"react-hook-form": "^7.82.0",
|
|
105
|
+
"recharts": "^3.8.1",
|
|
101
106
|
"sonner": "^1.5.0",
|
|
107
|
+
"swr": "^2.4.1",
|
|
102
108
|
"tailwind-merge": "^2.0.0",
|
|
103
109
|
"tailwindcss": "^3.0.0",
|
|
104
110
|
"tsup": "^8.0.0",
|