@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.
Files changed (106) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/LICENSE +21 -0
  3. package/README.md +267 -0
  4. package/SDK_HANDOVER_GUIDE.md +129 -0
  5. package/dist/PlaybasisProvider.d.ts +19 -0
  6. package/dist/PlaybasisProvider.d.ts.map +1 -0
  7. package/dist/PlaybasisProvider.js +24 -0
  8. package/dist/QwikCardApp.d.ts +9 -0
  9. package/dist/QwikCardApp.d.ts.map +1 -0
  10. package/dist/QwikCardApp.js +210 -0
  11. package/dist/api/client.d.ts +66 -0
  12. package/dist/api/client.d.ts.map +1 -0
  13. package/dist/api/client.js +196 -0
  14. package/dist/components/Badge.d.ts +8 -0
  15. package/dist/components/Badge.d.ts.map +1 -0
  16. package/dist/components/Badge.js +34 -0
  17. package/dist/components/BadgeIcon.d.ts +10 -0
  18. package/dist/components/BadgeIcon.d.ts.map +1 -0
  19. package/dist/components/BadgeIcon.js +51 -0
  20. package/dist/components/Button.d.ts +10 -0
  21. package/dist/components/Button.d.ts.map +1 -0
  22. package/dist/components/Button.js +40 -0
  23. package/dist/components/GradientCard.d.ts +9 -0
  24. package/dist/components/GradientCard.d.ts.map +1 -0
  25. package/dist/components/GradientCard.js +28 -0
  26. package/dist/components/PointsBalance.d.ts +8 -0
  27. package/dist/components/PointsBalance.d.ts.map +1 -0
  28. package/dist/components/PointsBalance.js +85 -0
  29. package/dist/components/ProgressBar.d.ts +8 -0
  30. package/dist/components/ProgressBar.d.ts.map +1 -0
  31. package/dist/components/ProgressBar.js +41 -0
  32. package/dist/components/QuestProgress.d.ts +10 -0
  33. package/dist/components/QuestProgress.d.ts.map +1 -0
  34. package/dist/components/QuestProgress.js +94 -0
  35. package/dist/components/RadialGauge.d.ts +8 -0
  36. package/dist/components/RadialGauge.d.ts.map +1 -0
  37. package/dist/components/RadialGauge.js +53 -0
  38. package/dist/components/RewardCard.d.ts +10 -0
  39. package/dist/components/RewardCard.d.ts.map +1 -0
  40. package/dist/components/RewardCard.js +64 -0
  41. package/dist/components/RulesModal.d.ts +7 -0
  42. package/dist/components/RulesModal.d.ts.map +1 -0
  43. package/dist/components/RulesModal.js +106 -0
  44. package/dist/hooks/useBadges.d.ts +12 -0
  45. package/dist/hooks/useBadges.d.ts.map +1 -0
  46. package/dist/hooks/useBadges.js +42 -0
  47. package/dist/hooks/usePoints.d.ts +13 -0
  48. package/dist/hooks/usePoints.d.ts.map +1 -0
  49. package/dist/hooks/usePoints.js +70 -0
  50. package/dist/hooks/useQuests.d.ts +12 -0
  51. package/dist/hooks/useQuests.d.ts.map +1 -0
  52. package/dist/hooks/useQuests.js +41 -0
  53. package/dist/hooks/useQwikApp.d.ts +16 -0
  54. package/dist/hooks/useQwikApp.d.ts.map +1 -0
  55. package/dist/hooks/useQwikApp.js +42 -0
  56. package/dist/hooks/useRewards.d.ts +12 -0
  57. package/dist/hooks/useRewards.d.ts.map +1 -0
  58. package/dist/hooks/useRewards.js +56 -0
  59. package/dist/index.d.ts +27 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +29 -0
  62. package/dist/theme/context.d.ts +8 -0
  63. package/dist/theme/context.d.ts.map +1 -0
  64. package/dist/theme/context.js +8 -0
  65. package/dist/theme/tokens.d.ts +35 -0
  66. package/dist/theme/tokens.d.ts.map +1 -0
  67. package/dist/theme/tokens.js +33 -0
  68. package/dist/types/index.d.ts +119 -0
  69. package/dist/types/index.d.ts.map +1 -0
  70. package/dist/types/index.js +4 -0
  71. package/dist/web/widgetAssets.d.ts +4 -0
  72. package/dist/web/widgetAssets.d.ts.map +1 -0
  73. package/dist/web/widgetAssets.js +5 -0
  74. package/dist/web/widgetHtml.d.ts +2 -0
  75. package/dist/web/widgetHtml.d.ts.map +1 -0
  76. package/dist/web/widgetHtml.js +299 -0
  77. package/dist/web/widgetTypes.d.ts +128 -0
  78. package/dist/web/widgetTypes.d.ts.map +1 -0
  79. package/dist/web/widgetTypes.js +1 -0
  80. package/package.json +86 -0
  81. package/src/PlaybasisProvider.tsx +72 -0
  82. package/src/QwikCardApp.tsx +302 -0
  83. package/src/api/client.ts +307 -0
  84. package/src/components/Badge.tsx +51 -0
  85. package/src/components/BadgeIcon.tsx +97 -0
  86. package/src/components/Button.tsx +70 -0
  87. package/src/components/GradientCard.tsx +49 -0
  88. package/src/components/PointsBalance.tsx +122 -0
  89. package/src/components/ProgressBar.tsx +65 -0
  90. package/src/components/QuestProgress.tsx +153 -0
  91. package/src/components/RadialGauge.tsx +101 -0
  92. package/src/components/RewardCard.tsx +123 -0
  93. package/src/components/RulesModal.tsx +171 -0
  94. package/src/hooks/useBadges.ts +59 -0
  95. package/src/hooks/usePoints.ts +91 -0
  96. package/src/hooks/useQuests.ts +60 -0
  97. package/src/hooks/useQwikApp.ts +49 -0
  98. package/src/hooks/useRewards.ts +74 -0
  99. package/src/index.ts +34 -0
  100. package/src/theme/context.tsx +17 -0
  101. package/src/theme/tokens.ts +68 -0
  102. package/src/types/index.ts +176 -0
  103. package/src/web/widgetAssets.d.ts +3 -0
  104. package/src/web/widgetAssets.ts +6 -0
  105. package/src/web/widgetHtml.ts +302 -0
  106. package/src/web/widgetTypes.ts +146 -0
@@ -0,0 +1,2 @@
1
+ export declare const getWidgetHtml: () => string;
2
+ //# sourceMappingURL=widgetHtml.d.ts.map
@@ -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;