@playbasis-ai/qwikcard-sdk 2.3.4
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 +142 -0
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/SDK_HANDOVER_GUIDE.md +129 -0
- package/dist/PlaybasisProvider.d.ts +19 -0
- package/dist/PlaybasisProvider.d.ts.map +1 -0
- package/dist/PlaybasisProvider.js +24 -0
- package/dist/QwikCardApp.d.ts +9 -0
- package/dist/QwikCardApp.d.ts.map +1 -0
- package/dist/QwikCardApp.js +210 -0
- package/dist/api/client.d.ts +66 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +196 -0
- package/dist/components/Badge.d.ts +8 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +34 -0
- package/dist/components/BadgeIcon.d.ts +10 -0
- package/dist/components/BadgeIcon.d.ts.map +1 -0
- package/dist/components/BadgeIcon.js +51 -0
- package/dist/components/Button.d.ts +10 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +40 -0
- package/dist/components/GradientCard.d.ts +9 -0
- package/dist/components/GradientCard.d.ts.map +1 -0
- package/dist/components/GradientCard.js +28 -0
- package/dist/components/PointsBalance.d.ts +8 -0
- package/dist/components/PointsBalance.d.ts.map +1 -0
- package/dist/components/PointsBalance.js +85 -0
- package/dist/components/ProgressBar.d.ts +8 -0
- package/dist/components/ProgressBar.d.ts.map +1 -0
- package/dist/components/ProgressBar.js +41 -0
- package/dist/components/QuestProgress.d.ts +10 -0
- package/dist/components/QuestProgress.d.ts.map +1 -0
- package/dist/components/QuestProgress.js +94 -0
- package/dist/components/RadialGauge.d.ts +8 -0
- package/dist/components/RadialGauge.d.ts.map +1 -0
- package/dist/components/RadialGauge.js +53 -0
- package/dist/components/RewardCard.d.ts +10 -0
- package/dist/components/RewardCard.d.ts.map +1 -0
- package/dist/components/RewardCard.js +64 -0
- package/dist/components/RulesModal.d.ts +7 -0
- package/dist/components/RulesModal.d.ts.map +1 -0
- package/dist/components/RulesModal.js +106 -0
- package/dist/hooks/useBadges.d.ts +12 -0
- package/dist/hooks/useBadges.d.ts.map +1 -0
- package/dist/hooks/useBadges.js +42 -0
- package/dist/hooks/usePoints.d.ts +13 -0
- package/dist/hooks/usePoints.d.ts.map +1 -0
- package/dist/hooks/usePoints.js +70 -0
- package/dist/hooks/useQuests.d.ts +12 -0
- package/dist/hooks/useQuests.d.ts.map +1 -0
- package/dist/hooks/useQuests.js +41 -0
- package/dist/hooks/useQwikApp.d.ts +16 -0
- package/dist/hooks/useQwikApp.d.ts.map +1 -0
- package/dist/hooks/useQwikApp.js +42 -0
- package/dist/hooks/useRewards.d.ts +12 -0
- package/dist/hooks/useRewards.d.ts.map +1 -0
- package/dist/hooks/useRewards.js +56 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/theme/context.d.ts +8 -0
- package/dist/theme/context.d.ts.map +1 -0
- package/dist/theme/context.js +8 -0
- package/dist/theme/tokens.d.ts +35 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +33 -0
- package/dist/types/index.d.ts +119 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/web/widgetAssets.d.ts +4 -0
- package/dist/web/widgetAssets.d.ts.map +1 -0
- package/dist/web/widgetAssets.js +5 -0
- package/dist/web/widgetHtml.d.ts +2 -0
- package/dist/web/widgetHtml.d.ts.map +1 -0
- package/dist/web/widgetHtml.js +299 -0
- package/dist/web/widgetTypes.d.ts +128 -0
- package/dist/web/widgetTypes.d.ts.map +1 -0
- package/dist/web/widgetTypes.js +1 -0
- package/package.json +86 -0
- package/src/PlaybasisProvider.tsx +72 -0
- package/src/QwikCardApp.tsx +302 -0
- package/src/api/client.ts +307 -0
- package/src/components/Badge.tsx +51 -0
- package/src/components/BadgeIcon.tsx +97 -0
- package/src/components/Button.tsx +70 -0
- package/src/components/GradientCard.tsx +49 -0
- package/src/components/PointsBalance.tsx +122 -0
- package/src/components/ProgressBar.tsx +65 -0
- package/src/components/QuestProgress.tsx +153 -0
- package/src/components/RadialGauge.tsx +101 -0
- package/src/components/RewardCard.tsx +123 -0
- package/src/components/RulesModal.tsx +171 -0
- package/src/hooks/useBadges.ts +59 -0
- package/src/hooks/usePoints.ts +91 -0
- package/src/hooks/useQuests.ts +60 -0
- package/src/hooks/useQwikApp.ts +49 -0
- package/src/hooks/useRewards.ts +74 -0
- package/src/index.ts +34 -0
- package/src/theme/context.tsx +17 -0
- package/src/theme/tokens.ts +68 -0
- package/src/types/index.ts +176 -0
- package/src/web/widgetAssets.d.ts +3 -0
- package/src/web/widgetAssets.ts +6 -0
- package/src/web/widgetHtml.ts +302 -0
- package/src/web/widgetTypes.ts +146 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgetHtml.d.ts","sourceRoot":"","sources":["../../src/web/widgetHtml.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,cAySzB,CAAC"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { WIDGET_CSS, WIDGET_UMD_JS, WIDGET_SDK_VERSION } from './widgetAssets';
|
|
2
|
+
const escapeScript = (value) => value.replace(/<\/script/gi, '<\\/script');
|
|
3
|
+
export const getWidgetHtml = () => {
|
|
4
|
+
const umd = escapeScript(WIDGET_UMD_JS);
|
|
5
|
+
const css = WIDGET_CSS;
|
|
6
|
+
return `<!DOCTYPE html>
|
|
7
|
+
<html lang="en">
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="UTF-8" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
|
11
|
+
<title>Playbasis Widget</title>
|
|
12
|
+
<style>
|
|
13
|
+
/* Base reset and responsive constraints */
|
|
14
|
+
*, *::before, *::after {
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
html, body {
|
|
18
|
+
height: 100%;
|
|
19
|
+
width: 100%;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
background: white;
|
|
23
|
+
overflow-x: hidden;
|
|
24
|
+
overflow-y: auto;
|
|
25
|
+
-webkit-overflow-scrolling: touch;
|
|
26
|
+
font-size: 14px;
|
|
27
|
+
}
|
|
28
|
+
/* Widget root container - CRITICAL for init() */
|
|
29
|
+
#pb-widget-root {
|
|
30
|
+
width: 100%;
|
|
31
|
+
min-height: 100vh;
|
|
32
|
+
max-width: 100vw;
|
|
33
|
+
overflow-x: hidden;
|
|
34
|
+
position: relative;
|
|
35
|
+
}
|
|
36
|
+
/* Playbasis widget container (created by init()) */
|
|
37
|
+
#playbasis-widget-container {
|
|
38
|
+
width: 100% !important;
|
|
39
|
+
max-width: 100vw !important;
|
|
40
|
+
height: auto !important;
|
|
41
|
+
}
|
|
42
|
+
/* Force responsive sizing on shadow DOM and children */
|
|
43
|
+
#playbasis-widget-container > * {
|
|
44
|
+
width: 100% !important;
|
|
45
|
+
max-width: 100vw !important;
|
|
46
|
+
}
|
|
47
|
+
/* Constrain SVG elements */
|
|
48
|
+
svg {
|
|
49
|
+
max-width: 100% !important;
|
|
50
|
+
height: auto !important;
|
|
51
|
+
}
|
|
52
|
+
/* Aggressive constraints on progress/orb elements */
|
|
53
|
+
[class*="progress"],
|
|
54
|
+
[class*="Progress"],
|
|
55
|
+
[class*="orb"],
|
|
56
|
+
[class*="Orb"],
|
|
57
|
+
[class*="radial"],
|
|
58
|
+
[class*="Radial"],
|
|
59
|
+
[class*="circular"],
|
|
60
|
+
[class*="Circular"] {
|
|
61
|
+
max-width: min(200px, 50vw) !important;
|
|
62
|
+
max-height: min(200px, 50vw) !important;
|
|
63
|
+
width: auto !important;
|
|
64
|
+
height: auto !important;
|
|
65
|
+
}
|
|
66
|
+
/* Dashboard and layout containers */
|
|
67
|
+
[class*="dashboard"],
|
|
68
|
+
[class*="Dashboard"],
|
|
69
|
+
[class*="container"],
|
|
70
|
+
[class*="Container"] {
|
|
71
|
+
width: 100% !important;
|
|
72
|
+
max-width: 100vw !important;
|
|
73
|
+
padding-left: 1rem !important;
|
|
74
|
+
padding-right: 1rem !important;
|
|
75
|
+
}
|
|
76
|
+
/* Responsive text scaling */
|
|
77
|
+
@media (max-width: 375px) {
|
|
78
|
+
html { font-size: 12px; }
|
|
79
|
+
[class*="text-"] { font-size: 0.875em !important; }
|
|
80
|
+
}
|
|
81
|
+
@media (min-width: 376px) and (max-width: 430px) {
|
|
82
|
+
html { font-size: 14px; }
|
|
83
|
+
}
|
|
84
|
+
@media (min-width: 431px) {
|
|
85
|
+
html { font-size: 16px; }
|
|
86
|
+
}
|
|
87
|
+
/* Mobile-specific overrides */
|
|
88
|
+
@media (max-width: 430px) {
|
|
89
|
+
[class*="w-"] {
|
|
90
|
+
max-width: 100vw !important;
|
|
91
|
+
}
|
|
92
|
+
[class*="h-64"],
|
|
93
|
+
[class*="h-72"],
|
|
94
|
+
[class*="h-80"],
|
|
95
|
+
[class*="h-96"] {
|
|
96
|
+
height: auto !important;
|
|
97
|
+
max-height: 50vh !important;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
101
|
+
<style>${css}</style>
|
|
102
|
+
</head>
|
|
103
|
+
<body>
|
|
104
|
+
<!-- ERROR DISPLAY -->
|
|
105
|
+
<div id="error-display" style="display:none; padding:20px; font-family:sans-serif; color:#ef4444; text-align:center; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); max-width:90%; z-index:10000;">
|
|
106
|
+
<h3 style="margin-bottom:10px; font-size:16px;">Widget Error</h3>
|
|
107
|
+
<div id="error-message" style="font-size:11px; opacity:0.8; font-family:monospace; white-space:pre-wrap; word-break:break-word;"></div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<!-- WIDGET MOUNT POINT (required by PlaybasisWidget.init) -->
|
|
111
|
+
<div id="pb-widget-root"></div>
|
|
112
|
+
|
|
113
|
+
<!-- POLYFILLS -->
|
|
114
|
+
<script>
|
|
115
|
+
// Fix 1: process.env.NODE_ENV polyfill
|
|
116
|
+
if (typeof window.process === 'undefined') {
|
|
117
|
+
window.process = { env: { NODE_ENV: 'production' } };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Fix 2: module/exports polyfill for UMD compatibility
|
|
121
|
+
var __pbModuleExports = {};
|
|
122
|
+
if (typeof window.module === 'undefined') {
|
|
123
|
+
window.module = { exports: __pbModuleExports };
|
|
124
|
+
}
|
|
125
|
+
if (typeof window.exports === 'undefined') {
|
|
126
|
+
window.exports = __pbModuleExports;
|
|
127
|
+
}
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<!-- WIDGET UMD BUNDLE -->
|
|
131
|
+
<script>
|
|
132
|
+
// Embedded @playbasis/widget-sdk UMD build (v${WIDGET_SDK_VERSION})
|
|
133
|
+
try {
|
|
134
|
+
${umd}
|
|
135
|
+
|
|
136
|
+
// Fix 2 (cont): Re-attach to window if UMD exported to module.exports
|
|
137
|
+
if (!window.PlaybasisWidget && window.module && window.module.exports) {
|
|
138
|
+
if (window.module.exports.PlaybasisWidget) {
|
|
139
|
+
window.PlaybasisWidget = window.module.exports;
|
|
140
|
+
} else if (typeof window.module.exports === 'object' && window.module.exports.init) {
|
|
141
|
+
// Direct export case
|
|
142
|
+
window.PlaybasisWidget = window.module.exports;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (e) {
|
|
146
|
+
console.error('Failed to load widget bundle:', e);
|
|
147
|
+
if (typeof showError === 'function') {
|
|
148
|
+
showError('Bundle Error: ' + e.message);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<!-- BOOTSTRAP BRIDGE -->
|
|
154
|
+
<script>
|
|
155
|
+
(function () {
|
|
156
|
+
function safeParse(text) {
|
|
157
|
+
try { return JSON.parse(text); } catch { return null; }
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function postToNative(payload) {
|
|
161
|
+
if (!window.ReactNativeWebView && !window.ReactNativeWebView.postMessage) return;
|
|
162
|
+
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
window.showError = function(msg) {
|
|
166
|
+
var el = document.getElementById('error-display');
|
|
167
|
+
var txt = document.getElementById('error-message');
|
|
168
|
+
if (el && txt) {
|
|
169
|
+
el.style.display = 'block';
|
|
170
|
+
txt.textContent = msg;
|
|
171
|
+
}
|
|
172
|
+
postToNative({ type: 'ERROR', error: msg });
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
window.onerror = function(msg, url, line, col, error) {
|
|
176
|
+
var errorStr = msg;
|
|
177
|
+
if (error && error.message) errorStr = error.message;
|
|
178
|
+
window.showError(errorStr);
|
|
179
|
+
return false;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
var initConfig = null;
|
|
183
|
+
var bootstrapData = null;
|
|
184
|
+
var mounted = false;
|
|
185
|
+
|
|
186
|
+
// Native -> Web message handler
|
|
187
|
+
window.__PB_HANDLE_NATIVE_MESSAGE__ = function (payload) {
|
|
188
|
+
try {
|
|
189
|
+
if (!payload) return;
|
|
190
|
+
if (payload.type === 'RESPONSE') {
|
|
191
|
+
if (!payload.ok) {
|
|
192
|
+
console.error('[PlaybasisWidget] Native bootstrap error:', payload.error);
|
|
193
|
+
window.showError('Native Bootstrap Failed: ' + (payload.error || 'Unknown'));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
bootstrapData = payload.data || null;
|
|
197
|
+
tryMount();
|
|
198
|
+
}
|
|
199
|
+
} catch (e) {
|
|
200
|
+
window.showError('Message Handle Error: ' + e.message);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
function tryMount() {
|
|
205
|
+
if (mounted || !initConfig || !bootstrapData) return;
|
|
206
|
+
|
|
207
|
+
// Verify container exists
|
|
208
|
+
var container = document.getElementById('pb-widget-root');
|
|
209
|
+
if (!container) {
|
|
210
|
+
window.showError('Container #pb-widget-root not found in DOM');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Locate widget module
|
|
215
|
+
var PlaybasisWidget = window.PlaybasisWidget;
|
|
216
|
+
if (!PlaybasisWidget) {
|
|
217
|
+
window.showError('PlaybasisWidget not found on window');
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Find init function (could be PlaybasisWidget.init or PlaybasisWidget.PlaybasisWidget.init)
|
|
222
|
+
var initFn = null;
|
|
223
|
+
var targetObject = null;
|
|
224
|
+
|
|
225
|
+
if (typeof PlaybasisWidget.init === 'function') {
|
|
226
|
+
initFn = PlaybasisWidget.init;
|
|
227
|
+
targetObject = PlaybasisWidget;
|
|
228
|
+
} else if (PlaybasisWidget.PlaybasisWidget && typeof PlaybasisWidget.PlaybasisWidget.init === 'function') {
|
|
229
|
+
initFn = PlaybasisWidget.PlaybasisWidget.init;
|
|
230
|
+
targetObject = PlaybasisWidget.PlaybasisWidget;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!initFn) {
|
|
234
|
+
window.showError('PlaybasisWidget.init function not found');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
mounted = true;
|
|
240
|
+
var tenantId = initConfig.config.tenantId;
|
|
241
|
+
var userId = initConfig.config.playerId;
|
|
242
|
+
|
|
243
|
+
// Call init with proper this context
|
|
244
|
+
initFn.call(targetObject, {
|
|
245
|
+
container: container,
|
|
246
|
+
embedded: true, // CRITICAL: Disable Shadow DOM so CSS applies correctly
|
|
247
|
+
apiKey: 'embedded',
|
|
248
|
+
tenantId: tenantId,
|
|
249
|
+
userId: userId,
|
|
250
|
+
themeName: 'qwik',
|
|
251
|
+
bootstrap: {
|
|
252
|
+
tenantId: tenantId,
|
|
253
|
+
...bootstrapData,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
} catch (e) {
|
|
257
|
+
window.showError('Mount Error: ' + e.message);
|
|
258
|
+
console.error('[PlaybasisWidget] Mount error details:', e);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function initIfReady() {
|
|
263
|
+
var init = window.__PB_INIT__;
|
|
264
|
+
if (!init || init.__applied) return;
|
|
265
|
+
init.__applied = true;
|
|
266
|
+
initConfig = init;
|
|
267
|
+
|
|
268
|
+
// Request bootstrap data from native
|
|
269
|
+
postToNative({
|
|
270
|
+
type: 'REQUEST',
|
|
271
|
+
requestId: String(Date.now()) + '-' + Math.random().toString(16).slice(2),
|
|
272
|
+
resource: 'bootstrap'
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Poll for injectedJavaScript
|
|
277
|
+
var start = Date.now();
|
|
278
|
+
var timer = setInterval(function () {
|
|
279
|
+
initIfReady();
|
|
280
|
+
if (Date.now() - start > 8000) {
|
|
281
|
+
clearInterval(timer);
|
|
282
|
+
if (!mounted && !bootstrapData) {
|
|
283
|
+
console.warn('[PlaybasisWidget] Bootstrap timed out');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}, 50);
|
|
287
|
+
|
|
288
|
+
// Listen for messages from native
|
|
289
|
+
function handleIncoming(event) {
|
|
290
|
+
var payload = typeof event.data === 'string' ? safeParse(event.data) : event.data;
|
|
291
|
+
if (payload) window.__PB_HANDLE_NATIVE_MESSAGE__(payload);
|
|
292
|
+
}
|
|
293
|
+
window.addEventListener('message', handleIncoming);
|
|
294
|
+
document.addEventListener('message', handleIncoming);
|
|
295
|
+
})();
|
|
296
|
+
</script>
|
|
297
|
+
</body>
|
|
298
|
+
</html>`;
|
|
299
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export type WidgetBridgeResource = 'bootstrap';
|
|
2
|
+
export type WidgetBridgeMessage = {
|
|
3
|
+
type: 'INIT';
|
|
4
|
+
config: {
|
|
5
|
+
tenantId: string;
|
|
6
|
+
playerId: string;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
};
|
|
9
|
+
platform?: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'REQUEST';
|
|
12
|
+
requestId: string;
|
|
13
|
+
resource: WidgetBridgeResource;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'RESPONSE';
|
|
16
|
+
requestId: string;
|
|
17
|
+
ok: true;
|
|
18
|
+
data: WidgetBootstrapData;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'RESPONSE';
|
|
21
|
+
requestId: string;
|
|
22
|
+
ok: false;
|
|
23
|
+
error: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'ERROR';
|
|
26
|
+
error: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'OPEN_GAME';
|
|
29
|
+
url: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
};
|
|
32
|
+
export interface WidgetUserState {
|
|
33
|
+
userId: string;
|
|
34
|
+
level: number;
|
|
35
|
+
exp: number;
|
|
36
|
+
compositeScore: number;
|
|
37
|
+
positiveChangePct: number;
|
|
38
|
+
}
|
|
39
|
+
export interface WidgetTransaction {
|
|
40
|
+
id: string;
|
|
41
|
+
type: 'earn' | 'spend' | 'bonus';
|
|
42
|
+
amount: number;
|
|
43
|
+
description: string;
|
|
44
|
+
timestamp: number;
|
|
45
|
+
}
|
|
46
|
+
export interface WidgetCollectionItem {
|
|
47
|
+
id: string;
|
|
48
|
+
category: string;
|
|
49
|
+
rarity: string;
|
|
50
|
+
unlocked: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface WidgetNotification {
|
|
53
|
+
id: string;
|
|
54
|
+
type: 'badge' | 'level_up' | 'goal' | 'reward' | 'leaderboard';
|
|
55
|
+
message: string;
|
|
56
|
+
timestamp?: number;
|
|
57
|
+
read?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export type WidgetGoalType = 'financial' | 'habit' | 'performance';
|
|
60
|
+
export type WidgetGoalStatus = 'on_track' | 'at_risk' | 'completed';
|
|
61
|
+
export interface WidgetGoal {
|
|
62
|
+
goalId: string;
|
|
63
|
+
type: WidgetGoalType;
|
|
64
|
+
target: number;
|
|
65
|
+
current: number;
|
|
66
|
+
progressPct: number;
|
|
67
|
+
startDate: string;
|
|
68
|
+
endDate: string;
|
|
69
|
+
status: WidgetGoalStatus;
|
|
70
|
+
rewards?: {
|
|
71
|
+
xp?: number;
|
|
72
|
+
badges?: string[];
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export interface WidgetActivityDay {
|
|
76
|
+
date: string;
|
|
77
|
+
count: number;
|
|
78
|
+
}
|
|
79
|
+
export interface WidgetLeaderboardEntry {
|
|
80
|
+
scope: 'global' | 'team' | 'season';
|
|
81
|
+
rank: number;
|
|
82
|
+
delta: number;
|
|
83
|
+
}
|
|
84
|
+
export type WidgetBadgeRarity = 'common' | 'rare' | 'epic' | 'legendary';
|
|
85
|
+
export interface WidgetBadge {
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
rarity: WidgetBadgeRarity;
|
|
89
|
+
unlocked: boolean;
|
|
90
|
+
imageUrl?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface WidgetLeaderboardEntryDisplay {
|
|
93
|
+
userId?: string;
|
|
94
|
+
rank: number;
|
|
95
|
+
displayName: string;
|
|
96
|
+
score: number;
|
|
97
|
+
delta?: number;
|
|
98
|
+
isCurrentUser?: boolean;
|
|
99
|
+
avatarUrl?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface WidgetWallet {
|
|
102
|
+
currency: string;
|
|
103
|
+
balance: number;
|
|
104
|
+
earnedDelta: number;
|
|
105
|
+
qwikCoins?: number;
|
|
106
|
+
}
|
|
107
|
+
export interface WidgetReward {
|
|
108
|
+
id: string;
|
|
109
|
+
name: string;
|
|
110
|
+
description: string;
|
|
111
|
+
cost: number;
|
|
112
|
+
imageUrl?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface WidgetBootstrapData {
|
|
115
|
+
tenantId: string;
|
|
116
|
+
user: WidgetUserState;
|
|
117
|
+
wallet: WidgetWallet | null;
|
|
118
|
+
goals: WidgetGoal[];
|
|
119
|
+
activities: WidgetActivityDay[];
|
|
120
|
+
transactions?: WidgetTransaction[];
|
|
121
|
+
collections?: WidgetCollectionItem[];
|
|
122
|
+
badges: WidgetBadge[];
|
|
123
|
+
rewards?: WidgetReward[];
|
|
124
|
+
leaderboardEntries: WidgetLeaderboardEntryDisplay[];
|
|
125
|
+
leaderboard?: WidgetLeaderboardEntry | null;
|
|
126
|
+
notifications?: WidgetNotification[];
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=widgetTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgetTypes.d.ts","sourceRoot":"","sources":["../../src/web/widgetTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@playbasis-ai/qwikcard-sdk",
|
|
3
|
+
"version": "2.3.4",
|
|
4
|
+
"description": "Playbasis SDK for QwikCard College Rewards - React Native gamification integration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"source": "src/index.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./QwikCardApp": {
|
|
17
|
+
"types": "./dist/QwikCardApp.d.ts",
|
|
18
|
+
"import": "./dist/QwikCardApp.js",
|
|
19
|
+
"require": "./dist/QwikCardApp.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"src",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CHANGELOG.md",
|
|
28
|
+
"SDK_HANDOVER_GUIDE.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"clean": "rm -rf dist",
|
|
33
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
34
|
+
"test": "jest",
|
|
35
|
+
"lint": "eslint src/",
|
|
36
|
+
"typecheck": "tsc --noEmit"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/react": "^18.2.0",
|
|
41
|
+
"@types/react-native": "^0.73.0",
|
|
42
|
+
"react": "^18.2.0",
|
|
43
|
+
"react-native": "^0.73.0",
|
|
44
|
+
"react-native-webview": "^13.15.0",
|
|
45
|
+
"typescript": "^5.3.0",
|
|
46
|
+
"jest": "^29.7.0",
|
|
47
|
+
"react-native-linear-gradient": "^2.8.0",
|
|
48
|
+
"react-native-svg": "^14.1.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"react": ">=18.0.0",
|
|
52
|
+
"react-native": ">=0.70.0",
|
|
53
|
+
"react-native-linear-gradient": ">=2.0.0",
|
|
54
|
+
"react-native-svg": ">=12.0.0",
|
|
55
|
+
"react-native-webview": ">=11.0.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"playbasis",
|
|
62
|
+
"gamification",
|
|
63
|
+
"qwikcard",
|
|
64
|
+
"react-native",
|
|
65
|
+
"loyalty",
|
|
66
|
+
"rewards",
|
|
67
|
+
"quests",
|
|
68
|
+
"badges",
|
|
69
|
+
"leaderboards",
|
|
70
|
+
"points"
|
|
71
|
+
],
|
|
72
|
+
"author": "Playbasis <support@playbasis.com>",
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"repository": {
|
|
75
|
+
"type": "git",
|
|
76
|
+
"url": "https://github.com/playbasis/playbasis-platform.git",
|
|
77
|
+
"directory": "client-sdks/qwikcard-sdk-v1.3.0-pkg"
|
|
78
|
+
},
|
|
79
|
+
"bugs": {
|
|
80
|
+
"url": "https://github.com/playbasis/playbasis-platform/issues"
|
|
81
|
+
},
|
|
82
|
+
"homepage": "https://github.com/playbasis/playbasis-platform/tree/main/client-sdks/qwikcard-sdk-v1.3.0-pkg#readme",
|
|
83
|
+
"publishConfig": {
|
|
84
|
+
"registry": "https://registry.npmjs.org/"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { PlaybasisClient } from './api/client';
|
|
5
|
+
import { ThemeProvider } from './theme/context';
|
|
6
|
+
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
// Context
|
|
9
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
interface PlaybasisContextValue {
|
|
12
|
+
client: PlaybasisClient;
|
|
13
|
+
tenantId: string;
|
|
14
|
+
playerId: string | null;
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const PlaybasisContext = createContext<PlaybasisContextValue | null>(null);
|
|
19
|
+
|
|
20
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
// Provider Props
|
|
22
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
interface PlaybasisProviderProps {
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
apiKey: string;
|
|
27
|
+
tenantId?: string;
|
|
28
|
+
playerId?: string;
|
|
29
|
+
baseUrl?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
33
|
+
// Provider Component
|
|
34
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
export function PlaybasisProvider({
|
|
37
|
+
children,
|
|
38
|
+
apiKey,
|
|
39
|
+
tenantId = 'qwikcard',
|
|
40
|
+
playerId,
|
|
41
|
+
baseUrl = 'https://apim-pb-production.azure-api.net/v1',
|
|
42
|
+
}: PlaybasisProviderProps) {
|
|
43
|
+
const client = useMemo(
|
|
44
|
+
() => new PlaybasisClient({ apiKey, tenantId, baseUrl }),
|
|
45
|
+
[apiKey, tenantId, baseUrl],
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const value = useMemo(
|
|
49
|
+
() => ({ client, tenantId, playerId: playerId ?? null, baseUrl }),
|
|
50
|
+
[client, tenantId, playerId, baseUrl],
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<ThemeProvider>
|
|
55
|
+
<PlaybasisContext.Provider value={value}>{children}</PlaybasisContext.Provider>
|
|
56
|
+
</ThemeProvider>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
// Hook
|
|
62
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
export function usePlaybasis(): PlaybasisContextValue {
|
|
65
|
+
const context = useContext(PlaybasisContext);
|
|
66
|
+
if (!context) {
|
|
67
|
+
throw new Error('usePlaybasis must be used within a PlaybasisProvider');
|
|
68
|
+
}
|
|
69
|
+
return context;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default PlaybasisProvider;
|