@phygitallabs/tapquest-core 2.8.0 → 2.9.1

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 (36) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +29 -35
  3. package/dist/index.js +1015 -721
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -3
  6. package/src/modules/auth/constants/index.ts +6 -0
  7. package/src/modules/auth/helpers/index.ts +1 -4
  8. package/src/modules/auth/hooks/index.ts +2 -0
  9. package/src/modules/auth/hooks/useGoogleLogin.ts +169 -0
  10. package/src/modules/auth/hooks/useTokenRefresher.ts +39 -0
  11. package/src/modules/auth/index.ts +8 -2
  12. package/src/modules/auth/providers/AuthProvider.tsx +214 -186
  13. package/src/modules/auth/store/authStore.ts +577 -0
  14. package/src/modules/auth/types/auth.ts +29 -0
  15. package/src/modules/auth/types/user-data.ts +38 -0
  16. package/src/modules/auth/utils/user.ts +21 -0
  17. package/src/modules/data-tracking/hooks/index.ts +25 -1
  18. package/src/modules/generate-certificate/helpers/index.ts +3 -0
  19. package/src/modules/generate-certificate/hooks/index.ts +15 -6
  20. package/src/modules/generate-certificate/index.ts +3 -1
  21. package/src/modules/notification/providers/index.tsx +3 -3
  22. package/src/modules/reward/hooks/useRewardService.ts +6 -6
  23. package/src/modules/session-replay/README.md +334 -0
  24. package/src/modules/session-replay/hooks/useSessionReplay.ts +16 -0
  25. package/src/modules/session-replay/index.ts +10 -0
  26. package/src/modules/session-replay/providers/SessionReplayProvider.tsx +189 -0
  27. package/src/modules/session-replay/types/index.ts +147 -0
  28. package/src/modules/session-replay/utils/index.ts +12 -0
  29. package/src/providers/ServicesProvider.tsx +4 -76
  30. package/src/providers/TapquestCoreProvider.tsx +33 -46
  31. package/tsup.config.ts +1 -1
  32. package/dist/index.cjs +0 -1531
  33. package/dist/index.cjs.map +0 -1
  34. package/dist/index.d.cts +0 -690
  35. package/src/modules/auth/helpers/refreshToken.ts +0 -63
  36. package/src/modules/auth/store/authSlice.ts +0 -137
