@playbasis-ai/qwikcard-sdk 2.3.16 → 2.3.19
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/CHANGELOG.md +20 -0
- package/dist/QwikCardApp.d.ts.map +1 -1
- package/dist/QwikCardApp.js +29 -18
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +37 -2
- package/dist/web/widgetAssets.d.ts +2 -2
- package/dist/web/widgetAssets.d.ts.map +1 -1
- package/dist/web/widgetAssets.js +2 -2
- package/package.json +1 -1
- package/src/QwikCardApp.tsx +39 -26
- package/src/api/client.ts +53 -7
- package/src/web/widgetAssets.ts +2 -4
package/CHANGELOG.md
CHANGED
|
@@ -79,6 +79,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
79
79
|
|
|
80
80
|
- Improved empty-state guidance and skeletons in dashboard quest/badge/leaderboard panels.
|
|
81
81
|
|
|
82
|
+
## [2.3.17] - 2026-01-30
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
|
|
86
|
+
- Use quest catalog when player progress is empty so quests render immediately.
|
|
87
|
+
- Support array responses for player quests/badges.
|
|
88
|
+
|
|
89
|
+
## [2.3.18] - 2026-01-30
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- Accept top-level leaderboard entries in API responses.
|
|
94
|
+
|
|
95
|
+
## [2.3.19] - 2026-01-31
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
|
|
99
|
+
- Normalize leaderboard entries across `entries/items/leaderboard` response shapes.
|
|
100
|
+
- Restore badge detail modal header styling in the embedded widget.
|
|
101
|
+
|
|
82
102
|
## [2.3.11] - 2026-01-29
|
|
83
103
|
|
|
84
104
|
### Changed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QwikCardApp.d.ts","sourceRoot":"","sources":["../src/QwikCardApp.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"QwikCardApp.d.ts","sourceRoot":"","sources":["../src/QwikCardApp.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAqSD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAMlD"}
|
package/dist/QwikCardApp.js
CHANGED
|
@@ -31,10 +31,11 @@ function AppContent({ leaderboardId }) {
|
|
|
31
31
|
if (!playerId) {
|
|
32
32
|
throw new Error('Missing playerId for widget bootstrap');
|
|
33
33
|
}
|
|
34
|
-
const [player, balances,
|
|
34
|
+
const [player, balances, playerQuests, questCatalog, allBadges, playerBadges, rewards] = await Promise.all([
|
|
35
35
|
client.getPlayer(playerId),
|
|
36
36
|
client.getBalances(playerId),
|
|
37
37
|
client.getPlayerQuests(playerId),
|
|
38
|
+
client.getQuests(),
|
|
38
39
|
client.getBadges(),
|
|
39
40
|
client.getPlayerBadges(playerId),
|
|
40
41
|
client.getRewards().catch(() => []), // Gracefully handle if rewards endpoint doesn't exist
|
|
@@ -72,23 +73,33 @@ function AppContent({ leaderboardId }) {
|
|
|
72
73
|
earnedDelta: 0,
|
|
73
74
|
qwikCoins,
|
|
74
75
|
},
|
|
75
|
-
goals:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
goals: (() => {
|
|
77
|
+
const quests = playerQuests.length > 0 ? playerQuests : questCatalog;
|
|
78
|
+
const nowIso = new Date().toISOString().slice(0, 10);
|
|
79
|
+
return quests.map((q) => ({
|
|
80
|
+
goalId: q.id,
|
|
81
|
+
type: 'financial',
|
|
82
|
+
target: q.target ?? 1,
|
|
83
|
+
current: q.progress ?? 0,
|
|
84
|
+
progressPct: q.target && q.target > 0
|
|
85
|
+
? Math.round(((q.progress ?? 0) / q.target) * 100)
|
|
86
|
+
: 0,
|
|
87
|
+
startDate: nowIso,
|
|
88
|
+
endDate: q.expiresAt ?? new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
89
|
+
status: q.status === 'completed'
|
|
90
|
+
? 'completed'
|
|
91
|
+
: q.status === 'expired'
|
|
92
|
+
? 'at_risk'
|
|
93
|
+
: 'on_track',
|
|
94
|
+
rewards: {
|
|
95
|
+
xp: q.rewards?.find((r) => r.type === 'points')?.amount || 100,
|
|
96
|
+
badges: (q.rewards
|
|
97
|
+
?.filter((r) => r.type === 'badge')
|
|
98
|
+
.map((r) => r.badgeId)
|
|
99
|
+
.filter(Boolean) || []),
|
|
100
|
+
},
|
|
101
|
+
}));
|
|
102
|
+
})(),
|
|
92
103
|
badges: allBadges.map((b) => ({
|
|
93
104
|
id: b.id,
|
|
94
105
|
name: b.name,
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,gBAAgB,EAChB,MAAM,EACN,UAAU,EACV,YAAY,EACZ,KAAK,EACL,gBAAgB,EAChB,MAAM,EACN,eAAe,EAChB,MAAM,UAAU,CAAC;AAMlB,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,YAAY;IAShC;;;OAGG;IACH,OAAO,CAAC,UAAU;YAQJ,OAAO;IAsFf,YAAY,CAAC,KAAK,EAAE;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,OAAO,CAAC,MAAM,CAAC;IAKb,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ5C,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,GAC3E,OAAO,CAAC,MAAM,CAAC;IAeZ,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAQtD,UAAU,CAAC,KAAK,EAAE;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,YAAY,CAAC;IASnB,YAAY,CAAC,KAAK,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,YAAY,CAAC;IAanB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsBhE,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAK7B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
package/dist/api/client.js
CHANGED
|
@@ -162,6 +162,8 @@ export class PlaybasisClient {
|
|
|
162
162
|
}
|
|
163
163
|
async getPlayerQuests(playerId) {
|
|
164
164
|
const data = await this.request('GET', `/players/${encodeURIComponent(playerId)}/quests`);
|
|
165
|
+
if (Array.isArray(data))
|
|
166
|
+
return data;
|
|
165
167
|
return data.quests || data.items || [];
|
|
166
168
|
}
|
|
167
169
|
async getQuestProgress(playerId, questId) {
|
|
@@ -177,6 +179,8 @@ export class PlaybasisClient {
|
|
|
177
179
|
}
|
|
178
180
|
async getPlayerBadges(playerId) {
|
|
179
181
|
const data = await this.request('GET', `/players/${encodeURIComponent(playerId)}/badges`);
|
|
182
|
+
if (Array.isArray(data))
|
|
183
|
+
return data;
|
|
180
184
|
return data.badges || data.items || [];
|
|
181
185
|
}
|
|
182
186
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -204,9 +208,40 @@ export class PlaybasisClient {
|
|
|
204
208
|
if (options?.cursor)
|
|
205
209
|
params.set('cursor', options.cursor);
|
|
206
210
|
const data = await this.request('GET', `/leaderboards/${encodeURIComponent(leaderboardId)}?${params}`);
|
|
211
|
+
const leaderboardData = data;
|
|
212
|
+
const entries = 'entries' in data
|
|
213
|
+
? data.entries
|
|
214
|
+
: 'items' in data
|
|
215
|
+
? data.items
|
|
216
|
+
: leaderboardData.leaderboard?.entries;
|
|
217
|
+
const total = 'total' in data && typeof data.total === 'number'
|
|
218
|
+
? data.total
|
|
219
|
+
: leaderboardData.leaderboard?.total ?? entries?.length ?? 0;
|
|
220
|
+
const normalizedEntries = (entries || []).map((entry, index) => {
|
|
221
|
+
const raw = entry;
|
|
222
|
+
const score = typeof raw.score === 'number'
|
|
223
|
+
? raw.score
|
|
224
|
+
: typeof raw.balance === 'number'
|
|
225
|
+
? raw.balance
|
|
226
|
+
: typeof raw.points === 'number'
|
|
227
|
+
? raw.points
|
|
228
|
+
: typeof raw.value === 'number'
|
|
229
|
+
? raw.value
|
|
230
|
+
: 0;
|
|
231
|
+
const rank = typeof raw.rank === 'number' ? raw.rank : index + 1;
|
|
232
|
+
const displayName = raw.displayName || raw.name || raw.playerId || 'Player';
|
|
233
|
+
const playerId = raw.playerId || raw.id || displayName;
|
|
234
|
+
return {
|
|
235
|
+
playerId,
|
|
236
|
+
displayName,
|
|
237
|
+
rank,
|
|
238
|
+
score,
|
|
239
|
+
metadata: raw.metadata,
|
|
240
|
+
};
|
|
241
|
+
});
|
|
207
242
|
return {
|
|
208
|
-
entries:
|
|
209
|
-
total
|
|
243
|
+
entries: normalizedEntries,
|
|
244
|
+
total,
|
|
210
245
|
};
|
|
211
246
|
}
|
|
212
247
|
async getPlayerRank(leaderboardId, playerId) {
|