package/dist/index.js CHANGED
@@ -2,10 +2,6 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __esm = (fn, res) => function __init() {
7
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
- };
9
5
  var __export = (target, all) => {
10
6
  for (var name in all)
11
7
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -19,324 +15,16 @@ var __copyProps = (to, from, except, desc) => {
19
15
  return to;
20
16
  };
21
17
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
22
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
23
-
24
- // src/modules/auth/constants/index.ts
25
- var userInfoKey, accessTokenKey, refreshTokenKey, httpMaxRetries, retryAttemptsRefreshToken, deviceUIDKey, chipAuthTokenKey;
26
- var init_constants = __esm({
27
- "src/modules/auth/constants/index.ts"() {
28
- "use strict";
29
- userInfoKey = "phygital-user-info";
30
- accessTokenKey = "accessToken";
31
- refreshTokenKey = "refreshToken";
32
- httpMaxRetries = 3;
33
- retryAttemptsRefreshToken = "retryAttemptsRefreshToken";
34
- deviceUIDKey = "Device-UID";
35
- chipAuthTokenKey = "chip-auth-token";
36
- }
37
- });
38
-
39
- // src/modules/auth/services/FirebaseAuthService.ts
40
- var firebaseApp, firebaseAuth, getFirebaseModules, FirebaseAuthService;
41
- var init_FirebaseAuthService = __esm({
42
- "src/modules/auth/services/FirebaseAuthService.ts"() {
43
- "use strict";
44
- init_constants();
45
- getFirebaseModules = async () => {
46
- if (typeof window === "undefined") {
47
- throw new Error("Firebase can only be used in client environment");
48
- }
49
- if (!firebaseApp || !firebaseAuth) {
50
- const [
51
- { initializeApp, getApps },
52
- {
53
- getAuth,
54
- signInWithEmailAndPassword,
55
- createUserWithEmailAndPassword,
56
- signInWithPopup,
57
- GoogleAuthProvider,
58
- signOut: signOut2,
59
- sendPasswordResetEmail,
60
- sendEmailVerification,
61
- updatePassword,
62
- onAuthStateChanged
63
- }
64
- ] = await Promise.all([
65
- import("firebase/app"),
66
- import("firebase/auth")
67
- ]);
68
- firebaseApp = { initializeApp, getApps };
69
- firebaseAuth = {
70
- getAuth,
71
- signInWithEmailAndPassword,
72
- createUserWithEmailAndPassword,
73
- signInWithPopup,
74
- GoogleAuthProvider,
75
- signOut: signOut2,
76
- sendPasswordResetEmail,
77
- sendEmailVerification,
78
- updatePassword,
79
- onAuthStateChanged
80
- };
81
- }
82
- return { firebaseApp, firebaseAuth };
83
- };
84
- FirebaseAuthService = class {
85
- constructor(config) {
86
- __publicField(this, "app");
87
- __publicField(this, "auth");
88
- __publicField(this, "googleProvider");
89
- __publicField(this, "config");
90
- __publicField(this, "initialized", false);
91
- this.config = config;
92
- }
93
- async ensureInitialized() {
94
- if (this.initialized) return;
95
- const { firebaseApp: firebaseApp2, firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
96
- if (!firebaseApp2.getApps().length) {
97
- this.app = firebaseApp2.initializeApp(this.config);
98
- } else {
99
- this.app = firebaseApp2.getApps()[0];
100
- }
101
- this.auth = firebaseAuth2.getAuth(this.app);
102
- this.googleProvider = new firebaseAuth2.GoogleAuthProvider();
103
- this.initialized = true;
104
- }
105
- transformUserData(user) {
106
- return {
107
- id: user.uid,
108
- uid: user.uid,
109
- userName: user.displayName || "",
110
- displayName: user.displayName || "",
111
- email: user.email || "",
112
- refreshToken: user.refreshToken,
113
- accessToken: user.accessToken || "",
114
- exp: user.stsTokenManager?.expirationTime || 0,
115
- emailVerified: user.emailVerified,
116
- avatar: user.photoURL || "/images/default-avatar.jpg",
117
- signInProvider: this.getSignInProvider(user),
118
- role: void 0,
119
- scanStatus: false
120
- };
121
- }
122
- getSignInProvider(user) {
123
- const providers = user.providerData.map((p) => p.providerId);
124
- if (providers.includes("google.com")) return "google.com";
125
- return "password";
126
- }
127
- translateErrorCode(errorCode) {
128
- switch (errorCode) {
129
- case "auth/invalid-email":
130
- return "Email kh\xF4ng h\u1EE3p l\u1EC7";
131
- case "auth/user-disabled":
132
- return "T\xE0i kho\u1EA3n \u0111\xE3 b\u1ECB kh\xF3a";
133
- case "auth/wrong-password":
134
- return "T\xE0i kho\u1EA3n/m\u1EADt kh\u1EA9u kh\xF4ng \u0111\xFAng";
135
- case "auth/user-not-found":
136
- return "T\xE0i kho\u1EA3n/m\u1EADt kh\u1EA9u kh\xF4ng \u0111\xFAng";
137
- case "auth/weak-password":
138
- return "Weak password! Please use stronger password.";
139
- case "auth/email-already-in-use":
140
- return "Email \u0111\xE3 \u0111\u01B0\u1EE3c s\u1EED d\u1EE5ng";
141
- case "auth/account-exists-with-different-credential":
142
- return "T\xE0i kho\u1EA3n email \u0111\xE3 \u0111\u01B0\u1EE3c s\u1EED d\u1EE5ng b\u1EDFi m\u1ED9t ph\u01B0\u01A1ng th\u1EE9c \u0111\u0103ng nh\u1EADp kh\xE1c";
143
- case "auth/email-not-verified":
144
- return "Email ch\u01B0a \u0111\u01B0\u1EE3c x\xE1c th\u1EF1c";
145
- default:
146
- return "\u0110\xE3 c\xF3 l\u1ED7i x\u1EA3y ra";
147
- }
148
- }
149
- async signInWithEmailAndPassword(email, password) {
150
- try {
151
- await this.ensureInitialized();
152
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
153
- const signInResponse = await firebaseAuth2.signInWithEmailAndPassword(this.auth, email, password);
154
- const { user } = signInResponse;
155
- const data = this.transformUserData(user);
156
- const { emailVerified } = data;
157
- if (!emailVerified) {
158
- await this.signOut();
159
- localStorage.removeItem("phygital-user-info");
160
- localStorage.removeItem(accessTokenKey);
161
- localStorage.removeItem(refreshTokenKey);
162
- throw new Error("Email is not verified");
163
- }
164
- return {
165
- errorCode: "",
166
- data
167
- };
168
- } catch (err) {
169
- const errorCode = this.translateErrorCode(err.code);
170
- return {
171
- errorCode,
172
- data: null
173
- };
174
- }
175
- }
176
- async signInWithGoogle() {
177
- try {
178
- await this.ensureInitialized();
179
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
180
- const signInResponse = await firebaseAuth2.signInWithPopup(this.auth, this.googleProvider);
181
- const { user } = signInResponse;
182
- const data = this.transformUserData(user);
183
- const { emailVerified } = data;
184
- if (!emailVerified) {
185
- await this.signOut();
186
- throw new Error("Email is not verified");
187
- }
188
- return {
189
- errorCode: "",
190
- data
191
- };
192
- } catch (err) {
193
- const errorCode = this.translateErrorCode(err.code);
194
- return {
195
- errorCode,
196
- data: null
197
- };
198
- }
199
- }
200
- async signUp(email, password) {
201
- try {
202
- await this.ensureInitialized();
203
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
204
- const signUpResponse = await firebaseAuth2.createUserWithEmailAndPassword(this.auth, email, password);
205
- const { user } = signUpResponse;
206
- const data = this.transformUserData(user);
207
- return {
208
- errorCode: "",
209
- data
210
- };
211
- } catch (err) {
212
- const errorCode = this.translateErrorCode(err.code);
213
- return {
214
- errorCode,
215
- data: null
216
- };
217
- }
218
- }
219
- async signOut() {
220
- try {
221
- await this.ensureInitialized();
222
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
223
- await firebaseAuth2.signOut(this.auth);
224
- } catch (err) {
225
- console.log("Firebase signOut error:", err);
226
- }
227
- }
228
- async sendPasswordResetEmail(email) {
229
- await this.ensureInitialized();
230
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
231
- const actionCodeSettings = {
232
- url: window.location.origin,
233
- handleCodeInApp: true
234
- };
235
- await firebaseAuth2.sendPasswordResetEmail(this.auth, email, actionCodeSettings);
236
- }
237
- async sendEmailVerification() {
238
- await this.ensureInitialized();
239
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
240
- if (!this.auth.currentUser) {
241
- throw new Error("No current user");
242
- }
243
- const actionCodeSettings = {
244
- url: window.location.origin,
245
- handleCodeInApp: true
246
- };
247
- await firebaseAuth2.sendEmailVerification(this.auth.currentUser, actionCodeSettings);
248
- }
249
- async changePassword(newPassword) {
250
- await this.ensureInitialized();
251
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
252
- const user = this.auth.currentUser;
253
- if (!user) {
254
- throw new Error("No current user");
255
- }
256
- return firebaseAuth2.updatePassword(user, newPassword);
257
- }
258
- onAuthStateChanged(callback) {
259
- if (typeof window === "undefined") {
260
- return () => {
261
- };
262
- }
263
- let unsubscriber = null;
264
- this.ensureInitialized().then(async () => {
265
- const { firebaseAuth: firebaseAuth2 } = await getFirebaseModules();
266
- unsubscriber = firebaseAuth2.onAuthStateChanged(this.auth, (user) => {
267
- if (user && user.emailVerified) {
268
- const userData = this.transformUserData(user);
269
- callback(userData);
270
- } else {
271
- callback(null);
272
- }
273
- });
274
- });
275
- return () => {
276
- if (unsubscriber) {
277
- unsubscriber();
278
- }
279
- };
280
- }
281
- getCurrentUser() {
282
- if (typeof window === "undefined" || !this.initialized) {
283
- return null;
284
- }
285
- const user = this.auth.currentUser;
286
- if (user && user.emailVerified) {
287
- return this.transformUserData(user);
288
- }
289
- return null;
290
- }
291
- };
292
- }
293
- });
294
-
295
- // src/modules/auth/services/authServiceFactory.ts
296
- var authServiceInstance, createAuthService, getAuthService, resetAuthService;
297
- var init_authServiceFactory = __esm({
298
- "src/modules/auth/services/authServiceFactory.ts"() {
299
- "use strict";
300
- init_FirebaseAuthService();
301
- authServiceInstance = null;
302
- createAuthService = (config) => {
303
- if (!authServiceInstance) {
304
- authServiceInstance = new FirebaseAuthService(config.firebaseConfig);
305
- }
306
- return authServiceInstance;
307
- };
308
- getAuthService = () => {
309
- return authServiceInstance;
310
- };
311
- resetAuthService = () => {
312
- authServiceInstance = null;
313
- };
314
- }
315
- });
316
-
317
- // src/modules/auth/services/index.ts
318
- var services_exports = {};
319
- __export(services_exports, {
320
- FirebaseAuthService: () => FirebaseAuthService,
321
- createAuthService: () => createAuthService,
322
- getAuthService: () => getAuthService,
323
- resetAuthService: () => resetAuthService
324
- });
325
- var init_services = __esm({
326
- "src/modules/auth/services/index.ts"() {
327
- "use strict";
328
- init_FirebaseAuthService();
329
- init_authServiceFactory();
330
- }
331
- });
332
18
 
333
19
  // src/index.ts
334
20
  var index_exports = {};
335
21
  __export(index_exports, {
22
+ ALLOWED_ORIGINS: () => ALLOWED_ORIGINS,
336
23
  AchievementRuleActionType: () => AchievementRuleActionType,
337
24
  AchievementServiceProvider: () => AchievementServiceProvider,
338
25
  AchievementType: () => AchievementType,
339
26
  AuthProvider: () => AuthProvider,
27
+ CALLBACK_URL: () => CALLBACK_URL,
340
28
  CampaignState: () => CampaignState,
341
29
  CmentityRewardType: () => CmentityRewardType,
342
30
  NotificationProvider: () => NotificationProvider,
@@ -349,7 +37,6 @@ __export(index_exports, {
349
37
  chipAuthTokenKey: () => chipAuthTokenKey,
350
38
  cn: () => cn,
351
39
  convertSnakeToCamel: () => convertSnakeToCamel,
352
- createRefreshTokenFunction: () => createRefreshTokenFunction,
353
40
  deviceUIDKey: () => deviceUIDKey,
354
41
  fileToBase64: () => fileToBase64,
355
42
  filterLocationsByProperty: () => filterLocationsByProperty,
@@ -390,18 +77,22 @@ __export(index_exports, {
390
77
  useChipScanStory: () => useChipScanStory,
391
78
  useClaimUserReward: () => useClaimUserReward,
392
79
  useClearUserRewardCache: () => useClearUserRewardCache,
80
+ useCreateCertificate: () => useCreateCertificate,
81
+ useCreateCertificateAnonymous: () => useCreateCertificateAnonymous,
82
+ useCreateCertificateWithMask: () => useCreateCertificateWithMask,
393
83
  useCreateMemory: () => useCreateMemory,
394
84
  useCreateModelGroupReward: () => useCreateModelGroupReward,
395
- useCreateRewardModel: () => useApiCreateRewardModel,
85
+ useCreateRewardModel: () => useCreateRewardModel,
396
86
  useDataTracking: () => useDataTracking,
397
- useDeleteRewardModel: () => useApiDeleteRewardModel,
87
+ useDeleteRewardModel: () => useDeleteRewardModel,
398
88
  useGenerateFansipanCertificate: () => useGenerateFansipanCertificate,
399
89
  useGenerateTemplateCertificate: () => useGenerateTemplateCertificate,
400
90
  useGenerateThaocamvienCertificate: () => useGenerateThaocamvienCertificate,
401
- useGetRewardModel: () => useApiGetRewardModel,
91
+ useGetRewardModel: () => useGetRewardModel,
402
92
  useGetUserRewards: () => useGetUserRewards,
93
+ useGoogleLogin: () => useGoogleLogin,
403
94
  useInfiniteMemories: () => useInfiniteMemories,
404
- useListRewardModels: () => useApiListRewardModels,
95
+ useListRewardModels: () => useListRewardModels,
405
96
  useLocationDetail: () => useOneLocation,
406
97
  useLocationProgress: () => useUserCampaignsCompletedLocation,
407
98
  useLocationsList: () => useManyLocations,
@@ -416,17 +107,18 @@ __export(index_exports, {
416
107
  useOneAchievement: () => useOneAchievement,
417
108
  useOneMemory: () => useOneMemory,
418
109
  useOneUserCampaign: () => useOneUserCampaign,
419
- usePGLCoreService: () => usePGLCoreService,
110
+ usePGLCoreService: () => usePGLCoreService2,
420
111
  useScanChip: () => useScanChip,
421
112
  useSendEmail: () => useSendEmail,
422
113
  useSyncCheckin: () => useSyncCheckin,
423
114
  useUpdateMyProfile: () => useUpdateMyProfile,
424
- useUpdateRewardModel: () => useApiUpdateRewardModel,
115
+ useUpdateRewardModel: () => useUpdateRewardModel,
425
116
  useUploadMedia: () => useUploadMedia,
426
117
  useUserAchievementAction: () => useUserAchievementAction,
427
118
  useUserCampaignAction: () => useUserCampaignAction,
428
119
  useV1ListRewards: () => useV1ListRewards,
429
- userInfoKey: () => userInfoKey
120
+ userInfoKey: () => userInfoKey,
121
+ wrapTextWithFont: () => wrapTextWithFont
430
122
  });
431
123
 
432
124
  // src/modules/achievement/hooks/index.ts
@@ -565,15 +257,15 @@ import {
565
257
  useManyUserRewards,
566
258
  useGetUserRewards,
567
259
  useClaimUserReward,
568
- useApiListRewardModels,
569
- useApiGetRewardModel,
570
- useApiCreateRewardModel,
571
- useApiUpdateRewardModel,
572
- useApiDeleteRewardModel,
260
+ useListRewardModels,
261
+ useGetRewardModel,
262
+ useCreateRewardModel,
263
+ useUpdateRewardModel,
264
+ useDeleteRewardModel,
573
265
  useCreateModelGroupReward,
574
266
  useClearUserRewardCache,
575
267
  useV1ListRewards
576
- } from "@phygitallabs/reward/src/hooks";
268
+ } from "@phygitallabs/reward";
577
269
 
578
270
  // src/modules/reward/types/enums.ts
579
271
  import {
@@ -642,8 +334,8 @@ var NotificationProvider = ({
642
334
  return /* @__PURE__ */ jsx(
643
335
  NotificationProviderApi,
644
336
  {
645
- userUid: user.id,
646
- accessToken: user.accessToken,
337
+ userUid: user?.id,
338
+ accessToken: user?.accessToken ?? null,
647
339
  webSocketUrl,
648
340
  autoConnect,
649
341
  onWebSocketOpen,
@@ -661,69 +353,774 @@ __reExport(index_exports, notification_exports);
661
353
  import { useOneMemory, useManyMemory, useInfiniteMemories, useCreateMemory, useUploadMedia, resetMemoriesQuery, memoriesKey } from "@phygitallabs/api-core";
662
354
 
663
355
  // src/modules/auth/providers/AuthProvider.tsx
664
- import { createContext, useEffect, useContext } from "react";
356
+ import {
357
+ AuthenticationProvider,
358
+ useAuthenticationHeaders,
359
+ tokenStorage as tokenStorage3
360
+ } from "@phygitallabs/authentication";
361
+ import { useEffect } from "react";
665
362
 
666
- // src/store/hooks.ts
667
- import { useDispatch, useSelector } from "react-redux";
668
- var useAppDispatch = () => useDispatch();
669
- var useAppSelector = useSelector;
363
+ // src/modules/auth/store/authStore.ts
364
+ import { create } from "zustand";
365
+ import { immer } from "zustand/middleware/immer";
366
+ import {
367
+ createJSONStorage,
368
+ devtools,
369
+ persist,
370
+ subscribeWithSelector
371
+ } from "zustand/middleware";
372
+ import {
373
+ authService,
374
+ verifyCodeService,
375
+ tokenStorage
376
+ } from "@phygitallabs/authentication";
670
377
 
671
- // src/modules/auth/store/authSlice.ts
672
- import { createSlice } from "@reduxjs/toolkit";
378
+ // src/modules/auth/constants/index.ts
379
+ var userInfoKey = "phygital-user-info";
380
+ var accessTokenKey = "accessToken";
381
+ var refreshTokenKey = "refreshToken";
382
+ var httpMaxRetries = 3;
383
+ var retryAttemptsRefreshToken = "retryAttemptsRefreshToken";
384
+ var deviceUIDKey = "Device-UID";
385
+ var chipAuthTokenKey = "chip-auth-token";
386
+ var CALLBACK_URL = "https://s3-sgn10.fptcloud.com/nomion-assets/platform/callback.html";
387
+ var ALLOWED_ORIGINS = [
388
+ "https://s3-sgn10.fptcloud.com",
389
+ "https://accounts.google.com/"
390
+ ];
673
391
 
674
- // src/modules/auth/helpers/index.ts
675
- init_constants();
676
- import { v4 as uuidv4 } from "uuid";
392
+ // src/modules/auth/store/authStore.ts
393
+ var initialState = {
394
+ user: null,
395
+ isSignedIn: false,
396
+ isInitialized: false,
397
+ isLoading: false,
398
+ error: null,
399
+ cleanupFunctions: {},
400
+ eventCallbacks: {}
401
+ };
402
+ var useAuthStore = create()(
403
+ devtools(
404
+ persist(
405
+ subscribeWithSelector(
406
+ immer((set, get) => ({
407
+ ...initialState,
408
+ actions: {
409
+ setIsLoading: (isLoading) => set((state) => {
410
+ state.isLoading = isLoading;
411
+ }),
412
+ setCleanupFunctions: (newCleanupFunctions) => set((state) => {
413
+ state.cleanupFunctions = {
414
+ ...state.cleanupFunctions,
415
+ ...newCleanupFunctions
416
+ };
417
+ }),
418
+ // Event management
419
+ addEventCallbacks: (callbacks) => {
420
+ set((state) => {
421
+ state.eventCallbacks = {
422
+ ...state.eventCallbacks,
423
+ ...callbacks
424
+ };
425
+ });
426
+ return () => {
427
+ set((state) => {
428
+ state.eventCallbacks = {
429
+ ...state.eventCallbacks,
430
+ ...callbacks
431
+ };
432
+ });
433
+ };
434
+ },
435
+ // Sign in with email and password
436
+ signInWithEmail: async (email, password) => {
437
+ const { eventCallbacks } = get();
438
+ set((state) => {
439
+ state.isLoading = true;
440
+ state.error = null;
441
+ });
442
+ try {
443
+ const response = await authService.signIn({
444
+ email,
445
+ password
446
+ });
447
+ if (response?.data?.idToken && response?.data?.refreshToken) {
448
+ tokenStorage.setTokens({
449
+ idToken: response.data.idToken,
450
+ refreshToken: response.data.refreshToken
451
+ });
452
+ set((state) => {
453
+ state.isSignedIn = true;
454
+ });
455
+ eventCallbacks.onLoginSuccess?.(response.data.idToken);
456
+ }
457
+ return response;
458
+ } catch (error) {
459
+ if (error?.response?.data?.code === 7) {
460
+ return {
461
+ data: void 0,
462
+ message: "Email verification required",
463
+ code: 7
464
+ };
465
+ }
466
+ const errorMessage = error instanceof Error ? error.message : "Login failed";
467
+ set((state) => {
468
+ state.error = errorMessage;
469
+ });
470
+ eventCallbacks.onLoginError?.(new Error(errorMessage));
471
+ throw error;
472
+ } finally {
473
+ set((state) => {
474
+ state.isLoading = false;
475
+ });
476
+ }
477
+ },
478
+ // Sign in with Google
479
+ signInWithGoogle: async () => {
480
+ const { eventCallbacks } = get();
481
+ try {
482
+ const currentDomain = CALLBACK_URL;
483
+ const userData = await authService.getOAuthSignInUrl(currentDomain);
484
+ return userData;
485
+ } catch (error) {
486
+ const errorMessage = error instanceof Error ? error.message : "Google sign in failed";
487
+ set((state) => {
488
+ state.error = errorMessage;
489
+ });
490
+ eventCallbacks.onLoginError?.(new Error(errorMessage));
491
+ throw error;
492
+ }
493
+ },
494
+ // Sign up with email and password
495
+ signUpWithEmail: async (email, password) => {
496
+ const { eventCallbacks } = get();
497
+ set((state) => {
498
+ state.isLoading = true;
499
+ state.error = null;
500
+ });
501
+ try {
502
+ const response = await authService.signUp({
503
+ email,
504
+ password
505
+ });
506
+ if (response.data) {
507
+ eventCallbacks.onSignupSuccess?.();
508
+ }
509
+ return response;
510
+ } catch (error) {
511
+ const errorMessage = error instanceof Error ? error.message : "Signup failed";
512
+ set((state) => {
513
+ state.error = errorMessage;
514
+ });
515
+ eventCallbacks.onSignupError?.(new Error(errorMessage));
516
+ throw error;
517
+ } finally {
518
+ set((state) => {
519
+ state.isLoading = false;
520
+ state.user = null;
521
+ state.isSignedIn = false;
522
+ });
523
+ }
524
+ },
525
+ // Sign out
526
+ signOut: async () => {
527
+ const { eventCallbacks, cleanupFunctions } = get();
528
+ set((state) => {
529
+ state.isLoading = true;
530
+ state.error = null;
531
+ });
532
+ try {
533
+ set((state) => {
534
+ state.user = null;
535
+ state.isSignedIn = false;
536
+ state.error = null;
537
+ });
538
+ const isTokenExpired = tokenStorage.isTokenExpired();
539
+ if (isTokenExpired) {
540
+ tokenStorage.clearTokens();
541
+ localStorage.clear();
542
+ return;
543
+ }
544
+ await authService.logout();
545
+ localStorage.clear();
546
+ tokenStorage.clearTokens();
547
+ try {
548
+ cleanupFunctions.clearQueryCache?.();
549
+ cleanupFunctions.clearOrganization?.();
550
+ cleanupFunctions.clearCustomData?.();
551
+ cleanupFunctions.clearHeaders?.();
552
+ } catch (cleanupError) {
553
+ console.warn("Error during logout cleanup:", cleanupError);
554
+ }
555
+ eventCallbacks.onLogoutSuccess?.();
556
+ } catch (error) {
557
+ console.log(error);
558
+ const errorMessage = error instanceof Error ? error.message : "Logout failed";
559
+ set((state) => {
560
+ state.error = errorMessage;
561
+ });
562
+ eventCallbacks.onLogoutError?.(new Error(errorMessage));
563
+ throw error;
564
+ } finally {
565
+ set((state) => {
566
+ state.isLoading = false;
567
+ });
568
+ }
569
+ },
570
+ // Send password reset email
571
+ sendPasswordResetEmail: async (email) => {
572
+ set((state) => {
573
+ state.isLoading = true;
574
+ state.error = null;
575
+ });
576
+ try {
577
+ await verifyCodeService.forgotPassword({
578
+ email
579
+ });
580
+ } catch (error) {
581
+ const errorMessage = error instanceof Error ? error.message : "Failed to send reset email";
582
+ set((state) => {
583
+ state.error = errorMessage;
584
+ });
585
+ throw error;
586
+ } finally {
587
+ set((state) => {
588
+ state.isLoading = false;
589
+ });
590
+ }
591
+ },
592
+ resetPassword: async (data) => {
593
+ set((state) => {
594
+ state.isLoading = true;
595
+ state.error = null;
596
+ });
597
+ try {
598
+ const resetPasswordResponse = await verifyCodeService.resetPassword(data);
599
+ return resetPasswordResponse;
600
+ } catch (error) {
601
+ const errorMessage = error instanceof Error ? error.message : "Failed to reset password";
602
+ set((state) => {
603
+ state.error = errorMessage;
604
+ });
605
+ throw error;
606
+ } finally {
607
+ set((state) => {
608
+ state.isLoading = false;
609
+ });
610
+ }
611
+ },
612
+ changePassword: async (data) => {
613
+ set((state) => {
614
+ state.isLoading = true;
615
+ state.error = null;
616
+ });
617
+ try {
618
+ const changePasswordResponse = await verifyCodeService.changePassword(data);
619
+ return changePasswordResponse;
620
+ } catch (error) {
621
+ throw error;
622
+ } finally {
623
+ set((state) => {
624
+ state.isLoading = false;
625
+ });
626
+ }
627
+ },
628
+ verifyEmailCode: async (data) => {
629
+ set((state) => {
630
+ state.isLoading = true;
631
+ state.error = null;
632
+ });
633
+ try {
634
+ const verifyEmailResponse = await verifyCodeService.verifyEmail(data);
635
+ return verifyEmailResponse;
636
+ } catch (error) {
637
+ const errorMessage = error instanceof Error ? error.message : "Failed to send reset email";
638
+ set((state) => {
639
+ state.error = errorMessage;
640
+ });
641
+ throw error;
642
+ } finally {
643
+ set((state) => {
644
+ state.isLoading = false;
645
+ });
646
+ }
647
+ },
648
+ sendVerifyCode: async (data) => {
649
+ set((state) => {
650
+ state.isLoading = true;
651
+ state.error = null;
652
+ });
653
+ try {
654
+ const sendVerifyCodeResponse = await verifyCodeService.sendVerifyCode(data);
655
+ return sendVerifyCodeResponse;
656
+ } catch (error) {
657
+ const errorMessage = error instanceof Error ? error.message : "Failed to send verify code";
658
+ set((state) => {
659
+ state.error = errorMessage;
660
+ });
661
+ throw error;
662
+ } finally {
663
+ set((state) => {
664
+ state.isLoading = false;
665
+ });
666
+ }
667
+ },
668
+ refreshToken: async (refreshToken) => {
669
+ const refreshTokenResponse = await authService.refreshToken({
670
+ refreshToken: refreshToken ?? tokenStorage.getRefreshToken() ?? ""
671
+ });
672
+ return refreshTokenResponse;
673
+ },
674
+ // Clear error
675
+ clearError: () => set((state) => {
676
+ state.error = null;
677
+ }),
678
+ setUser: (user) => set((state) => {
679
+ state.user = user;
680
+ }),
681
+ setIsSignedIn: (isSignedIn) => set((state) => {
682
+ state.isSignedIn = isSignedIn;
683
+ }),
684
+ setIsInitialized: (isInitialized) => set((state) => {
685
+ state.isInitialized = isInitialized;
686
+ }),
687
+ patchUser: (user) => set((state) => {
688
+ if (state.user) {
689
+ state.user = { ...state.user, ...user };
690
+ } else {
691
+ state.user = user;
692
+ }
693
+ }),
694
+ // Initialize the store - check if user is already authenticated from tokenStorage
695
+ initialize: () => {
696
+ set((state) => {
697
+ const token = tokenStorage.getAuthToken();
698
+ state.isSignedIn = !!token;
699
+ state.isInitialized = true;
700
+ });
701
+ },
702
+ // Sync auth state from tokenStorage (called when axios interceptor updates tokens)
703
+ syncAuthState: () => {
704
+ set((state) => {
705
+ const token = tokenStorage.getAuthToken();
706
+ const wasSignedIn = state.isSignedIn;
707
+ state.isSignedIn = !!token;
708
+ if (wasSignedIn !== state.isSignedIn) {
709
+ if (state.isSignedIn) {
710
+ state.eventCallbacks?.onAuthStateChange?.(state.user, true);
711
+ } else {
712
+ state.eventCallbacks?.onAuthStateChange?.(null, false);
713
+ }
714
+ }
715
+ });
716
+ }
717
+ }
718
+ }))
719
+ ),
720
+ {
721
+ version: 1,
722
+ name: "auth-store",
723
+ storage: createJSONStorage(() => localStorage),
724
+ partialize: (state) => ({
725
+ isSignedIn: state.isSignedIn,
726
+ user: state.user
727
+ })
728
+ }
729
+ )
730
+ )
731
+ );
732
+ var useAuth = () => {
733
+ const user = useAuthStore((state) => state.user);
734
+ const isSignedIn = useAuthStore((state) => state.isSignedIn);
735
+ const isInitialized = useAuthStore((state) => state.isInitialized);
736
+ const isLoading = useAuthStore((state) => state.isLoading);
737
+ const error = useAuthStore((state) => state.error);
738
+ const actions = useAuthStore((state) => state.actions);
739
+ return {
740
+ user,
741
+ isSignedIn,
742
+ isInitialized,
743
+ isLoading,
744
+ error,
745
+ ...actions
746
+ };
747
+ };
677
748
 
678
- // src/modules/auth/helpers/refreshToken.ts
679
- import mem from "mem";
680
- var REFRESH_TOKEN_CONFIG = {
681
- maxAge: 1e4
682
- // 10 seconds cache
749
+ // src/modules/auth/utils/user.ts
750
+ import jwtDecode from "jwt-decode";
751
+ var transformProtoUserData = (user, accessToken) => {
752
+ const userData = { ...user };
753
+ let tokenDecoded = {};
754
+ try {
755
+ tokenDecoded = jwtDecode(accessToken);
756
+ } catch (error) {
757
+ console.warn("Failed to decode token in transformUserData:", error);
758
+ }
759
+ userData.exp = tokenDecoded.exp || 0;
760
+ userData.accessToken = accessToken || "";
761
+ userData.roles = tokenDecoded?.roles || ["USER" /* USER */];
762
+ userData.account_type = tokenDecoded?.account_type || 0 /* C */;
763
+ userData.picture = user.picture || "";
764
+ return userData;
683
765
  };
684
- var createRefreshTokenFunction = (config) => {
685
- const refreshTokenFn = async () => {
766
+
767
+ // src/modules/auth/providers/AuthProvider.tsx
768
+ import { userService } from "@phygitallabs/api-core";
769
+ import { usePGLCoreService } from "@phygitallabs/api-core";
770
+ import { useAchievementService } from "@phygitallabs/achievement";
771
+ import { useRewardService } from "@phygitallabs/reward";
772
+ import { useGenerateCertificateService } from "@phygitallabs/generate-certificate";
773
+
774
+ // src/modules/auth/hooks/useTokenRefresher.ts
775
+ import { useQuery } from "@tanstack/react-query";
776
+ import { tokenStorage as tokenStorage2 } from "@phygitallabs/authentication";
777
+ function useTokenRefresher() {
778
+ const { refreshToken, signOut } = useAuth();
779
+ const handleRefreshToken = async () => {
686
780
  try {
687
- const session = getUserInfo();
688
- const refreshToken = getRefreshToken();
689
- if (!refreshToken) {
690
- removeUserInfo();
781
+ const isTokenExpired = tokenStorage2.isTokenExpired();
782
+ if (!isTokenExpired) {
691
783
  return;
692
784
  }
693
- const params = new URLSearchParams();
694
- params.append("grant_type", "refresh_token");
695
- params.append("refresh_token", refreshToken);
696
- const fetchData = {
697
- method: "POST",
698
- headers: new Headers({
699
- "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
700
- }),
701
- body: params
702
- };
703
- const response = await fetch(
704
- `https://securetoken.googleapis.com/v1/token?key=${config.firebaseApiKey}`,
705
- fetchData
785
+ const newToken = await refreshToken();
786
+ if (newToken.data?.idToken && newToken.data?.refreshToken) {
787
+ tokenStorage2.setTokens({
788
+ idToken: newToken.data?.idToken,
789
+ refreshToken: newToken.data?.refreshToken
790
+ });
791
+ }
792
+ } catch (error) {
793
+ console.error("Failed to refresh token:", error);
794
+ signOut();
795
+ }
796
+ };
797
+ useQuery({
798
+ queryKey: ["refresh-token"],
799
+ queryFn: () => handleRefreshToken(),
800
+ refetchInterval: 30 * 60 * 1e3,
801
+ // every 30 minutes
802
+ refetchIntervalInBackground: false,
803
+ // even when tab is hidden
804
+ refetchOnWindowFocus: true,
805
+ // also refresh when user returns to tab
806
+ retry: false,
807
+ // don't retry repeatedly if refresh fails
808
+ enabled: !!tokenStorage2.getAuthToken()
809
+ // only run if logged in
810
+ });
811
+ }
812
+
813
+ // src/modules/auth/providers/AuthProvider.tsx
814
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
815
+ var AuthStateManager = () => {
816
+ const { updateHeaders } = useAuthenticationHeaders();
817
+ const { updateHeaders: updateHeadersPGL, coreApi } = usePGLCoreService();
818
+ const { updateHeaders: updateHeadersAchievement } = useAchievementService();
819
+ const { updateHeaders: updateHeadersReward } = useRewardService();
820
+ const { updateHeaders: updateHeadersGenerateCertificate } = useGenerateCertificateService();
821
+ useEffect(() => {
822
+ useAuthStore.getState().actions.initialize();
823
+ const token = tokenStorage3.getAuthToken();
824
+ if (token) {
825
+ updateHeaders({
826
+ Authorization: `Bearer ${token}`
827
+ });
828
+ updateHeadersPGL({
829
+ Authorization: `Bearer ${token}`
830
+ });
831
+ updateHeadersAchievement({
832
+ Authorization: `Bearer ${token}`
833
+ });
834
+ updateHeadersReward({
835
+ Authorization: `Bearer ${token}`
836
+ });
837
+ updateHeadersGenerateCertificate({
838
+ Authorization: `Bearer ${token}`
839
+ });
840
+ const { user } = useAuthStore.getState();
841
+ if (user && user.accessToken !== token) {
842
+ useAuthStore.getState().actions.setUser({
843
+ ...user,
844
+ accessToken: token
845
+ });
846
+ }
847
+ }
848
+ let previousIsSignedIn = useAuthStore.getState().isSignedIn;
849
+ const unsub = useAuthStore.subscribe(
850
+ (state) => [state.isSignedIn, state.user],
851
+ async ([isSignedIn]) => {
852
+ if (isSignedIn === previousIsSignedIn) {
853
+ return;
854
+ }
855
+ previousIsSignedIn = isSignedIn;
856
+ if (isSignedIn) {
857
+ const token2 = tokenStorage3.getAuthToken();
858
+ if (token2) {
859
+ updateHeaders({
860
+ Authorization: `Bearer ${token2}`
861
+ });
862
+ updateHeadersPGL({
863
+ Authorization: `Bearer ${token2}`
864
+ });
865
+ updateHeadersAchievement({
866
+ Authorization: `Bearer ${token2}`
867
+ });
868
+ updateHeadersReward({
869
+ Authorization: `Bearer ${token2}`
870
+ });
871
+ updateHeadersGenerateCertificate({
872
+ Authorization: `Bearer ${token2}`
873
+ });
874
+ try {
875
+ const userApi = userService(coreApi);
876
+ const userProfile = await userApi.getMyProfile();
877
+ const transformedUserData = transformProtoUserData(
878
+ userProfile,
879
+ token2
880
+ );
881
+ useAuthStore.getState().actions.setUser(transformedUserData);
882
+ } catch (error) {
883
+ useAuthStore.getState().actions.signOut();
884
+ }
885
+ }
886
+ const { eventCallbacks, user } = useAuthStore.getState();
887
+ eventCallbacks?.onAuthStateChange?.(user, true);
888
+ } else {
889
+ updateHeaders({});
890
+ updateHeadersPGL({});
891
+ updateHeadersAchievement({
892
+ Authorization: ``
893
+ });
894
+ updateHeadersReward({
895
+ Authorization: ``
896
+ });
897
+ updateHeadersGenerateCertificate({
898
+ Authorization: ``
899
+ });
900
+ const { eventCallbacks } = useAuthStore.getState();
901
+ eventCallbacks?.onAuthStateChange?.(null, false);
902
+ }
903
+ }
904
+ );
905
+ const unsubTokenChange = tokenStorage3.addTokenChangeListener(async () => {
906
+ const { isSignedIn, user } = useAuthStore.getState();
907
+ if (isSignedIn) {
908
+ const token2 = tokenStorage3.getAuthToken();
909
+ if (token2) {
910
+ updateHeaders({
911
+ Authorization: `Bearer ${token2}`
912
+ });
913
+ updateHeadersPGL({
914
+ Authorization: `Bearer ${token2}`
915
+ });
916
+ updateHeadersAchievement({
917
+ Authorization: `Bearer ${token2}`
918
+ });
919
+ updateHeadersReward({
920
+ Authorization: `Bearer ${token2}`
921
+ });
922
+ updateHeadersGenerateCertificate({
923
+ Authorization: `Bearer ${token2}`
924
+ });
925
+ if (user && user.accessToken !== token2) {
926
+ useAuthStore.getState().actions.setUser({
927
+ ...user,
928
+ accessToken: token2
929
+ });
930
+ }
931
+ } else {
932
+ useAuthStore.getState().actions.signOut();
933
+ updateHeaders({});
934
+ updateHeadersPGL({});
935
+ updateHeadersAchievement({
936
+ Authorization: ``
937
+ });
938
+ updateHeadersReward({
939
+ Authorization: ``
940
+ });
941
+ updateHeadersGenerateCertificate({
942
+ Authorization: ``
943
+ });
944
+ }
945
+ }
946
+ });
947
+ return () => {
948
+ unsub();
949
+ unsubTokenChange();
950
+ };
951
+ }, [
952
+ updateHeaders,
953
+ updateHeadersPGL,
954
+ updateHeadersAchievement,
955
+ updateHeadersReward,
956
+ updateHeadersGenerateCertificate,
957
+ coreApi
958
+ ]);
959
+ return null;
960
+ };
961
+ var TokenRefresher = () => {
962
+ useTokenRefresher();
963
+ return null;
964
+ };
965
+ var AuthProvider = ({
966
+ children,
967
+ baseURL,
968
+ queryClient
969
+ }) => {
970
+ const axiosConfig = {
971
+ headers: {
972
+ "Content-Type": "application/json"
973
+ }
974
+ };
975
+ return /* @__PURE__ */ jsxs(
976
+ AuthenticationProvider,
977
+ {
978
+ axiosConfig,
979
+ baseURL,
980
+ queryClient,
981
+ children: [
982
+ /* @__PURE__ */ jsx2(AuthStateManager, {}),
983
+ /* @__PURE__ */ jsx2(TokenRefresher, {}),
984
+ children
985
+ ]
986
+ }
987
+ );
988
+ };
989
+
990
+ // src/modules/auth/hooks/useGoogleLogin.ts
991
+ import { useRef, useCallback, useEffect as useEffect2 } from "react";
992
+ import { tokenStorage as tokenStorage4 } from "@phygitallabs/authentication";
993
+ function useGoogleLogin(options = {}) {
994
+ const { onSuccess, onError, onPopupBlocked, onPopupClosed } = options;
995
+ const { signInWithGoogle, refreshToken, setIsSignedIn, setIsLoading, isLoading } = useAuth();
996
+ const popupRef = useRef(null);
997
+ const gotDataRef = useRef(false);
998
+ const timerRef = useRef(null);
999
+ const errorRef = useRef(null);
1000
+ const handleTokenRefresh = useCallback(
1001
+ async (refresh) => {
1002
+ if (refresh) {
1003
+ try {
1004
+ const newToken = await refreshToken(refresh);
1005
+ if (newToken.data?.idToken && newToken.data?.refreshToken) {
1006
+ tokenStorage4.setTokens({
1007
+ idToken: newToken.data.idToken,
1008
+ refreshToken: newToken.data.refreshToken
1009
+ });
1010
+ setIsSignedIn(true);
1011
+ setIsLoading(false);
1012
+ onSuccess?.();
1013
+ }
1014
+ } catch (error) {
1015
+ const errorMessage = error instanceof Error ? error.message : "Token refresh failed";
1016
+ errorRef.current = errorMessage;
1017
+ onError?.(errorMessage);
1018
+ setIsLoading(false);
1019
+ }
1020
+ }
1021
+ },
1022
+ [refreshToken, setIsSignedIn, setIsLoading, onSuccess, onError]
1023
+ );
1024
+ const cleanup = useCallback(() => {
1025
+ if (timerRef.current) {
1026
+ clearInterval(timerRef.current);
1027
+ timerRef.current = null;
1028
+ }
1029
+ gotDataRef.current = false;
1030
+ }, []);
1031
+ const handleMessage = useCallback(
1032
+ (event) => {
1033
+ const allowedOrigins = ALLOWED_ORIGINS.concat(window?.location?.origin);
1034
+ if (event.origin !== "*" && !allowedOrigins.includes(event.origin)) {
1035
+ console.warn("Rejected message from untrusted origin:", event.origin);
1036
+ return;
1037
+ }
1038
+ if (!event.data || typeof event.data !== "object") {
1039
+ console.warn("Invalid message data received");
1040
+ return;
1041
+ }
1042
+ if (event.data.type === "LOGIN_SUCCESS") {
1043
+ const { refreshToken: refresh } = event.data;
1044
+ if (refresh) {
1045
+ handleTokenRefresh(refresh);
1046
+ }
1047
+ gotDataRef.current = true;
1048
+ cleanup();
1049
+ } else if (event.data.type === "LOGIN_ERROR") {
1050
+ const errorMessage = event.data.error || "Login failed";
1051
+ errorRef.current = errorMessage;
1052
+ onError?.(errorMessage);
1053
+ setIsLoading(false);
1054
+ gotDataRef.current = true;
1055
+ cleanup();
1056
+ }
1057
+ },
1058
+ [handleTokenRefresh, setIsLoading, cleanup, onError]
1059
+ );
1060
+ const signIn = useCallback(async () => {
1061
+ const width = 500;
1062
+ const height = 600;
1063
+ const left = window.screenX + (window.outerWidth - width) / 2;
1064
+ const top = window.screenY + (window.outerHeight - height) / 2;
1065
+ try {
1066
+ errorRef.current = null;
1067
+ setIsLoading(true);
1068
+ const response = await signInWithGoogle();
1069
+ popupRef.current = window.open(
1070
+ `${response.statusMessage}`,
1071
+ "oauthPopup",
1072
+ `width=${width},height=${height},left=${left},top=${top},resizable,scrollbars`
706
1073
  );
707
- const data = await response.json();
708
- if (data.error) {
709
- removeUserInfo();
1074
+ if (!popupRef.current) {
1075
+ setIsLoading(false);
1076
+ const error = "Popup blocked. Please allow popups for this site.";
1077
+ errorRef.current = error;
1078
+ onPopupBlocked?.();
1079
+ onError?.(error);
710
1080
  return;
711
1081
  }
712
- const newSession = {
713
- ...session,
714
- accessToken: data.access_token,
715
- refreshToken: data.refresh_token
716
- };
717
- setUserInfo(newSession);
718
- return newSession;
719
- } catch {
720
- removeUserInfo();
1082
+ timerRef.current = setInterval(() => {
1083
+ if (popupRef.current && popupRef.current.closed) {
1084
+ if (timerRef.current) {
1085
+ clearInterval(timerRef.current);
1086
+ timerRef.current = null;
1087
+ }
1088
+ if (!gotDataRef.current) {
1089
+ const error = "Authentication popup was closed";
1090
+ errorRef.current = error;
1091
+ onPopupClosed?.();
1092
+ onError?.(error);
1093
+ setIsLoading(false);
1094
+ }
1095
+ }
1096
+ }, 500);
1097
+ } catch (error) {
1098
+ const errorMessage = error instanceof Error ? error.message : "Google sign in failed";
1099
+ errorRef.current = errorMessage;
1100
+ onError?.(errorMessage);
1101
+ setIsLoading(false);
721
1102
  }
1103
+ }, [signInWithGoogle, setIsLoading, handleMessage, onError, onPopupBlocked, onPopupClosed]);
1104
+ useEffect2(() => {
1105
+ window.addEventListener("message", handleMessage);
1106
+ return () => {
1107
+ window.removeEventListener("message", handleMessage);
1108
+ };
1109
+ }, [handleMessage]);
1110
+ useEffect2(() => {
1111
+ return () => {
1112
+ cleanup();
1113
+ };
1114
+ }, [cleanup, handleMessage]);
1115
+ return {
1116
+ signIn,
1117
+ isLoading,
1118
+ error: errorRef.current
722
1119
  };
723
- return mem(refreshTokenFn, { maxAge: REFRESH_TOKEN_CONFIG.maxAge });
724
- };
1120
+ }
725
1121
 
726
1122
  // src/modules/auth/helpers/index.ts
1123
+ import { v4 as uuidv4 } from "uuid";
727
1124
  var generateDeviceId = async () => {
728
1125
  try {
729
1126
  const deviceFingerprint = await generateDeviceFingerprint();
@@ -838,208 +1235,6 @@ var removeUserInfo = () => {
838
1235
  localStorage.removeItem(userInfoKey);
839
1236
  };
840
1237
 
841
- // src/modules/auth/store/authSlice.ts
842
- var defaultUser = {
843
- uid: "",
844
- id: "",
845
- userName: "",
846
- displayName: "",
847
- avatar: "/images/default-avatar.jpg",
848
- email: "",
849
- exp: 0,
850
- emailVerified: false,
851
- refreshToken: "",
852
- accessToken: "",
853
- role: "NULL" /* NULL */,
854
- scanStatus: false
855
- };
856
- var initialState = {
857
- user: defaultUser,
858
- isSignedIn: false,
859
- pending: true
860
- };
861
- var authSlice = createSlice({
862
- name: "auth",
863
- initialState,
864
- reducers: {
865
- signIn: (state, action) => {
866
- const userData = action.payload;
867
- state.user = userData;
868
- state.isSignedIn = true;
869
- state.pending = false;
870
- setUserInfo(userData);
871
- setAccessToken(userData.accessToken);
872
- setRefreshToken(userData.refreshToken);
873
- },
874
- signOut: (state) => {
875
- state.user = defaultUser;
876
- state.isSignedIn = false;
877
- state.pending = false;
878
- removeUserInfo();
879
- removeAccessToken();
880
- removeRefreshToken();
881
- },
882
- updateScanStatus: (state, action) => {
883
- state.user.scanStatus = action.payload;
884
- setUserInfo(state.user);
885
- },
886
- refreshUser: (state, action) => {
887
- const userData = action.payload;
888
- if (userData) {
889
- state.user = userData;
890
- state.isSignedIn = true;
891
- state.pending = false;
892
- setUserInfo(userData);
893
- setAccessToken(userData.accessToken);
894
- setRefreshToken(userData.refreshToken);
895
- }
896
- },
897
- setPending: (state, action) => {
898
- state.pending = action.payload;
899
- },
900
- initializeFromStorage: (state) => {
901
- const storedUser = getUserInfo();
902
- const accessToken = getAccessToken();
903
- if (storedUser && accessToken) {
904
- state.user = storedUser;
905
- state.isSignedIn = true;
906
- }
907
- state.pending = false;
908
- }
909
- }
910
- });
911
- var {
912
- signIn,
913
- signOut,
914
- updateScanStatus,
915
- refreshUser,
916
- setPending,
917
- initializeFromStorage
918
- } = authSlice.actions;
919
- var selectUser = (state) => state.auth.user;
920
- var selectIsSignedIn = (state) => state.auth.isSignedIn;
921
- var selectIsLoading = (state) => state.auth.pending;
922
- var authSlice_default = authSlice.reducer;
923
-
924
- // src/modules/auth/providers/AuthProvider.tsx
925
- import { jsx as jsx2 } from "react/jsx-runtime";
926
- var AuthContext = createContext(null);
927
- function AuthProvider({ children, authService, authCallbacks }) {
928
- const dispatch = useAppDispatch();
929
- useEffect(() => {
930
- dispatch(initializeFromStorage());
931
- const unsubscribe = authService.onAuthStateChanged((user2) => {
932
- if (user2) {
933
- dispatch(signIn(user2));
934
- if (authCallbacks?.onUserIdentify && user2.email) {
935
- authCallbacks.onUserIdentify({
936
- email: user2.email,
937
- name: user2.displayName,
938
- avatar: user2.avatar,
939
- uid: user2.uid
940
- });
941
- }
942
- if (authCallbacks?.onSignInSuccess) {
943
- authCallbacks.onSignInSuccess(user2);
944
- }
945
- } else {
946
- dispatch(signOut());
947
- if (authCallbacks?.onTrackingReset) {
948
- authCallbacks.onTrackingReset();
949
- }
950
- }
951
- dispatch(setPending(false));
952
- });
953
- return () => {
954
- unsubscribe();
955
- };
956
- }, [authService, dispatch, authCallbacks]);
957
- const user = useAppSelector(selectUser);
958
- const isSignedIn = useAppSelector(selectIsSignedIn);
959
- const isLoading = useAppSelector(selectIsLoading);
960
- const signInWithCredential = async (email, password) => {
961
- const result = await authService.signInWithEmailAndPassword(email, password);
962
- if (result.data && authCallbacks?.onSignInSuccess) {
963
- authCallbacks.onSignInSuccess(result.data);
964
- } else if (result.errorCode && authCallbacks?.onSignInError) {
965
- authCallbacks.onSignInError(result.errorCode);
966
- }
967
- return result;
968
- };
969
- const signInWithGoogle = async () => {
970
- const result = await authService.signInWithGoogle();
971
- if (result.data && authCallbacks?.onSignInSuccess) {
972
- authCallbacks.onSignInSuccess(result.data);
973
- return result;
974
- } else if (result.errorCode && authCallbacks?.onSignInError) {
975
- authCallbacks.onSignInError(result.errorCode);
976
- }
977
- return null;
978
- };
979
- const signUp = async (email, password) => {
980
- const result = await authService.signUp(email, password);
981
- if (result.data && authCallbacks?.onSignUpSuccess) {
982
- authCallbacks.onSignUpSuccess(result.data);
983
- } else if (result.errorCode && authCallbacks?.onSignUpError) {
984
- authCallbacks.onSignUpError(result.errorCode);
985
- }
986
- return result;
987
- };
988
- const signOut2 = async () => {
989
- await authService.signOut();
990
- dispatch(signOut());
991
- if (authCallbacks?.onSignOutSuccess) {
992
- authCallbacks.onSignOutSuccess();
993
- }
994
- };
995
- const forgotPassword = async (email) => {
996
- return await authService.sendPasswordResetEmail(email);
997
- };
998
- const sendEmailVerification = async () => {
999
- return await authService.sendEmailVerification();
1000
- };
1001
- const changePassword = async (newPassword) => {
1002
- return await authService.changePassword(newPassword);
1003
- };
1004
- const updateScanStatus2 = (status) => {
1005
- dispatch(updateScanStatus(status));
1006
- };
1007
- const refreshUser2 = (userData) => {
1008
- dispatch(refreshUser(userData));
1009
- };
1010
- const contextValue = {
1011
- authService,
1012
- authCallbacks,
1013
- // User state
1014
- user,
1015
- isSignedIn,
1016
- isLoading,
1017
- // Auth actions
1018
- signInWithCredential,
1019
- signInWithGoogle,
1020
- signUp,
1021
- signOut: signOut2,
1022
- // Password actions
1023
- forgotPassword,
1024
- sendEmailVerification,
1025
- changePassword,
1026
- // User management
1027
- updateScanStatus: updateScanStatus2,
1028
- refreshUser: refreshUser2
1029
- };
1030
- return /* @__PURE__ */ jsx2(AuthContext.Provider, { value: contextValue, children });
1031
- }
1032
- var useAuth = () => {
1033
- const authContext = useContext(AuthContext);
1034
- if (!authContext) {
1035
- throw new Error("useAuth must be used within an AuthProvider");
1036
- }
1037
- return authContext;
1038
- };
1039
-
1040
- // src/modules/auth/index.ts
1041
- init_constants();
1042
-
1043
1238
  // src/modules/user-profile/hooks/index.ts
1044
1239
  import { useMyProfile, useUpdateMyProfile, useSyncCheckin, useCancelUserRewardsRequest } from "@phygitallabs/api-core";
1045
1240
 
@@ -1047,12 +1242,12 @@ import { useMyProfile, useUpdateMyProfile, useSyncCheckin, useCancelUserRewardsR
1047
1242
  import { UserSourceType } from "@phygitallabs/api-core";
1048
1243
 
1049
1244
  // src/modules/scan-chip/hooks/index.tsx
1050
- import { useEffect as useEffect2 } from "react";
1245
+ import { useEffect as useEffect3 } from "react";
1051
1246
  import { useChipScanStory } from "@phygitallabs/api-core";
1052
- import { usePGLCoreService } from "@phygitallabs/api-core";
1247
+ import { usePGLCoreService as usePGLCoreService2 } from "@phygitallabs/api-core";
1053
1248
  function useScanChip({ token, id, onScanChipError }) {
1054
- const { updateHeaders } = usePGLCoreService();
1055
- useEffect2(() => {
1249
+ const { updateHeaders } = usePGLCoreService2();
1250
+ useEffect3(() => {
1056
1251
  if (!!token) {
1057
1252
  const header = {
1058
1253
  "Chip-Authorization": token
@@ -1065,7 +1260,7 @@ function useScanChip({ token, id, onScanChipError }) {
1065
1260
  token,
1066
1261
  id
1067
1262
  });
1068
- useEffect2(() => {
1263
+ useEffect3(() => {
1069
1264
  if (isError) {
1070
1265
  onScanChipError?.();
1071
1266
  }
@@ -1138,11 +1333,172 @@ var filterLocationsByProperty = (locations, propertyName, value) => {
1138
1333
  import {
1139
1334
  useGenerateThaocamvienCertificate,
1140
1335
  useGenerateTemplateCertificate,
1141
- useGenerateFansipanCertificate
1336
+ useGenerateFansipanCertificate,
1337
+ useCreateCertificate,
1338
+ useCreateCertificateAnonymous,
1339
+ useCreateCertificateWithMask
1142
1340
  } from "@phygitallabs/generate-certificate";
1143
1341
 
1342
+ // src/modules/generate-certificate/helpers/index.ts
1343
+ import { wrapTextWithFont } from "@phygitallabs/generate-certificate";
1344
+
1144
1345
  // src/modules/data-tracking/hooks/index.ts
1145
1346
  import posthog from "posthog-js";
1347
+
1348
+ // src/modules/session-replay/providers/SessionReplayProvider.tsx
1349
+ import { createContext, useEffect as useEffect4, useReducer } from "react";
1350
+ import { v4 as uuidV4 } from "uuid";
1351
+
1352
+ // src/modules/session-replay/utils/index.ts
1353
+ var isBrowser = () => {
1354
+ return typeof window !== "undefined";
1355
+ };
1356
+
1357
+ // src/modules/session-replay/providers/SessionReplayProvider.tsx
1358
+ import { jsx as jsx3 } from "react/jsx-runtime";
1359
+ var TrackerContext = createContext(null);
1360
+ function defaultGetUserId() {
1361
+ return uuidV4();
1362
+ }
1363
+ async function newTracker(config) {
1364
+ try {
1365
+ const OpenReplay = (await import("@openreplay/tracker")).default;
1366
+ const getUserId = config?.userIdEnabled && config?.getUserId ? config.getUserId : defaultGetUserId;
1367
+ const trackerConfig = {
1368
+ projectKey: config?.projectKey || process.env.NEXT_PUBLIC_OPENREPLAY_PROJECT_KEY,
1369
+ ingestPoint: config?.ingestPoint,
1370
+ // Capture options
1371
+ captureExceptions: config.captureExceptions ?? true,
1372
+ capturePerformance: config.capturePerformance ?? true,
1373
+ // Network tracking
1374
+ network: config.network || {
1375
+ capturePayload: true,
1376
+ sanitizer: (data) => data
1377
+ },
1378
+ // Console tracking
1379
+ console: config.console || {
1380
+ levels: ["error", "warn", "log"]
1381
+ },
1382
+ // Privacy settings
1383
+ obscureTextEmails: config.obscureTextEmails ?? true,
1384
+ obscureTextNumbers: config.obscureTextNumbers ?? false,
1385
+ obscureInputEmails: config.obscureInputEmails ?? true,
1386
+ // Development mode
1387
+ __DISABLE_SECURE_MODE: config.__DISABLE_SECURE_MODE ?? (typeof process !== "undefined" && process.env?.NODE_ENV === "development")
1388
+ };
1389
+ const tracker = new OpenReplay(trackerConfig);
1390
+ if (config?.userIdEnabled) {
1391
+ const userId = getUserId();
1392
+ tracker.setUserID(userId);
1393
+ console.log("User ID set:", userId);
1394
+ }
1395
+ console.log("OpenReplay tracker initialized");
1396
+ console.log("Project Key:", trackerConfig.projectKey);
1397
+ console.log("Ingest Point:", trackerConfig.ingestPoint);
1398
+ return tracker;
1399
+ } catch (error) {
1400
+ console.error("Failed to create tracker:", error);
1401
+ throw error;
1402
+ }
1403
+ }
1404
+ function reducer(state, action) {
1405
+ const { debug = false } = state.config;
1406
+ switch (action.type) {
1407
+ case "init":
1408
+ if (!state.tracker && isBrowser()) {
1409
+ if (!state.config.projectKey && !process.env.NEXT_PUBLIC_OPENREPLAY_PROJECT_KEY) {
1410
+ console.warn(
1411
+ debug,
1412
+ "Project key not found. Skipping session replay initialization."
1413
+ );
1414
+ return state;
1415
+ }
1416
+ return {
1417
+ ...state,
1418
+ tracker: newTracker(state.config)
1419
+ };
1420
+ }
1421
+ return state;
1422
+ case "start":
1423
+ if (state.tracker) {
1424
+ Promise.resolve(state.tracker).then((tracker) => {
1425
+ tracker.start();
1426
+ console.log(debug, "Session replay tracker started");
1427
+ }).catch((error) => {
1428
+ console.error("Failed to start tracker:", error);
1429
+ });
1430
+ } else {
1431
+ console.warn(debug, "Tracker not initialized. Call initTracker() first.");
1432
+ }
1433
+ return state;
1434
+ case "setUserId":
1435
+ if (state.tracker) {
1436
+ Promise.resolve(state.tracker).then((tracker) => {
1437
+ tracker.setUserID(action.payload);
1438
+ console.log(debug, "User ID updated:", action.payload);
1439
+ }).catch((error) => {
1440
+ console.error("Failed to set user ID:", error);
1441
+ });
1442
+ } else {
1443
+ console.warn(debug, "Tracker not initialized. Call initTracker() first.");
1444
+ }
1445
+ return state;
1446
+ // Set metadata
1447
+ case "setMetadata":
1448
+ if (state.tracker) {
1449
+ Promise.resolve(state.tracker).then((tracker) => {
1450
+ Object.entries(action.payload || {})?.forEach(([key, value]) => {
1451
+ tracker.setMetadata(key, value);
1452
+ });
1453
+ console.log(debug, "Metadata updated:", action.payload.metadata);
1454
+ }).catch((error) => {
1455
+ console.error("Failed to set metadata:", error);
1456
+ });
1457
+ } else {
1458
+ console.warn(debug, "Tracker not initialized. Call initTracker() first.");
1459
+ }
1460
+ return state;
1461
+ default:
1462
+ return state;
1463
+ }
1464
+ }
1465
+ var SessionReplayProvider = ({
1466
+ children,
1467
+ config = {}
1468
+ }) => {
1469
+ const [, dispatch] = useReducer(reducer, {
1470
+ tracker: null,
1471
+ config
1472
+ });
1473
+ const initTracker = () => dispatch({ type: "init" });
1474
+ const startTracking = () => dispatch({ type: "start" });
1475
+ const setUserId = (userId) => dispatch({ type: "setUserId", payload: userId });
1476
+ const setMetadata = (metadata) => dispatch({ type: "setMetadata", payload: metadata });
1477
+ useEffect4(() => {
1478
+ initTracker();
1479
+ startTracking();
1480
+ }, []);
1481
+ return /* @__PURE__ */ jsx3(TrackerContext.Provider, { value: {
1482
+ initTracker,
1483
+ startTracking,
1484
+ setUserId,
1485
+ setMetadata
1486
+ }, children });
1487
+ };
1488
+
1489
+ // src/modules/session-replay/hooks/useSessionReplay.ts
1490
+ import { useContext } from "react";
1491
+ function useSessionReplay() {
1492
+ const context = useContext(TrackerContext);
1493
+ if (!context) {
1494
+ throw new Error(
1495
+ "useSessionReplay must be used within a SessionReplayProvider. Make sure your component is wrapped with <SessionReplayProvider>."
1496
+ );
1497
+ }
1498
+ return context;
1499
+ }
1500
+
1501
+ // src/modules/data-tracking/hooks/index.ts
1146
1502
  var pushEventToDataLayer = (event, data) => {
1147
1503
  try {
1148
1504
  window.dataLayer = window.dataLayer || [];
@@ -1165,6 +1521,7 @@ var pushEventToPosthog = (eventName, eventData) => {
1165
1521
  posthog.capture(eventName, eventData);
1166
1522
  };
1167
1523
  function useDataTracking() {
1524
+ const { setUserId, setMetadata } = useSessionReplay();
1168
1525
  const trackEvent = (eventName, eventData, useTools) => {
1169
1526
  useTools = useTools || ["gtm"];
1170
1527
  if (useTools.includes("gtm") && typeof window !== "undefined") {
@@ -1177,91 +1534,58 @@ function useDataTracking() {
1177
1534
  pushEventToPosthog(eventName, eventData);
1178
1535
  }
1179
1536
  };
1537
+ const trackUserIdentify = (userInfo) => {
1538
+ posthog.identify(userInfo.email, {
1539
+ email: userInfo.email,
1540
+ name: userInfo.name,
1541
+ avatar: userInfo.avatar,
1542
+ uid: userInfo.uid
1543
+ });
1544
+ setUserId(userInfo.id);
1545
+ setMetadata({
1546
+ user_email: userInfo.email
1547
+ });
1548
+ };
1549
+ const trackLogoutEvent = () => {
1550
+ posthog.capture("user_signed_out");
1551
+ };
1180
1552
  return {
1181
- trackEvent
1553
+ trackEvent,
1554
+ trackUserIdentify,
1555
+ trackLogoutEvent
1182
1556
  };
1183
1557
  }
1184
1558
 
1185
1559
  // src/providers/TapquestCoreProvider.tsx
1186
- import { useState as useState2, useEffect as useEffect4 } from "react";
1187
- import { Provider } from "react-redux";
1188
- import { PersistGate } from "redux-persist/integration/react";
1560
+ import { useMemo } from "react";
1189
1561
 
1190
1562
  // src/providers/ServicesProvider.tsx
1191
- import { useEffect as useEffect3, useState, useMemo } from "react";
1563
+ import { useEffect as useEffect5, useState } from "react";
1192
1564
  import { PGLCoreServiceProvider } from "@phygitallabs/api-core";
1193
1565
  import { RewardServiceProvider } from "@phygitallabs/reward";
1194
1566
  import { AchievementServiceProvider as AchievementServiceProvider2 } from "@phygitallabs/achievement";
1195
1567
  import { GenerateCertificateServiceProvider } from "@phygitallabs/generate-certificate";
1196
- import axios from "axios";
1197
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
1568
+ import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
1198
1569
  var ServicesProvider = ({
1199
1570
  children,
1200
1571
  queryClient,
1201
1572
  apiConfig = {
1202
1573
  environment: "dev",
1203
1574
  version: "v1"
1204
- },
1205
- firebaseConfig
1575
+ }
1206
1576
  }) => {
1207
- const { refreshUser: refreshUser2, signOut: signOut2 } = useAuth();
1208
1577
  const { environment, version } = apiConfig;
1209
1578
  const [commonServiceConfig, setCommonServiceConfig] = useState(null);
1210
- const memoizedRefreshToken = useMemo(() => {
1211
- if (!firebaseConfig?.apiKey) {
1212
- console.warn("Firebase API key not provided, refresh token functionality will not work");
1213
- return null;
1214
- }
1215
- return createRefreshTokenFunction({
1216
- firebaseApiKey: firebaseConfig.apiKey
1217
- });
1218
- }, [firebaseConfig?.apiKey]);
1219
- useEffect3(() => {
1579
+ useEffect5(() => {
1220
1580
  const initClient = async () => {
1221
1581
  try {
1222
1582
  const deviceUid = await checkDeviceUid();
1223
1583
  const responseInterceptors = {
1224
1584
  onFulfilled: (response) => response,
1225
- onRejected: async (error) => {
1226
- const originalRequest = error.config;
1227
- if (error.response?.status === 401 && !originalRequest._retry) {
1228
- const retryAttempts = parseInt(
1229
- getRetryAttemptsRefreshToken() || "0",
1230
- 10
1231
- );
1232
- if (retryAttempts >= httpMaxRetries) {
1233
- await signOut2();
1234
- return Promise.reject(error);
1235
- }
1236
- setRetryAttemptsRefreshToken(`${retryAttempts + 1}`);
1237
- originalRequest._retry = true;
1238
- try {
1239
- if (!memoizedRefreshToken) {
1240
- await signOut2();
1241
- return Promise.reject(error);
1242
- }
1243
- const result = await memoizedRefreshToken();
1244
- if (result?.accessToken) {
1245
- originalRequest.headers["Authorization"] = `Bearer ${result.accessToken}`;
1246
- setRetryAttemptsRefreshToken("0");
1247
- refreshUser2(result);
1248
- return axios(originalRequest);
1249
- }
1250
- } catch (refreshError) {
1251
- console.log("Failed to refresh token:", refreshError);
1252
- }
1253
- }
1254
- return Promise.reject(error);
1255
- }
1585
+ onRejected: async (error) => Promise.reject(error)
1256
1586
  };
1257
1587
  const requestInterceptors = {
1258
- onFulfilled: (config2) => {
1259
- const currentToken = getAccessToken();
1260
- if (currentToken && !config2.headers.Authorization) {
1261
- config2.headers.Authorization = `Bearer ${currentToken}`;
1262
- }
1263
- return config2;
1264
- },
1588
+ onFulfilled: (config2) => config2,
1265
1589
  onRejected: (error) => Promise.reject(error)
1266
1590
  };
1267
1591
  const axiosConfig = {
@@ -1285,25 +1609,25 @@ var ServicesProvider = ({
1285
1609
  initClient();
1286
1610
  }, [queryClient]);
1287
1611
  if (!commonServiceConfig) {
1288
- return /* @__PURE__ */ jsx3(Fragment, {});
1612
+ return /* @__PURE__ */ jsx4(Fragment, {});
1289
1613
  }
1290
- return /* @__PURE__ */ jsx3(
1614
+ return /* @__PURE__ */ jsx4(
1291
1615
  PGLCoreServiceProvider,
1292
1616
  {
1293
1617
  ...commonServiceConfig,
1294
1618
  baseURL: `${service_default[environment].API_BASE_URL}/${version}`,
1295
1619
  baseCoreURL: `${service_default[environment].API_BASE_CORE_URL}/${version}`,
1296
- children: /* @__PURE__ */ jsx3(
1620
+ children: /* @__PURE__ */ jsx4(
1297
1621
  RewardServiceProvider,
1298
1622
  {
1299
1623
  ...commonServiceConfig,
1300
1624
  baseURL: `${service_default[environment].API_REWARD_URL}/v1`,
1301
- children: /* @__PURE__ */ jsx3(
1625
+ children: /* @__PURE__ */ jsx4(
1302
1626
  AchievementServiceProvider2,
1303
1627
  {
1304
1628
  ...commonServiceConfig,
1305
1629
  baseURL: `${service_default[environment].API_ACHIEVEMENT_URL}/${version}`,
1306
- children: /* @__PURE__ */ jsx3(
1630
+ children: /* @__PURE__ */ jsx4(
1307
1631
  GenerateCertificateServiceProvider,
1308
1632
  {
1309
1633
  ...commonServiceConfig,
@@ -1319,87 +1643,51 @@ var ServicesProvider = ({
1319
1643
  );
1320
1644
  };
1321
1645
 
1322
- // src/store/index.ts
1323
- import { configureStore } from "@reduxjs/toolkit";
1324
- import storage from "redux-persist/lib/storage";
1325
- import { persistReducer, persistStore } from "redux-persist";
1326
- var authPersistConfig = {
1327
- key: "tapquest-auth",
1328
- storage,
1329
- whitelist: ["user", "isSignedIn"]
1330
- // Only persist user and sign-in status
1331
- };
1332
- var persistedAuthReducer = persistReducer(authPersistConfig, authSlice.reducer);
1333
- var store = configureStore({
1334
- reducer: {
1335
- auth: persistedAuthReducer
1336
- },
1337
- middleware: (getDefaultMiddleware) => getDefaultMiddleware({
1338
- serializableCheck: {
1339
- // Ignore redux-persist actions
1340
- ignoredActions: [
1341
- "persist/FLUSH",
1342
- "persist/REHYDRATE",
1343
- "persist/PAUSE",
1344
- "persist/PERSIST",
1345
- "persist/PURGE",
1346
- "persist/REGISTER"
1347
- ]
1348
- }
1349
- })
1350
- });
1351
- var persistor = persistStore(store);
1352
-
1353
1646
  // src/providers/TapquestCoreProvider.tsx
1354
- import { jsx as jsx4 } from "react/jsx-runtime";
1647
+ import { jsx as jsx5 } from "react/jsx-runtime";
1355
1648
  var TapquestCoreProvider = ({
1356
1649
  children,
1357
1650
  queryClient,
1358
- apiConfig,
1359
- firebaseConfig,
1360
- authCallbacks
1651
+ apiConfig
1652
+ // authCallbacks
1361
1653
  }) => {
1362
- const [internalAuthService, setInternalAuthService] = useState2(null);
1363
- useEffect4(() => {
1364
- if (firebaseConfig && typeof window !== "undefined") {
1365
- Promise.resolve().then(() => (init_services(), services_exports)).then(({ createAuthService: createAuthService2 }) => {
1366
- try {
1367
- const authService = createAuthService2({ firebaseConfig });
1368
- setInternalAuthService(authService);
1369
- } catch (error) {
1370
- console.warn("Failed to create auth service from firebase config:", error);
1371
- setInternalAuthService(null);
1372
- }
1373
- }).catch((error) => {
1374
- console.warn("Failed to dynamically import auth services:", error);
1375
- setInternalAuthService(null);
1376
- });
1377
- } else {
1378
- setInternalAuthService(null);
1654
+ const { environment } = apiConfig;
1655
+ const sessionReplayConfig = useMemo(() => {
1656
+ const projectKey = process.env.NEXT_PUBLIC_OPENREPLAY_PROJECT_KEY;
1657
+ if (!projectKey) {
1658
+ return void 0;
1379
1659
  }
1380
- }, [firebaseConfig]);
1381
- return /* @__PURE__ */ jsx4(Provider, { store, children: /* @__PURE__ */ jsx4(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsx4(
1382
- AuthProvider,
1660
+ return {
1661
+ projectKey,
1662
+ ingestPoint: process.env.NEXT_PUBLIC_OPENREPLAY_INGEST_POINT,
1663
+ debug: process.env.NODE_ENV === "development",
1664
+ captureExceptions: true,
1665
+ capturePerformance: true,
1666
+ obscureTextEmails: true,
1667
+ obscureInputEmails: true
1668
+ };
1669
+ }, []);
1670
+ return /* @__PURE__ */ jsx5(SessionReplayProvider, { config: sessionReplayConfig, children: /* @__PURE__ */ jsx5(
1671
+ ServicesProvider,
1383
1672
  {
1384
- authService: internalAuthService,
1385
- authCallbacks,
1386
- children: /* @__PURE__ */ jsx4(
1387
- ServicesProvider,
1673
+ queryClient,
1674
+ apiConfig,
1675
+ children: /* @__PURE__ */ jsx5(
1676
+ AuthProvider,
1388
1677
  {
1678
+ baseURL: `${service_default[environment].API_BASE_URL}`,
1389
1679
  queryClient,
1390
- apiConfig,
1391
- firebaseConfig,
1392
1680
  children
1393
1681
  }
1394
1682
  )
1395
1683
  }
1396
- ) }) });
1684
+ ) });
1397
1685
  };
1398
1686
 
1399
1687
  // src/modules/achivementWithReward/hooks/achivementPlusRewardModel.ts
1400
1688
  import { useManyAchievements as useManyAchievements2 } from "@phygitallabs/achievement";
1401
1689
  import { useCreateModelGroupReward as useCreateModelGroupReward2 } from "@phygitallabs/reward/src/hooks/useGroupReward";
1402
- import { useEffect as useEffect5, useMemo as useMemo2 } from "react";
1690
+ import { useEffect as useEffect6, useMemo as useMemo2 } from "react";
1403
1691
  function buildMappedAchievements(achievements, groupRewardData) {
1404
1692
  if (!groupRewardData?.reward_models) return [];
1405
1693
  const rewardModels = groupRewardData.reward_models;
@@ -1438,7 +1726,7 @@ var useAchivementPlusRewardModel = ({ campaignId }) => {
1438
1726
  data: groupRewardModelsData,
1439
1727
  isPending: isPendingGroupRewardModels
1440
1728
  } = useCreateModelGroupReward2();
1441
- useEffect5(() => {
1729
+ useEffect6(() => {
1442
1730
  if (groupRewardIds.length > 0) {
1443
1731
  fetchGroupRewardModels({ group_reward_ids: groupRewardIds });
1444
1732
  }
@@ -1460,10 +1748,12 @@ import { useSendEmail } from "@phygitallabs/api-core";
1460
1748
  // src/helper/helpers.ts
1461
1749
  import { cn, parse, fileToBase64 } from "@phygitallabs/helpers";
1462
1750
  export {
1751
+ ALLOWED_ORIGINS,
1463
1752
  AchievementRuleActionType,
1464
1753
  AchievementServiceProvider,
1465
1754
  AchievementType,
1466
1755
  AuthProvider,
1756
+ CALLBACK_URL,
1467
1757
  CampaignState,
1468
1758
  CmentityRewardType,
1469
1759
  NotificationProvider,
@@ -1476,7 +1766,6 @@ export {
1476
1766
  chipAuthTokenKey,
1477
1767
  cn,
1478
1768
  convertSnakeToCamel,
1479
- createRefreshTokenFunction,
1480
1769
  deviceUIDKey,
1481
1770
  fileToBase64,
1482
1771
  filterLocationsByProperty,
@@ -1517,18 +1806,22 @@ export {
1517
1806
  useChipScanStory,
1518
1807
  useClaimUserReward,
1519
1808
  useClearUserRewardCache,
1809
+ useCreateCertificate,
1810
+ useCreateCertificateAnonymous,
1811
+ useCreateCertificateWithMask,
1520
1812
  useCreateMemory,
1521
1813
  useCreateModelGroupReward,
1522
- useApiCreateRewardModel as useCreateRewardModel,
1814
+ useCreateRewardModel,
1523
1815
  useDataTracking,
1524
- useApiDeleteRewardModel as useDeleteRewardModel,
1816
+ useDeleteRewardModel,
1525
1817
  useGenerateFansipanCertificate,
1526
1818
  useGenerateTemplateCertificate,
1527
1819
  useGenerateThaocamvienCertificate,
1528
- useApiGetRewardModel as useGetRewardModel,
1820
+ useGetRewardModel,
1529
1821
  useGetUserRewards,
1822
+ useGoogleLogin,
1530
1823
  useInfiniteMemories,
1531
- useApiListRewardModels as useListRewardModels,
1824
+ useListRewardModels,
1532
1825
  useOneLocation as useLocationDetail,
1533
1826
  useUserCampaignsCompletedLocation as useLocationProgress,
1534
1827
  useManyLocations as useLocationsList,
@@ -1543,16 +1836,17 @@ export {
1543
1836
  useOneAchievement,
1544
1837
  useOneMemory,
1545
1838
  useOneUserCampaign,
1546
- usePGLCoreService,
1839
+ usePGLCoreService2 as usePGLCoreService,
1547
1840
  useScanChip,
1548
1841
  useSendEmail,
1549
1842
  useSyncCheckin,
1550
1843
  useUpdateMyProfile,
1551
- useApiUpdateRewardModel as useUpdateRewardModel,
1844
+ useUpdateRewardModel,
1552
1845
  useUploadMedia,
1553
1846
  useUserAchievementAction,
1554
1847
  useUserCampaignAction,
1555
1848
  useV1ListRewards,
1556
- userInfoKey
1849
+ userInfoKey,
1850
+ wrapTextWithFont
1557
1851
  };
1558
1852
  //# sourceMappingURL=index.js.map