@passgage/sdk-react-native 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,11 +1,62 @@
1
+ import axios from 'axios';
2
+ import React, { createContext, useEffect, useContext, useState, useCallback } from 'react';
3
+ import { create } from 'zustand';
4
+ import * as Keychain from 'react-native-keychain';
5
+ import Geolocation2 from 'react-native-geolocation-service';
6
+ import RNPermissions, { PERMISSIONS, RESULTS, request } from 'react-native-permissions';
7
+ import { Platform } from 'react-native';
8
+ import NfcManager, { NfcTech } from 'react-native-nfc-manager';
9
+
1
10
  var __defProp = Object.defineProperty;
11
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
12
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
13
+ }) : x)(function(x) {
14
+ if (typeof require !== "undefined") return require.apply(this, arguments);
15
+ throw Error('Dynamic require of "' + x + '" is not supported');
16
+ });
2
17
  var __export = (target, all) => {
3
18
  for (var name in all)
4
19
  __defProp(target, name, { get: all[name], enumerable: true });
5
20
  };
6
-
7
- // src/api/client.ts
8
- import axios from "axios";
21
+ var httpClient = axios.create();
22
+ var createHttpClient = ({
23
+ baseURL,
24
+ apiVersion,
25
+ timeout = 3e3
26
+ }) => {
27
+ httpClient = axios.create({
28
+ baseURL: `${baseURL}/api/${apiVersion}`,
29
+ timeout,
30
+ headers: {
31
+ "Content-Type": "application/json",
32
+ Accept: "application/json"
33
+ }
34
+ });
35
+ httpClient.interceptors.request.use(
36
+ (config) => {
37
+ return config;
38
+ },
39
+ (error) => {
40
+ return Promise.reject(error);
41
+ }
42
+ );
43
+ httpClient.interceptors.response.use(
44
+ (response) => {
45
+ const originalRequest = response.config;
46
+ if (response.status === 401 && originalRequest) {
47
+ return new Promise(async (resolve, _reject) => {
48
+ });
49
+ }
50
+ return response.data;
51
+ },
52
+ (err) => {
53
+ return Promise.reject(err);
54
+ }
55
+ );
56
+ };
57
+ var setTokenToHttpClient = (token) => {
58
+ httpClient.defaults.headers["Authorization"] = token ? `Bearer ${token}` : "";
59
+ };
9
60
  var ApiClient = class {
10
61
  constructor(config) {
11
62
  this.isRefreshing = false;
@@ -166,32 +217,24 @@ var ApiClient = class {
166
217
  * Generic PUT request
167
218
  */
168
219
  async put(options) {
169
- const response = await this.axiosInstance.put(
170
- options.endpoint,
171
- options.data,
172
- {
173
- params: options.params,
174
- headers: options.headers,
175
- ...options.config,
176
- skipAuth: options.skipAuth
177
- }
178
- );
220
+ const response = await this.axiosInstance.put(options.endpoint, options.data, {
221
+ params: options.params,
222
+ headers: options.headers,
223
+ ...options.config,
224
+ skipAuth: options.skipAuth
225
+ });
179
226
  return response.data;
180
227
  }
181
228
  /**
182
229
  * Generic PATCH request
183
230
  */
184
231
  async patch(options) {
185
- const response = await this.axiosInstance.patch(
186
- options.endpoint,
187
- options.data,
188
- {
189
- params: options.params,
190
- headers: options.headers,
191
- ...options.config,
192
- skipAuth: options.skipAuth
193
- }
194
- );
232
+ const response = await this.axiosInstance.patch(options.endpoint, options.data, {
233
+ params: options.params,
234
+ headers: options.headers,
235
+ ...options.config,
236
+ skipAuth: options.skipAuth
237
+ });
195
238
  return response.data;
196
239
  }
197
240
  /**
@@ -214,6 +257,7 @@ function createApiClient(config) {
214
257
  // src/api/endpoints.ts
215
258
  var endpoints_exports = {};
216
259
  __export(endpoints_exports, {
260
+ EP_AZURE_AUTH: () => EP_AZURE_AUTH,
217
261
  EP_BRANCHES: () => EP_BRANCHES,
218
262
  EP_CREATE_QR: () => EP_CREATE_QR,
219
263
  EP_DEVICES: () => EP_DEVICES,
@@ -231,6 +275,7 @@ __export(endpoints_exports, {
231
275
  });
232
276
  var EP_LOGIN = "users/sign_in";
233
277
  var EP_TOKEN = "token";
278
+ var EP_AZURE_AUTH = "auth/azure";
234
279
  var EP_DEVICES = "devices";
235
280
  var EP_QR_DEVICES = "devices/qr_devices";
236
281
  var EP_QR_ACCESS = "qr_access/accessible_qrs";
@@ -264,17 +309,7 @@ var DeviceDirection = /* @__PURE__ */ ((DeviceDirection2) => {
264
309
  })(DeviceDirection || {});
265
310
 
266
311
  // src/services/AuthService.ts
267
- var AuthService = class {
268
- constructor(apiClient) {
269
- this.apiClient = apiClient;
270
- }
271
- /**
272
- * Set token storage implementation
273
- * This is used by platform-specific implementations (React Native, Android, iOS)
274
- */
275
- setTokenStorage(storage) {
276
- this.tokenStorage = storage;
277
- }
312
+ var AuthService = {
278
313
  /**
279
314
  * Login with credentials
280
315
  *
@@ -295,7 +330,7 @@ var AuthService = class {
295
330
  * }
296
331
  * ```
297
332
  */
298
- async login(credentials) {
333
+ login: async (credentials) => {
299
334
  try {
300
335
  const requestBody = {
301
336
  user: {
@@ -303,12 +338,7 @@ var AuthService = class {
303
338
  password: credentials.password
304
339
  }
305
340
  };
306
- const response = await this.apiClient.post({
307
- endpoint: "/api/v2/users/sign_in",
308
- data: requestBody,
309
- skipAuth: true
310
- // Don't send auth header for login
311
- });
341
+ const response = await httpClient.post(EP_LOGIN, requestBody);
312
342
  if (!response.success || !response.data?.tokens) {
313
343
  return {
314
344
  success: false,
@@ -317,18 +347,12 @@ var AuthService = class {
317
347
  };
318
348
  }
319
349
  const tokens = response.data.tokens;
320
- if (this.tokenStorage) {
321
- await this.tokenStorage.saveTokens(tokens);
322
- }
323
- this.apiClient.setToken(tokens.access.token);
350
+ setTokenToHttpClient(tokens.access.token);
324
351
  let user;
325
352
  try {
326
- const userResult = await this.getCurrentUser();
353
+ const userResult = await AuthService.getCurrentUser();
327
354
  if (userResult.success) {
328
355
  user = userResult.user;
329
- if (this.tokenStorage) {
330
- await this.tokenStorage.saveUser(user);
331
- }
332
356
  }
333
357
  } catch (error) {
334
358
  console.warn("Failed to fetch user info after login:", error);
@@ -345,7 +369,68 @@ var AuthService = class {
345
369
  code: error.code || "NETWORK_ERROR"
346
370
  };
347
371
  }
348
- }
372
+ },
373
+ /**
374
+ * Login with Azure AD token
375
+ *
376
+ * @param credentials - Azure AD login credentials (id_token and optional device_type)
377
+ * @returns Login result with tokens on success
378
+ *
379
+ * @example
380
+ * ```typescript
381
+ * const result = await authService.loginWithAzure({
382
+ * id_token: 'azure_id_token_here',
383
+ * device_type: 'ios'
384
+ * });
385
+ *
386
+ * if (result.success) {
387
+ * console.log('Access token:', result.tokens.access.token);
388
+ * } else {
389
+ * console.error('Azure login failed:', result.error);
390
+ * }
391
+ * ```
392
+ */
393
+ loginWithAzure: async (credentials) => {
394
+ try {
395
+ const response = await httpClient.post(
396
+ EP_AZURE_AUTH,
397
+ {
398
+ id_token: credentials.id_token,
399
+ device_type: credentials.device_type || "android"
400
+ },
401
+ { skipAuth: true }
402
+ );
403
+ if (!response.success || !response.data?.tokens) {
404
+ return {
405
+ success: false,
406
+ error: response.message || "Azure login failed",
407
+ code: "AZURE_LOGIN_FAILED"
408
+ };
409
+ }
410
+ const tokens = response.data.tokens;
411
+ setTokenToHttpClient(tokens.access.token);
412
+ let user;
413
+ try {
414
+ const userResult = await AuthService.getCurrentUser();
415
+ if (userResult.success) {
416
+ user = userResult.user;
417
+ }
418
+ } catch (error) {
419
+ console.warn("Failed to fetch user info after Azure login:", error);
420
+ }
421
+ return {
422
+ success: true,
423
+ tokens,
424
+ user
425
+ };
426
+ } catch (error) {
427
+ return {
428
+ success: false,
429
+ error: error.message || "An error occurred during Azure login",
430
+ code: error.code || "NETWORK_ERROR"
431
+ };
432
+ }
433
+ },
349
434
  /**
350
435
  * Refresh access token using refresh token
351
436
  *
@@ -361,16 +446,18 @@ var AuthService = class {
361
446
  * }
362
447
  * ```
363
448
  */
364
- async refreshToken(refreshToken) {
449
+ refreshToken: async (refreshToken) => {
365
450
  try {
366
451
  const requestBody = {
367
452
  refresh_token: refreshToken
368
453
  };
369
- const response = await this.apiClient.post({
370
- endpoint: "/token",
371
- data: requestBody,
372
- skipAuth: true
373
- });
454
+ const response = await httpClient.post(
455
+ "/token",
456
+ {
457
+ data: requestBody
458
+ },
459
+ { skipAuth: true }
460
+ );
374
461
  if (!response.success || !response.data?.token || !response.data?.refresh_token) {
375
462
  return {
376
463
  success: false,
@@ -380,18 +467,14 @@ var AuthService = class {
380
467
  }
381
468
  const tokens = {
382
469
  access: {
383
- token: response.data.token,
470
+ token: response.data.token ?? "",
384
471
  expiresIn: "30 days"
385
472
  },
386
473
  refresh: {
387
- token: response.data.refresh_token,
474
+ token: response.data.refresh_token ?? "",
388
475
  expiresIn: "30 days"
389
476
  }
390
477
  };
391
- if (this.tokenStorage) {
392
- await this.tokenStorage.saveTokens(tokens);
393
- }
394
- this.apiClient.setToken(tokens.access.token);
395
478
  return {
396
479
  success: true,
397
480
  tokens
@@ -403,7 +486,7 @@ var AuthService = class {
403
486
  code: error.code || "NETWORK_ERROR"
404
487
  };
405
488
  }
406
- }
489
+ },
407
490
  /**
408
491
  * Get current user information
409
492
  *
@@ -418,12 +501,10 @@ var AuthService = class {
418
501
  * }
419
502
  * ```
420
503
  */
421
- async getCurrentUser() {
504
+ getCurrentUser: async () => {
422
505
  try {
423
- const response = await this.apiClient.get({
424
- endpoint: "/api/v2/users/me"
425
- });
426
- if (!response.success || !response.data) {
506
+ const response = await httpClient.get(EP_ME);
507
+ if (!response || !response.data) {
427
508
  return {
428
509
  success: false,
429
510
  error: response.message || "Failed to fetch user information"
@@ -457,69 +538,40 @@ var AuthService = class {
457
538
  };
458
539
  }
459
540
  }
541
+ };
542
+
543
+ // src/services/QRAccessService.ts
544
+ var QRAccessService = {
460
545
  /**
461
- * Logout current user
462
- * Clears tokens from storage and API client
463
- *
464
- * @example
465
- * ```typescript
466
- * await authService.logout();
467
- * console.log('User logged out');
468
- * ```
469
- */
470
- async logout() {
471
- if (this.tokenStorage) {
472
- await this.tokenStorage.clearTokens();
473
- await this.tokenStorage.clearUser();
474
- }
475
- this.apiClient.setToken(null);
476
- }
477
- /**
478
- * Check if user is authenticated
479
- *
480
- * @returns True if user has valid tokens
481
- */
482
- async isAuthenticated() {
483
- if (!this.tokenStorage) {
484
- return false;
485
- }
486
- const tokens = await this.tokenStorage.getTokens();
487
- return tokens !== null && tokens.access.token.length > 0;
488
- }
489
- /**
490
- * Get stored tokens
491
- *
492
- * @returns Stored tokens or null
546
+ * Trigger IoT device
493
547
  */
494
- async getStoredTokens() {
495
- if (!this.tokenStorage) {
496
- return null;
497
- }
498
- return await this.tokenStorage.getTokens();
499
- }
548
+ triggerIoTDevice: async (deviceId, config) => {
549
+ return httpClient.post(
550
+ `${EP_TRIGGER_IOT}/${deviceId}`,
551
+ config
552
+ );
553
+ },
500
554
  /**
501
- * Get stored user
502
- *
503
- * @returns Stored user or null
555
+ * Create entrance from QR code
504
556
  */
505
- async getStoredUser() {
506
- if (!this.tokenStorage) {
507
- return null;
508
- }
509
- return await this.tokenStorage.getUser();
557
+ createEntranceFromQR: (request2) => {
558
+ return httpClient.post(
559
+ EP_CREATE_QR,
560
+ request2
561
+ );
510
562
  }
511
563
  };
512
564
 
513
565
  // src/utils/location.ts
514
566
  function calculateDistance(lat1, lon1, lat2, lon2) {
515
- const R = 6371e3;
516
- const \u03C61 = lat1 * Math.PI / 180;
517
- const \u03C62 = lat2 * Math.PI / 180;
518
- const \u0394\u03C6 = (lat2 - lat1) * Math.PI / 180;
519
- const \u0394\u03BB = (lon2 - lon1) * Math.PI / 180;
520
- const a = Math.sin(\u0394\u03C6 / 2) * Math.sin(\u0394\u03C6 / 2) + Math.cos(\u03C61) * Math.cos(\u03C62) * Math.sin(\u0394\u03BB / 2) * Math.sin(\u0394\u03BB / 2);
567
+ let earthRadiusKm = 6371;
568
+ const lat1Rad = lat1 * Math.PI / 180;
569
+ const lat2Rad = lat2 * Math.PI / 180;
570
+ const dLat = (lat2 - lat1) * Math.PI / 180;
571
+ const dLon = (lon2 - lon1) * Math.PI / 180;
572
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
521
573
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
522
- return R * c;
574
+ return earthRadiusKm * c;
523
575
  }
524
576
  function checkOnLocation(targetLat, targetLon, allowedRange, userPosition) {
525
577
  if (!userPosition) {
@@ -545,20 +597,27 @@ function validateCoordinates(coords) {
545
597
  }
546
598
 
547
599
  // src/utils/validation.ts
548
- var READ_TIMEOUT = 15e3;
600
+ var READ_TIMEOUT = 3e4;
549
601
  var readRecords = [];
550
602
  function checkRepetitiveRead(code) {
551
603
  const now = Date.now();
552
- readRecords = readRecords.filter((record) => now - record.timestamp < READ_TIMEOUT);
604
+ readRecords = readRecords.filter(
605
+ (record) => now - record.timestamp < READ_TIMEOUT
606
+ );
553
607
  const recentRead = readRecords.find(
554
608
  (record) => record.code === code && now - record.timestamp < READ_TIMEOUT
555
609
  );
556
610
  if (recentRead) {
557
611
  return false;
558
612
  }
559
- readRecords.push({ code, timestamp: now });
560
613
  return true;
561
614
  }
615
+ var addQrReadRecord = (code) => {
616
+ const now = Date.now();
617
+ if (code) {
618
+ readRecords.push({ code, timestamp: now });
619
+ }
620
+ };
562
621
  function clearReadRecords() {
563
622
  readRecords = [];
564
623
  }
@@ -572,6 +631,27 @@ function validateDeviceId(id) {
572
631
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
573
632
  return uuidRegex.test(id);
574
633
  }
634
+ var shouldValidateLocation = (device) => {
635
+ return device.range_matter === "1" && !!device.latitude && !!device.longitude;
636
+ };
637
+ var validateLocation = (device, userLocation) => {
638
+ if (!shouldValidateLocation(device)) {
639
+ return { valid: true };
640
+ }
641
+ if (!userLocation) {
642
+ return { valid: false };
643
+ }
644
+ const locationCheck = checkOnLocation(
645
+ device.latitude,
646
+ device.longitude,
647
+ device.range || 100,
648
+ userLocation
649
+ );
650
+ return {
651
+ valid: locationCheck.ok,
652
+ distance: locationCheck.distance
653
+ };
654
+ };
575
655
 
576
656
  // src/utils/date.ts
577
657
  function formatISO(date = /* @__PURE__ */ new Date()) {
@@ -598,442 +678,162 @@ function parseISO(isoString) {
598
678
  return new Date(isoString);
599
679
  }
600
680
 
601
- // src/services/QRAccessService.ts
602
- var QRAccessService = class {
603
- constructor(apiClient) {
604
- this.apiClient = apiClient;
605
- }
606
- /**
607
- * Validate QR code format
608
- */
609
- validateQRFormat(code) {
610
- return validateQRCode(code);
611
- }
612
- /**
613
- * Check if location validation is required
614
- */
615
- shouldValidateLocation(device) {
616
- return device.range_matter === "1" && !!device.latitude && !!device.longitude;
617
- }
618
- /**
619
- * Validate user location against device location
620
- */
621
- validateLocation(device, userLocation) {
622
- if (!this.shouldValidateLocation(device)) {
681
+ // src/services/NFCAccessService.ts
682
+ var NfcAccessService = {
683
+ validateNFCFormat: (code) => {
684
+ return validateNFCCode(code);
685
+ },
686
+ shouldValidateLocation: (device) => {
687
+ return device?.nfc_range_matter === "1" && !!device?.latitude && !!device.longitude;
688
+ },
689
+ validateLocation: (device, userLocation) => {
690
+ if (!NfcAccessService.shouldValidateLocation(device)) {
623
691
  return { valid: true };
624
692
  }
625
693
  if (!userLocation) {
626
694
  return { valid: false };
627
695
  }
628
696
  const locationCheck = checkOnLocation(
629
- device.latitude,
630
- device.longitude,
631
- device.range || 100,
697
+ device?.latitude,
698
+ device?.longitude,
699
+ device?.nfc_range || 100,
632
700
  userLocation
633
701
  );
634
702
  return {
635
703
  valid: locationCheck.ok,
636
704
  distance: locationCheck.distance
637
705
  };
638
- }
706
+ },
639
707
  /**
640
- * Validate QR code with full checks
708
+ * Validate NFC code with full checks
641
709
  */
642
- async validateQR(options) {
643
- const { qrCode, device, userLocation, skipLocationCheck, skipRepetitiveCheck } = options;
644
- if (!this.validateQRFormat(qrCode)) {
645
- return {
646
- success: false,
647
- message: "Invalid QR code format",
648
- error: { code: "INVALID_QR_FORMAT" }
649
- };
650
- }
651
- if (!skipRepetitiveCheck && !checkRepetitiveRead(qrCode)) {
652
- return {
653
- success: false,
654
- message: "QR code was recently scanned. Please wait before scanning again.",
655
- error: { code: "REPETITIVE_READ" }
656
- };
657
- }
658
- if (!skipLocationCheck) {
659
- const locationValidation = this.validateLocation(device, userLocation);
660
- if (!locationValidation.valid) {
710
+ async validateNFC(options) {
711
+ const { device } = options;
712
+ const onlineRequestBody = {
713
+ device_id: device.id
714
+ };
715
+ if (device.is_iot) {
716
+ try {
717
+ const enteranceQrRes = await QRAccessService.createEntranceFromQR(
718
+ onlineRequestBody
719
+ );
720
+ return {
721
+ success: !!enteranceQrRes?.success,
722
+ message: "QR code validated successfully",
723
+ entrance: enteranceQrRes.data
724
+ };
725
+ } catch (error) {
661
726
  return {
662
727
  success: false,
663
- message: "You are not within the allowed range of this device",
664
- error: {
665
- code: "LOCATION_OUT_OF_RANGE",
666
- details: locationValidation.distance ? `Distance: ${locationValidation.distance.toFixed(2)}m` : void 0
667
- }
728
+ message: error.message || "Failed to validate QR code",
729
+ error: { code: "NETWORK_ERROR" }
668
730
  };
669
731
  }
670
- }
671
- try {
672
- const response = await this.apiClient.post({
673
- endpoint: EP_QR_CHECK,
674
- data: { qr_code: qrCode }
675
- });
676
- if (!response.success) {
732
+ } else {
733
+ try {
734
+ const enteranceQrRes = await QRAccessService.createEntranceFromQR(
735
+ onlineRequestBody
736
+ );
737
+ return {
738
+ success: !!enteranceQrRes?.success,
739
+ message: "QR code validated successfully",
740
+ entrance: enteranceQrRes.data
741
+ };
742
+ } catch (error) {
677
743
  return {
678
744
  success: false,
679
- message: response.message || "QR validation failed",
680
- error: { code: "API_ERROR" }
745
+ message: error.message || "Failed to validate QR code",
746
+ error: { code: "NETWORK_ERROR" }
681
747
  };
682
748
  }
683
- return {
684
- success: true,
685
- message: "QR code validated successfully",
686
- entrance: response.data
687
- };
688
- } catch (error) {
689
- return {
690
- success: false,
691
- message: error.message || "Failed to validate QR code",
692
- error: { code: "NETWORK_ERROR" }
693
- };
694
749
  }
695
750
  }
751
+ };
752
+
753
+ // src/services/DeviceAccessService.ts
754
+ var DeviceAccessService = {
696
755
  /**
697
- * Create entrance from QR code
756
+ * Get all devices
698
757
  */
699
- async createEntranceFromQR(request) {
700
- return this.apiClient.post({
701
- endpoint: EP_CREATE_QR,
702
- data: request
758
+ getDevices: async (params) => {
759
+ return httpClient.get(EP_DEVICES, {
760
+ params: params || { per_page: 100 }
703
761
  });
704
- }
762
+ },
705
763
  /**
706
- * Trigger IoT device
764
+ * Get all QR devices
707
765
  */
708
- async triggerIoTDevice(deviceId) {
709
- return this.apiClient.post({
710
- endpoint: `${EP_TRIGGER_IOT}/${deviceId}`
711
- });
712
- }
713
- };
714
-
715
- // src/services/NFCAccessService.ts
716
- var NFCAccessService = class {
717
- constructor(apiClient) {
718
- this.apiClient = apiClient;
719
- }
766
+ getQRDevices: async (params) => {
767
+ return httpClient.get(
768
+ EP_QR_DEVICES,
769
+ {
770
+ params: params || { per_page: 100 }
771
+ }
772
+ );
773
+ },
720
774
  /**
721
- * Validate NFC code format
775
+ * Get all QR devices with pagination support
722
776
  */
723
- validateNFCFormat(code) {
724
- return validateNFCCode(code);
725
- }
777
+ getAllQRDevices: async () => {
778
+ const perPage = 50;
779
+ let currentPage = 1;
780
+ let allData = [];
781
+ while (true) {
782
+ const response = await DeviceAccessService.getQRDevices({
783
+ page: currentPage,
784
+ per_page: perPage
785
+ });
786
+ if (!response.success || !response.data) {
787
+ break;
788
+ }
789
+ allData = [...allData, ...response.data];
790
+ if (!response.meta || !response.meta.total_pages) {
791
+ break;
792
+ }
793
+ if (currentPage >= response.meta.total_pages) {
794
+ break;
795
+ }
796
+ currentPage++;
797
+ }
798
+ return allData;
799
+ },
726
800
  /**
727
- * Check if location validation is required
801
+ * Get accessible QR codes for current user
728
802
  */
729
- shouldValidateLocation(device) {
730
- return device.nfc_range_matter === "1" && !!device.latitude && !!device.longitude;
731
- }
803
+ getAccessibleQRs: async () => {
804
+ return httpClient.get(
805
+ EP_QR_ACCESS
806
+ );
807
+ },
732
808
  /**
733
- * Validate user location against device location
809
+ * Get user devices
734
810
  */
735
- validateLocation(device, userLocation) {
736
- if (!this.shouldValidateLocation(device)) {
737
- return { valid: true };
738
- }
739
- if (!userLocation) {
740
- return { valid: false };
741
- }
742
- const locationCheck = checkOnLocation(
743
- device.latitude,
744
- device.longitude,
745
- device.nfc_range || 100,
746
- userLocation
811
+ getUserDevices: async (request2) => {
812
+ const { userId, page, per_page } = request2;
813
+ return httpClient.get(
814
+ `${EP_USERS}/${userId}/devices`,
815
+ {
816
+ params: {
817
+ ...page && { page },
818
+ ...per_page && { per_page }
819
+ }
820
+ }
747
821
  );
748
- return {
749
- valid: locationCheck.ok,
750
- distance: locationCheck.distance
751
- };
752
- }
822
+ },
753
823
  /**
754
- * Validate NFC code with full checks
824
+ * Get device by ID
755
825
  */
756
- async validateNFC(options) {
757
- const { nfcCode, device, userLocation, skipLocationCheck, skipRepetitiveCheck } = options;
758
- if (!this.validateNFCFormat(nfcCode)) {
759
- return {
760
- success: false,
761
- message: "Invalid NFC code format",
762
- error: { code: "INVALID_NFC_FORMAT" }
763
- };
764
- }
765
- if (!skipRepetitiveCheck && !checkRepetitiveRead(nfcCode)) {
766
- return {
767
- success: false,
768
- message: "NFC card was recently scanned. Please wait before scanning again.",
769
- error: { code: "REPETITIVE_READ" }
770
- };
771
- }
772
- if (!skipLocationCheck) {
773
- const locationValidation = this.validateLocation(device, userLocation);
774
- if (!locationValidation.valid) {
775
- return {
776
- success: false,
777
- message: "You are not within the allowed range of this device",
778
- error: {
779
- code: "LOCATION_OUT_OF_RANGE",
780
- details: locationValidation.distance ? `Distance: ${locationValidation.distance.toFixed(2)}m` : void 0
781
- }
782
- };
783
- }
784
- }
785
- try {
786
- const response = await this.apiClient.post({
787
- endpoint: EP_NFC_CHECK,
788
- data: { nfc_code: nfcCode }
789
- });
790
- if (!response.success) {
791
- return {
792
- success: false,
793
- message: response.message || "NFC validation failed",
794
- error: { code: "API_ERROR" }
795
- };
796
- }
797
- return {
798
- success: true,
799
- message: "NFC card validated successfully",
800
- entrance: response.data
801
- };
802
- } catch (error) {
803
- return {
804
- success: false,
805
- message: error.message || "Failed to validate NFC card",
806
- error: { code: "NETWORK_ERROR" }
807
- };
808
- }
809
- }
810
- };
811
-
812
- // src/services/CheckInService.ts
813
- var CheckInService = class {
814
- constructor(apiClient) {
815
- this.apiClient = apiClient;
816
- }
817
- /**
818
- * Get nearby branches based on user location
819
- */
820
- async getNearbyBranches(request) {
821
- const { latitude, longitude, radius } = request;
822
- if (!validateCoordinates({ latitude, longitude })) {
823
- throw new Error("Invalid coordinates provided");
824
- }
825
- return this.apiClient.get({
826
- endpoint: EP_BRANCHES,
827
- params: {
828
- latitude,
829
- longitude,
830
- ...radius && { radius }
831
- }
832
- });
833
- }
834
- /**
835
- * Check in to a branch
836
- */
837
- async checkIn(options) {
838
- const { branchId, entranceType, userId, userLocation: _userLocation } = options;
839
- try {
840
- const entranceRequest = {
841
- user_id: userId,
842
- branch_id: branchId,
843
- entrance_type: entranceType,
844
- is_manual_recording: false
845
- };
846
- const response = await this.apiClient.post({
847
- endpoint: EP_ENTRANCES,
848
- data: entranceRequest
849
- });
850
- if (!response.success) {
851
- return {
852
- success: false,
853
- message: response.message || "Check-in failed",
854
- error: { code: "API_ERROR" }
855
- };
856
- }
857
- return {
858
- success: true,
859
- message: "Check-in successful",
860
- entrance: response.data
861
- };
862
- } catch (error) {
863
- return {
864
- success: false,
865
- message: error.message || "Failed to check-in",
866
- error: { code: "NETWORK_ERROR" }
867
- };
868
- }
869
- }
870
- /**
871
- * Get branch by ID
872
- */
873
- async getBranchById(branchId) {
874
- return this.apiClient.get({
875
- endpoint: `${EP_BRANCHES}/${branchId}`
876
- });
877
- }
878
- /**
879
- * Get all branches (with pagination)
880
- */
881
- async getAllBranches(params) {
882
- return this.apiClient.get({
883
- endpoint: EP_BRANCHES,
884
- params
885
- });
886
- }
887
- };
888
-
889
- // src/services/RemoteWorkService.ts
890
- var RemoteWorkService = class {
891
- constructor(apiClient) {
892
- this.apiClient = apiClient;
893
- }
894
- /**
895
- * Log remote work entry or exit
896
- */
897
- async logRemoteWork(options) {
898
- const { userId, entranceType, timestamp, description } = options;
899
- try {
900
- const createdAt = timestamp ? typeof timestamp === "string" ? timestamp : formatISO(timestamp) : formatISO();
901
- const entranceRequest = {
902
- user_id: userId,
903
- entrance_type: entranceType,
904
- is_manual_recording: true,
905
- is_remote_work: true,
906
- created_at: createdAt,
907
- description
908
- };
909
- const response = await this.apiClient.post({
910
- endpoint: EP_ENTRANCES,
911
- data: { entrance: entranceRequest }
912
- });
913
- if (!response.success) {
914
- return {
915
- success: false,
916
- message: response.message || "Failed to log remote work",
917
- error: { code: "API_ERROR" }
918
- };
919
- }
920
- return {
921
- success: true,
922
- message: "Remote work logged successfully",
923
- entrance: response.data
924
- };
925
- } catch (error) {
926
- return {
927
- success: false,
928
- message: error.message || "Failed to log remote work",
929
- error: { code: "NETWORK_ERROR" }
930
- };
931
- }
932
- }
933
- /**
934
- * Log remote work entry
935
- */
936
- async logEntry(options) {
937
- return this.logRemoteWork({
938
- ...options,
939
- entranceType: 0 /* ENTRY */
940
- });
941
- }
942
- /**
943
- * Log remote work exit
944
- */
945
- async logExit(options) {
946
- return this.logRemoteWork({
947
- ...options,
948
- entranceType: 1 /* EXIT */
949
- });
950
- }
951
- };
952
-
953
- // src/services/DeviceAccessService.ts
954
- var DeviceAccessService = class {
955
- constructor(apiClient) {
956
- this.apiClient = apiClient;
957
- }
958
- /**
959
- * Get all devices
960
- */
961
- async getDevices(params) {
962
- return this.apiClient.get({
963
- endpoint: EP_DEVICES,
964
- params: params || { per_page: 100 }
965
- });
966
- }
967
- /**
968
- * Get all QR devices
969
- */
970
- async getQRDevices(params) {
971
- return this.apiClient.get({
972
- endpoint: EP_QR_DEVICES,
973
- params: params || { per_page: 100 }
974
- });
975
- }
976
- /**
977
- * Get all QR devices with pagination support
978
- */
979
- async getAllQRDevices() {
980
- const perPage = 50;
981
- let currentPage = 1;
982
- let allData = [];
983
- while (true) {
984
- const response = await this.getQRDevices({
985
- page: currentPage,
986
- per_page: perPage
987
- });
988
- if (!response.success || !response.data) {
989
- break;
990
- }
991
- allData = [...allData, ...response.data];
992
- if (!response.meta || !response.meta.total_pages) {
993
- break;
994
- }
995
- if (currentPage >= response.meta.total_pages) {
996
- break;
997
- }
998
- currentPage++;
999
- }
1000
- return allData;
1001
- }
1002
- /**
1003
- * Get accessible QR codes for current user
1004
- */
1005
- async getAccessibleQRs() {
1006
- return this.apiClient.get({
1007
- endpoint: EP_QR_ACCESS
1008
- });
1009
- }
1010
- /**
1011
- * Get user devices
1012
- */
1013
- async getUserDevices(request) {
1014
- const { userId, page, per_page } = request;
1015
- return this.apiClient.get({
1016
- endpoint: `${EP_USERS}/${userId}/devices`,
1017
- params: {
1018
- ...page && { page },
1019
- ...per_page && { per_page }
1020
- }
1021
- });
1022
- }
1023
- /**
1024
- * Get device by ID
1025
- */
1026
- async getDeviceById(deviceId) {
1027
- return this.apiClient.get({
1028
- endpoint: `${EP_DEVICES}/${deviceId}`
1029
- });
1030
- }
826
+ getDeviceById: async (deviceId) => {
827
+ return httpClient.get(
828
+ `${EP_DEVICES}/${deviceId}`
829
+ );
830
+ },
1031
831
  /**
1032
832
  * Check if user has access to a device
1033
833
  */
1034
- async checkDeviceAccess(deviceId) {
834
+ checkDeviceAccess: async (deviceId) => {
1035
835
  try {
1036
- const response = await this.getAccessibleQRs();
836
+ const response = await DeviceAccessService.getAccessibleQRs();
1037
837
  if (!response.success || !response.data) {
1038
838
  return false;
1039
839
  }
@@ -1041,24 +841,25 @@ var DeviceAccessService = class {
1041
841
  } catch {
1042
842
  return false;
1043
843
  }
1044
- }
844
+ },
1045
845
  /**
1046
846
  * Find QR device by QR code ID
1047
847
  */
1048
- async findDeviceByQRCode(qrCodeId) {
848
+ findDeviceByQRCode: async (qrCodeId) => {
1049
849
  try {
1050
- const devices = await this.getAllQRDevices();
1051
- return devices.find((device) => device.qr_code_id === qrCodeId);
850
+ const devices = await DeviceAccessService.getAllQRDevices();
851
+ const qr = devices.find((device) => device.qr_code_id === qrCodeId);
852
+ return qr;
1052
853
  } catch {
1053
854
  return void 0;
1054
855
  }
1055
- }
856
+ },
1056
857
  /**
1057
858
  * Find QR device by NFC code
1058
859
  */
1059
- async findDeviceByNFCCode(nfcCode) {
860
+ findDeviceByNFCCode: async (nfcCode) => {
1060
861
  try {
1061
- const devices = await this.getAllQRDevices();
862
+ const devices = await DeviceAccessService.getAllQRDevices();
1062
863
  return devices.find((device) => device.nfc_code === nfcCode);
1063
864
  } catch {
1064
865
  return void 0;
@@ -1153,21 +954,15 @@ var LocationService = class {
1153
954
  return this.logLocationVerification(log);
1154
955
  }
1155
956
  };
1156
-
1157
- // src/providers/PassgageAccessProvider.tsx
1158
- import React, { createContext, useContext, useMemo } from "react";
1159
-
1160
- // src/utils/secureStorage.ts
1161
- import * as Keychain from "react-native-keychain";
1162
957
  var STORAGE_KEYS = {
1163
958
  TOKENS: "passgage_auth_tokens",
1164
959
  USER: "passgage_user_info"
1165
960
  };
1166
- var SecureStorage = class {
961
+ var SecureStorage = {
1167
962
  /**
1168
963
  * Save tokens to secure storage
1169
964
  */
1170
- async saveTokens(tokens) {
965
+ saveTokens: async (tokens) => {
1171
966
  try {
1172
967
  await Keychain.setGenericPassword(
1173
968
  STORAGE_KEYS.TOKENS,
@@ -1181,11 +976,11 @@ var SecureStorage = class {
1181
976
  console.error("Failed to save tokens to secure storage:", error);
1182
977
  throw new Error("Failed to save tokens");
1183
978
  }
1184
- }
979
+ },
1185
980
  /**
1186
981
  * Get tokens from secure storage
1187
982
  */
1188
- async getTokens() {
983
+ getTokens: async () => {
1189
984
  try {
1190
985
  const credentials = await Keychain.getGenericPassword({
1191
986
  service: STORAGE_KEYS.TOKENS
@@ -1199,11 +994,11 @@ var SecureStorage = class {
1199
994
  console.error("Failed to get tokens from secure storage:", error);
1200
995
  return null;
1201
996
  }
1202
- }
997
+ },
1203
998
  /**
1204
999
  * Clear tokens from secure storage
1205
1000
  */
1206
- async clearTokens() {
1001
+ clearTokens: async () => {
1207
1002
  try {
1208
1003
  await Keychain.resetGenericPassword({
1209
1004
  service: STORAGE_KEYS.TOKENS
@@ -1211,11 +1006,11 @@ var SecureStorage = class {
1211
1006
  } catch (error) {
1212
1007
  console.error("Failed to clear tokens from secure storage:", error);
1213
1008
  }
1214
- }
1009
+ },
1215
1010
  /**
1216
1011
  * Save user information
1217
1012
  */
1218
- async saveUser(user) {
1013
+ saveUser: async (user) => {
1219
1014
  try {
1220
1015
  await Keychain.setGenericPassword(
1221
1016
  STORAGE_KEYS.USER,
@@ -1229,11 +1024,11 @@ var SecureStorage = class {
1229
1024
  console.error("Failed to save user to secure storage:", error);
1230
1025
  throw new Error("Failed to save user");
1231
1026
  }
1232
- }
1027
+ },
1233
1028
  /**
1234
1029
  * Get user information
1235
1030
  */
1236
- async getUser() {
1031
+ getUser: async () => {
1237
1032
  try {
1238
1033
  const credentials = await Keychain.getGenericPassword({
1239
1034
  service: STORAGE_KEYS.USER
@@ -1247,11 +1042,11 @@ var SecureStorage = class {
1247
1042
  console.error("Failed to get user from secure storage:", error);
1248
1043
  return null;
1249
1044
  }
1250
- }
1045
+ },
1251
1046
  /**
1252
1047
  * Clear user information
1253
1048
  */
1254
- async clearUser() {
1049
+ clearUser: async () => {
1255
1050
  try {
1256
1051
  await Keychain.resetGenericPassword({
1257
1052
  service: STORAGE_KEYS.USER
@@ -1259,257 +1054,567 @@ var SecureStorage = class {
1259
1054
  } catch (error) {
1260
1055
  console.error("Failed to clear user from secure storage:", error);
1261
1056
  }
1262
- }
1057
+ },
1263
1058
  /**
1264
1059
  * Clear all data (tokens + user)
1265
1060
  */
1266
- async clearAll() {
1267
- await this.clearTokens();
1268
- await this.clearUser();
1061
+ clearAll: async () => {
1062
+ await SecureStorage.clearTokens();
1063
+ await SecureStorage.clearUser();
1269
1064
  }
1270
1065
  };
1271
- function createSecureStorage() {
1272
- return new SecureStorage();
1273
- }
1066
+ var qrScannerStore = create((set, get) => ({
1067
+ loading: false,
1068
+ error: null,
1069
+ qrDevices: [],
1070
+ qrAccessDevices: [],
1071
+ handleQrAccess: async () => {
1072
+ const res = await DeviceAccessService.getAccessibleQRs();
1073
+ if (res.data) {
1074
+ set({ qrAccessDevices: res.data.qr_ids });
1075
+ }
1076
+ },
1077
+ fetchQrDevicesAndAccess: async () => {
1078
+ try {
1079
+ const [qrDevicesRes, qrAccessRes] = await Promise.all([
1080
+ DeviceAccessService.getAllQRDevices(),
1081
+ DeviceAccessService.getAccessibleQRs()
1082
+ ]);
1083
+ if (qrDevicesRes && qrDevicesRes.length > 0 && qrAccessRes) {
1084
+ set({
1085
+ qrDevices: qrDevicesRes,
1086
+ qrAccessDevices: qrAccessRes.data?.qr_ids
1087
+ });
1088
+ }
1089
+ } catch (error) {
1090
+ }
1091
+ }
1092
+ }));
1093
+ var locationStore = create((set, get) => ({
1094
+ location: null,
1095
+ error: null,
1096
+ loading: false,
1097
+ refreshLocation: (config = {
1098
+ enableHighAccuracy: true,
1099
+ timeout: 15e3,
1100
+ maximumAge: 1e4
1101
+ }) => {
1102
+ Geolocation2.getCurrentPosition(
1103
+ (position) => {
1104
+ set({
1105
+ loading: false,
1106
+ error: null,
1107
+ location: {
1108
+ latitude: position.coords.latitude,
1109
+ longitude: position.coords.longitude,
1110
+ accuracy: position.coords.accuracy,
1111
+ altitude: position.coords.altitude ?? void 0,
1112
+ altitudeAccuracy: position.coords.altitudeAccuracy ?? void 0,
1113
+ heading: position.coords.heading ?? void 0,
1114
+ speed: position.coords.speed ?? void 0
1115
+ }
1116
+ });
1117
+ },
1118
+ (err) => {
1119
+ set({
1120
+ loading: false,
1121
+ error: err
1122
+ });
1123
+ },
1124
+ config
1125
+ );
1126
+ }
1127
+ }));
1274
1128
 
1275
- // src/providers/PassgageAccessProvider.tsx
1276
- var PassgageAccessContext = createContext(void 0);
1277
- function PassgageAccessProvider({
1278
- children,
1279
- baseURL,
1280
- token,
1281
- apiVersion = "v2",
1282
- timeout = 3e4,
1283
- onUnauthorized,
1284
- onError
1285
- }) {
1286
- const config = {
1287
- baseURL,
1288
- token,
1289
- apiVersion,
1290
- timeout,
1291
- onUnauthorized,
1292
- onError
1293
- };
1294
- const { apiClient, services } = useMemo(() => {
1295
- const secureStorage = createSecureStorage();
1296
- let authService;
1297
- const client = createApiClient({
1298
- baseURL: config.baseURL,
1299
- token: config.token,
1300
- apiVersion: config.apiVersion,
1301
- timeout: config.timeout,
1302
- onUnauthorized: config.onUnauthorized,
1303
- onError: config.onError,
1304
- onTokenRefreshNeeded: async () => {
1305
- const storedTokens = await authService.getStoredTokens();
1306
- if (!storedTokens) {
1307
- return null;
1308
- }
1309
- const result = await authService.refreshToken(storedTokens.refresh.token);
1310
- if (result.success) {
1311
- return result.tokens.access.token;
1312
- }
1313
- return null;
1129
+ // src/utils/flowHelpers.ts
1130
+ var enteranceFlow = async (data, options) => {
1131
+ const location = locationStore.getState().location;
1132
+ const qrAccessDevices = qrScannerStore.getState().qrAccessDevices;
1133
+ const { qrCode, device, isQrCode, nfcCode = "" } = data;
1134
+ if (isQrCode ? !validateQRCode(qrCode) : validateNFCCode(nfcCode)) {
1135
+ return {
1136
+ success: false,
1137
+ message: "Invalid QR code format",
1138
+ error: { code: "INVALID_QR_FORMAT" }
1139
+ };
1140
+ }
1141
+ const checkAccessible = isQrCode ? qrAccessDevices.find((qrAccessDevice) => qrAccessDevice === qrCode) : qrAccessDevices.find((qrAccessDevice) => qrAccessDevice === nfcCode);
1142
+ if (!checkAccessible) {
1143
+ return {
1144
+ success: false,
1145
+ message: "You do not have permission. Please contact your administrator",
1146
+ error: {
1147
+ code: "QR_ACCESS_DENIED"
1314
1148
  }
1315
- });
1316
- authService = new AuthService(client);
1317
- authService.setTokenStorage(secureStorage);
1318
- const allServices = {
1319
- authService,
1320
- qrAccessService: new QRAccessService(client),
1321
- nfcAccessService: new NFCAccessService(client),
1322
- checkInService: new CheckInService(client),
1323
- remoteWorkService: new RemoteWorkService(client),
1324
- deviceAccessService: new DeviceAccessService(client),
1325
- locationService: new LocationService(client)
1326
1149
  };
1150
+ }
1151
+ if (!options.skipRepetitiveCheck && !checkRepetitiveRead(isQrCode ? qrCode : nfcCode)) {
1327
1152
  return {
1328
- apiClient: client,
1329
- services: allServices
1153
+ success: false,
1154
+ message: "QR code was recently scanned. Please wait before scanning again.",
1155
+ error: { code: "REPETITIVE_READ" }
1330
1156
  };
1331
- }, [config.baseURL, config.token, config.apiVersion, config.timeout, config.onUnauthorized, config.onError]);
1332
- const setToken = (newToken) => {
1333
- apiClient.setToken(newToken);
1334
- };
1335
- const clearToken = () => {
1336
- apiClient.clearToken();
1337
- };
1338
- const contextValue = {
1339
- apiClient,
1340
- ...services,
1341
- config,
1342
- setToken,
1343
- clearToken
1344
- };
1345
- return /* @__PURE__ */ React.createElement(PassgageAccessContext.Provider, { value: contextValue }, children);
1346
- }
1347
- function usePassgageAccess() {
1348
- const context = useContext(PassgageAccessContext);
1349
- if (!context) {
1350
- throw new Error(
1351
- "usePassgageAccess must be used within a PassgageAccessProvider"
1352
- );
1353
1157
  }
1354
- return context;
1355
- }
1356
-
1357
- // src/hooks/usePassgageAuth.ts
1358
- import { useState, useEffect, useCallback } from "react";
1359
- function usePassgageAuth(options = {}) {
1360
- const {
1361
- onLoginSuccess,
1362
- onLoginError,
1363
- onLogoutSuccess,
1364
- autoRestore = true
1365
- } = options;
1366
- const { authService } = usePassgageAccess();
1367
- const [isAuthenticated, setIsAuthenticated] = useState(false);
1368
- const [user, setUser] = useState(null);
1369
- const [isLoading, setIsLoading] = useState(false);
1370
- const [error, setError] = useState(null);
1371
- useEffect(() => {
1372
- if (!autoRestore) {
1373
- return;
1374
- }
1375
- const restoreAuth = async () => {
1376
- try {
1377
- setIsLoading(true);
1378
- const authenticated = await authService.isAuthenticated();
1379
- if (authenticated) {
1380
- const storedTokens = await authService.getStoredTokens();
1381
- const storedUser = await authService.getStoredUser();
1382
- if (storedTokens && storedUser) {
1383
- authService["apiClient"].setToken(storedTokens.access.token);
1384
- setIsAuthenticated(true);
1385
- setUser(storedUser);
1386
- try {
1387
- const userResult = await authService.getCurrentUser();
1388
- if (userResult.success) {
1389
- setUser(userResult.user);
1390
- }
1391
- } catch (error2) {
1392
- console.warn("Failed to fetch fresh user info:", error2);
1393
- }
1394
- }
1158
+ if (!options.skipLocationCheck) {
1159
+ const locationValidation = validateLocation(device, location ?? void 0);
1160
+ if (!locationValidation.valid) {
1161
+ return {
1162
+ success: false,
1163
+ message: `You are not within the allowed range of this device${location?.latitude},${location?.longitude}`,
1164
+ error: {
1165
+ code: "LOCATION_OUT_OF_RANGE",
1166
+ details: locationValidation.distance ? `Distance: ${locationValidation.distance.toFixed(2)}m` : void 0
1395
1167
  }
1396
- } catch (error2) {
1397
- console.error("Failed to restore authentication:", error2);
1398
- setError(error2.message || "Failed to restore authentication");
1399
- } finally {
1400
- setIsLoading(false);
1401
- }
1402
- };
1403
- restoreAuth();
1404
- }, [authService, autoRestore]);
1405
- const login = useCallback(
1406
- async (credentials) => {
1407
- try {
1408
- setIsLoading(true);
1409
- setError(null);
1410
- const result = await authService.login(credentials);
1411
- if (result.success) {
1412
- setIsAuthenticated(true);
1413
- setUser(result.user || null);
1414
- if (onLoginSuccess) {
1415
- onLoginSuccess(result.user);
1416
- }
1417
- } else {
1418
- setError(result.error);
1419
- if (onLoginError) {
1420
- onLoginError(result.error);
1168
+ };
1169
+ }
1170
+ }
1171
+ const onlineRequestBody = {
1172
+ device_id: device?.id ?? ""
1173
+ };
1174
+ if (device?.is_iot) {
1175
+ try {
1176
+ const enteranceResIot = await QRAccessService.triggerIoTDevice(device.id);
1177
+ if (enteranceResIot.success) {
1178
+ try {
1179
+ const enteranceQrRes = await QRAccessService.createEntranceFromQR(
1180
+ onlineRequestBody
1181
+ );
1182
+ if (enteranceQrRes.success) {
1183
+ addQrReadRecord(qrCode);
1184
+ return {
1185
+ success: !!enteranceQrRes?.success,
1186
+ message: enteranceQrRes.success ? "Enterance validated successfully" : "Enterance validation failed",
1187
+ entrance: enteranceQrRes.data
1188
+ };
1189
+ } else {
1190
+ return {
1191
+ success: false,
1192
+ message: enteranceQrRes.message ?? "Trigger IOT validation failed"
1193
+ };
1421
1194
  }
1195
+ } catch (error) {
1196
+ return {
1197
+ success: false,
1198
+ message: error?.message ?? "Qr enterance failed"
1199
+ };
1422
1200
  }
1423
- return result;
1424
- } catch (error2) {
1425
- const errorMessage = error2.message || "An error occurred during login";
1426
- setError(errorMessage);
1427
- if (onLoginError) {
1428
- onLoginError(errorMessage);
1429
- }
1201
+ } else {
1430
1202
  return {
1431
1203
  success: false,
1432
- error: errorMessage,
1433
- code: "UNKNOWN_ERROR"
1204
+ message: enteranceResIot.message ?? "Trigger IOT validation failed"
1434
1205
  };
1435
- } finally {
1436
- setIsLoading(false);
1437
- }
1438
- },
1439
- [authService, onLoginSuccess, onLoginError]
1440
- );
1441
- const logout = useCallback(async () => {
1442
- try {
1443
- setIsLoading(true);
1444
- setError(null);
1445
- await authService.logout();
1446
- setIsAuthenticated(false);
1447
- setUser(null);
1448
- if (onLogoutSuccess) {
1449
- onLogoutSuccess();
1450
1206
  }
1451
- } catch (error2) {
1452
- const errorMessage = error2.message || "An error occurred during logout";
1453
- setError(errorMessage);
1454
- console.error("Logout failed:", error2);
1455
- } finally {
1456
- setIsLoading(false);
1207
+ } catch (error) {
1208
+ return {
1209
+ success: false,
1210
+ message: error ?? "Trigger IOT validation failed"
1211
+ };
1457
1212
  }
1458
- }, [authService, onLogoutSuccess]);
1459
- const refreshToken = useCallback(async () => {
1213
+ } else {
1460
1214
  try {
1461
- const storedTokens = await authService.getStoredTokens();
1462
- if (!storedTokens) {
1463
- return false;
1464
- }
1465
- const result = await authService.refreshToken(storedTokens.refresh.token);
1466
- if (result.success) {
1467
- return true;
1468
- } else {
1469
- await logout();
1470
- return false;
1471
- }
1472
- } catch (error2) {
1473
- console.error("Token refresh failed:", error2);
1474
- await logout();
1215
+ const enteranceQrRes = await QRAccessService.createEntranceFromQR(
1216
+ onlineRequestBody
1217
+ );
1218
+ addQrReadRecord(qrCode);
1219
+ return {
1220
+ success: !!enteranceQrRes?.success,
1221
+ message: enteranceQrRes.success ? "QR code validated successfully" : "QR code validation failed",
1222
+ entrance: enteranceQrRes.data
1223
+ };
1224
+ } catch (error) {
1225
+ return {
1226
+ success: false,
1227
+ message: error.message || "Failed to validate QR code",
1228
+ error: { code: "NETWORK_ERROR" }
1229
+ };
1230
+ }
1231
+ }
1232
+ };
1233
+ var loginSuccessFlow = async (result) => {
1234
+ qrScannerStore.getState().fetchQrDevicesAndAccess();
1235
+ if (result.success) {
1236
+ await SecureStorage.saveTokens(result.tokens);
1237
+ if (result.user) {
1238
+ await SecureStorage.saveUser?.(result.user);
1239
+ }
1240
+ }
1241
+ };
1242
+
1243
+ // src/stores/authStore.ts
1244
+ var useAuthStore = create((set, get) => ({
1245
+ loading: false,
1246
+ error: null,
1247
+ authStatus: false,
1248
+ user: null,
1249
+ restoreAuth: async () => {
1250
+ const tokens = await SecureStorage.getTokens?.();
1251
+ try {
1252
+ set({ loading: true });
1253
+ const isAuthenticated = tokens !== null && tokens?.access?.token?.length > 0;
1254
+ if (isAuthenticated) {
1255
+ const storedTokens = await SecureStorage.getTokens?.();
1256
+ const storedUser = await SecureStorage.getUser?.();
1257
+ if (storedTokens && storedUser) {
1258
+ setTokenToHttpClient(storedTokens.access.token);
1259
+ set({
1260
+ user: storedUser,
1261
+ authStatus: true
1262
+ });
1263
+ try {
1264
+ const userResult = await AuthService.getCurrentUser();
1265
+ if (userResult.success) {
1266
+ set({
1267
+ user: userResult.user
1268
+ });
1269
+ qrScannerStore.getState().fetchQrDevicesAndAccess();
1270
+ }
1271
+ } catch (error) {
1272
+ console.warn("Failed to fetch fresh user info:", error);
1273
+ }
1274
+ }
1275
+ }
1276
+ } catch (error) {
1277
+ console.error("Failed to restore authentication:", error);
1278
+ set({ error: error.message || "Failed to restore authentication" });
1279
+ } finally {
1280
+ set({ loading: false });
1281
+ }
1282
+ },
1283
+ login: async (credentials, resolve, reject) => {
1284
+ try {
1285
+ set({ loading: true, error: null });
1286
+ const result = await AuthService.login(credentials);
1287
+ if (result.success) {
1288
+ resolve?.(result.user);
1289
+ loginSuccessFlow(result);
1290
+ set({ authStatus: true, user: result.user || null });
1291
+ } else {
1292
+ get().logout();
1293
+ reject?.(result.error);
1294
+ set({ error: result.error });
1295
+ }
1296
+ } catch (error) {
1297
+ get().logout();
1298
+ const errorMessage = error.message || "An error occurred during login";
1299
+ set({ error: errorMessage });
1300
+ reject?.(errorMessage);
1301
+ } finally {
1302
+ set({ loading: false });
1303
+ }
1304
+ },
1305
+ loginWithAzure: async (credentials, resolve, reject) => {
1306
+ try {
1307
+ set({ loading: true, error: null });
1308
+ const result = await AuthService.loginWithAzure(credentials);
1309
+ if (result.success) {
1310
+ loginSuccessFlow(result);
1311
+ resolve?.(result.user);
1312
+ set({ authStatus: true, user: result.user || null });
1313
+ } else {
1314
+ reject?.(result.error);
1315
+ get().logout();
1316
+ set({ error: result.error });
1317
+ }
1318
+ } catch (error) {
1319
+ const errorMessage = error.message || "An error occurred during Azure login";
1320
+ get().logout();
1321
+ set({ error: errorMessage });
1322
+ reject?.(errorMessage);
1323
+ } finally {
1324
+ set({ loading: false });
1325
+ }
1326
+ },
1327
+ logout: async (resolve) => {
1328
+ try {
1329
+ set({
1330
+ loading: true,
1331
+ error: null
1332
+ });
1333
+ await SecureStorage.clearTokens?.();
1334
+ await SecureStorage.clearUser?.();
1335
+ set({ authStatus: false, user: null });
1336
+ resolve?.();
1337
+ } catch (error) {
1338
+ const errorMessage = error.message || "An error occurred during logout";
1339
+ set({ error: errorMessage });
1340
+ console.error("Logout failed:", error);
1341
+ } finally {
1342
+ set({ loading: false });
1343
+ }
1344
+ },
1345
+ refreshToken: async () => {
1346
+ try {
1347
+ const storedTokens = await SecureStorage.getTokens?.();
1348
+ if (!storedTokens) {
1349
+ return false;
1350
+ }
1351
+ const result = await AuthService.refreshToken(storedTokens.refresh.token);
1352
+ if (result.success) {
1353
+ return true;
1354
+ } else {
1355
+ await get().logout();
1356
+ return false;
1357
+ }
1358
+ } catch (error) {
1359
+ console.error("Token refresh failed:", error);
1360
+ await get().logout();
1475
1361
  return false;
1476
1362
  }
1477
- }, [authService, logout]);
1478
- const clearError = useCallback(() => {
1479
- setError(null);
1363
+ },
1364
+ clearError: () => {
1365
+ set({ error: null });
1366
+ }
1367
+ }));
1368
+ var PassgageAccessProvideContext = createContext(void 0);
1369
+ function PassgageAccessProvider(props) {
1370
+ const {
1371
+ children,
1372
+ baseURL,
1373
+ msalToken,
1374
+ apiVersion = "v2",
1375
+ timeout = 3e4,
1376
+ rememberUser = true,
1377
+ onUnauthorized = () => {
1378
+ },
1379
+ locationPermissionErrorCallback = () => {
1380
+ },
1381
+ getLocationErrorCallback = () => {
1382
+ }
1383
+ } = props;
1384
+ const useLocationStore = locationStore();
1385
+ const authStore = useAuthStore();
1386
+ useEffect(() => {
1387
+ const msalTokenInitFlow = async () => {
1388
+ try {
1389
+ await authStore.loginWithAzure(
1390
+ {
1391
+ id_token: msalToken ?? "",
1392
+ device_type: Platform.OS === "ios" ? "ios" : "android"
1393
+ },
1394
+ () => {
1395
+ },
1396
+ (error) => {
1397
+ console.error("Failed to login with Azure:", error);
1398
+ authStore.logout();
1399
+ }
1400
+ );
1401
+ } catch (error) {
1402
+ console.error("Failed to login with Azure:", error);
1403
+ authStore.logout();
1404
+ }
1405
+ };
1406
+ const LocationPermission = Platform.select({
1407
+ android: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
1408
+ ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
1409
+ default: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
1410
+ });
1411
+ if (LocationPermission) {
1412
+ RNPermissions.check(LocationPermission).then((status) => {
1413
+ switch (status) {
1414
+ case RESULTS.DENIED:
1415
+ request(LocationPermission).then(() => {
1416
+ useLocationStore.refreshLocation();
1417
+ });
1418
+ break;
1419
+ case RESULTS.BLOCKED:
1420
+ case RESULTS.UNAVAILABLE:
1421
+ case RESULTS.GRANTED:
1422
+ case RESULTS.LIMITED:
1423
+ useLocationStore.refreshLocation();
1424
+ break;
1425
+ }
1426
+ }).catch((error) => {
1427
+ locationPermissionErrorCallback(error);
1428
+ console.error(error);
1429
+ });
1430
+ }
1431
+ createHttpClient({ apiVersion, baseURL, timeout });
1432
+ if (msalToken) {
1433
+ msalTokenInitFlow();
1434
+ } else {
1435
+ authStore.logout();
1436
+ onUnauthorized({
1437
+ name: "Unauthorized",
1438
+ message: "MSAL Token is required"
1439
+ });
1440
+ }
1441
+ if (rememberUser) {
1442
+ authStore.restoreAuth();
1443
+ }
1480
1444
  }, []);
1445
+ useEffect(() => {
1446
+ if (useLocationStore.error) {
1447
+ getLocationErrorCallback(useLocationStore.error);
1448
+ }
1449
+ }, [useLocationStore.error]);
1450
+ return /* @__PURE__ */ React.createElement(PassgageAccessProvideContext.Provider, { value: { ...props } }, children);
1451
+ }
1452
+ var usePassgageAccessContext = () => {
1453
+ const ctx = useContext(PassgageAccessProvideContext);
1454
+ if (!ctx) {
1455
+ throw new Error(
1456
+ "usePassgageAccessContext must be used inside AuthProvider"
1457
+ );
1458
+ }
1459
+ return ctx;
1460
+ };
1461
+ var usePassgageQRScanner = (payload) => {
1462
+ const [isLoading, setIsLoading] = useState(false);
1463
+ const [error, setError] = useState(null);
1464
+ const { qrDevices } = qrScannerStore();
1465
+ const scan = async (qrCode, device) => {
1466
+ setIsLoading(true);
1467
+ setError(null);
1468
+ try {
1469
+ let qrDevice = device;
1470
+ if (!qrDevice) {
1471
+ qrDevice = qrDevices.find((item) => item.qr_code_id === qrCode);
1472
+ if (!qrDevice) {
1473
+ payload.onError?.(
1474
+ error ?? { message: "QR Device not found", success: false }
1475
+ );
1476
+ return;
1477
+ }
1478
+ }
1479
+ const result = await enteranceFlow(
1480
+ {
1481
+ device: qrDevice,
1482
+ qrCode,
1483
+ isQrCode: true
1484
+ },
1485
+ payload.options
1486
+ );
1487
+ if (!result.success) {
1488
+ payload.onError?.(result);
1489
+ } else {
1490
+ payload.onSuccess?.(result.entrance);
1491
+ }
1492
+ } catch (err) {
1493
+ const errorObj = {
1494
+ success: false,
1495
+ message: err?.message || "Qr scan failed",
1496
+ error: { code: "QR_SCAN_FAILED" }
1497
+ };
1498
+ setError(errorObj);
1499
+ payload.onError?.(errorObj);
1500
+ } finally {
1501
+ setIsLoading(false);
1502
+ }
1503
+ };
1481
1504
  return {
1482
- login,
1483
- logout,
1484
- refreshToken,
1485
- isAuthenticated,
1486
- user,
1505
+ scan,
1487
1506
  isLoading,
1507
+ error
1508
+ };
1509
+ };
1510
+ var bigInt = __require("big-integer");
1511
+ var reversedHexToDec = (reversedHex) => {
1512
+ try {
1513
+ reversedHex = reversedHex.replace(/\s+/g, "");
1514
+ let originalHex = "";
1515
+ for (let i = reversedHex.length; i > 0; i -= 2) {
1516
+ originalHex += reversedHex.substring(i - 2, i);
1517
+ }
1518
+ let decimalValue = bigInt(originalHex, 16);
1519
+ return decimalValue.toString();
1520
+ } catch (error) {
1521
+ return reversedHex;
1522
+ }
1523
+ };
1524
+ function usePassgageNFCScanner(payload) {
1525
+ const [supportNFC, setSupportNFC] = useState();
1526
+ const [isScanning, setIsScanning] = useState(false);
1527
+ const [nfcData, setNfcData] = useState();
1528
+ const { qrDevices } = qrScannerStore();
1529
+ const [error, setError] = useState(null);
1530
+ useEffect(() => {
1531
+ NfcManager.isSupported().then((supported) => {
1532
+ if (supported) {
1533
+ setSupportNFC(true);
1534
+ } else {
1535
+ setSupportNFC(false);
1536
+ }
1537
+ });
1538
+ return () => {
1539
+ NfcManager.cancelTechnologyRequest();
1540
+ };
1541
+ }, []);
1542
+ const stopScanning = async () => {
1543
+ try {
1544
+ NfcManager.cancelTechnologyRequest().finally(() => {
1545
+ setIsScanning(false);
1546
+ });
1547
+ } catch {
1548
+ }
1549
+ };
1550
+ const handleNFCTag = async (tag) => {
1551
+ if (!tag.id) {
1552
+ return;
1553
+ }
1554
+ try {
1555
+ const nfcCode = reversedHexToDec(tag.id);
1556
+ if (Platform.OS === "ios") {
1557
+ await NfcManager.cancelTechnologyRequest();
1558
+ }
1559
+ const device = qrDevices.find((device2) => device2.nfc_code === nfcCode);
1560
+ if (!device) {
1561
+ throw new Error("NFC device not found");
1562
+ }
1563
+ const result = await enteranceFlow(
1564
+ {
1565
+ device,
1566
+ nfcCode,
1567
+ isQrCode: false
1568
+ },
1569
+ payload.options
1570
+ );
1571
+ if (!result.success) {
1572
+ throw new Error(result.message);
1573
+ }
1574
+ payload.onSuccess?.(result.entrance);
1575
+ stopScanning();
1576
+ } catch (err) {
1577
+ const error2 = err;
1578
+ setError(error2);
1579
+ payload.onError?.(error2);
1580
+ stopScanning();
1581
+ }
1582
+ };
1583
+ const startScanning = async () => {
1584
+ await NfcManager.requestTechnology(NfcTech.Ndef, {
1585
+ invalidateAfterFirstRead: true
1586
+ });
1587
+ await NfcManager.getTag().then((tag) => {
1588
+ setNfcData(tag?.id ?? "");
1589
+ handleNFCTag(tag || {});
1590
+ }).catch(() => false);
1591
+ NfcManager.cancelTechnologyRequest();
1592
+ setIsScanning(true);
1593
+ setError(null);
1594
+ };
1595
+ return {
1596
+ nfcData,
1597
+ supportNFC,
1598
+ startScanning,
1599
+ stopScanning,
1488
1600
  error,
1489
- clearError
1601
+ isScanning
1490
1602
  };
1491
1603
  }
1492
-
1493
- // src/hooks/usePassgageQRScanner.ts
1494
- import { useState as useState3, useCallback as useCallback3 } from "react";
1495
-
1496
- // src/hooks/useLocation.ts
1497
- import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
1498
- import Geolocation from "@react-native-community/geolocation";
1499
1604
  function useLocation(options = {}) {
1500
- const [location, setLocation] = useState2(null);
1501
- const [error, setError] = useState2(null);
1502
- const [isLoading, setIsLoading] = useState2(true);
1605
+ const [location, setLocation] = useState(null);
1606
+ const [error, setError] = useState(null);
1607
+ const [isLoading, setIsLoading] = useState(true);
1503
1608
  const config = {
1504
1609
  enableHighAccuracy: options.enableHighAccuracy ?? true,
1505
1610
  timeout: options.timeout ?? 15e3,
1506
1611
  maximumAge: options.maximumAge ?? 1e4
1507
1612
  };
1508
- const refreshLocation = useCallback2(async () => {
1613
+ const refreshLocation = useCallback(async () => {
1509
1614
  setIsLoading(true);
1510
1615
  setError(null);
1511
1616
  return new Promise((resolve) => {
1512
- Geolocation.getCurrentPosition(
1617
+ Geolocation2.getCurrentPosition(
1513
1618
  (position) => {
1514
1619
  setLocation({
1515
1620
  latitude: position.coords.latitude,
@@ -1532,10 +1637,10 @@ function useLocation(options = {}) {
1532
1637
  );
1533
1638
  });
1534
1639
  }, [config.enableHighAccuracy, config.timeout, config.maximumAge]);
1535
- useEffect2(() => {
1640
+ useEffect(() => {
1536
1641
  refreshLocation();
1537
1642
  if (options.watchPosition) {
1538
- const watchId = Geolocation.watchPosition(
1643
+ const watchId = Geolocation2.watchPosition(
1539
1644
  (position) => {
1540
1645
  setLocation({
1541
1646
  latitude: position.coords.latitude,
@@ -1553,7 +1658,7 @@ function useLocation(options = {}) {
1553
1658
  config
1554
1659
  );
1555
1660
  return () => {
1556
- Geolocation.clearWatch(watchId);
1661
+ Geolocation2.clearWatch(watchId);
1557
1662
  };
1558
1663
  }
1559
1664
  return void 0;
@@ -1566,376 +1671,7 @@ function useLocation(options = {}) {
1566
1671
  };
1567
1672
  }
1568
1673
 
1569
- // src/hooks/usePassgageQRScanner.ts
1570
- function usePassgageQRScanner(options = {}) {
1571
- const { qrAccessService, deviceAccessService } = usePassgageAccess();
1572
- const { location } = useLocation();
1573
- const [isLoading, setIsLoading] = useState3(false);
1574
- const [error, setError] = useState3(null);
1575
- const scan = useCallback3(
1576
- async (qrCode, device) => {
1577
- setIsLoading(true);
1578
- setError(null);
1579
- try {
1580
- let qrDevice = device;
1581
- if (!qrDevice) {
1582
- qrDevice = await deviceAccessService.findDeviceByQRCode(qrCode);
1583
- if (!qrDevice) {
1584
- throw new Error("QR device not found");
1585
- }
1586
- }
1587
- const result = await qrAccessService.validateQR({
1588
- qrCode,
1589
- device: qrDevice,
1590
- userLocation: location || void 0,
1591
- skipLocationCheck: options.skipLocationCheck,
1592
- skipRepetitiveCheck: options.skipRepetitiveCheck
1593
- });
1594
- if (!result.success) {
1595
- throw new Error(result.message);
1596
- }
1597
- options.onSuccess?.(result.entrance);
1598
- } catch (err) {
1599
- const error2 = err;
1600
- setError(error2);
1601
- options.onError?.(error2);
1602
- } finally {
1603
- setIsLoading(false);
1604
- }
1605
- },
1606
- [qrAccessService, deviceAccessService, location, options]
1607
- );
1608
- return {
1609
- scan,
1610
- isLoading,
1611
- error
1612
- };
1613
- }
1614
-
1615
- // src/hooks/usePassgageNFCScanner.ts
1616
- import { useState as useState4, useCallback as useCallback4, useEffect as useEffect3 } from "react";
1617
- import NfcManager, { NfcTech } from "react-native-nfc-manager";
1618
- function reversedHexToDec(hexString) {
1619
- const hex = hexString.replace(/:/g, "");
1620
- return parseInt(hex, 16).toString();
1621
- }
1622
- function usePassgageNFCScanner(options = {}) {
1623
- const { nfcAccessService, deviceAccessService } = usePassgageAccess();
1624
- const { location } = useLocation();
1625
- const [isScanning, setIsScanning] = useState4(false);
1626
- const [error, setError] = useState4(null);
1627
- const stopScanning = useCallback4(async () => {
1628
- try {
1629
- await NfcManager.cancelTechnologyRequest();
1630
- setIsScanning(false);
1631
- } catch {
1632
- }
1633
- }, []);
1634
- const handleNFCTag = useCallback4(
1635
- async (tag) => {
1636
- if (!tag.id) {
1637
- return;
1638
- }
1639
- try {
1640
- const nfcCode = reversedHexToDec(tag.id);
1641
- const device = await deviceAccessService.findDeviceByNFCCode(nfcCode);
1642
- if (!device) {
1643
- throw new Error("NFC device not found");
1644
- }
1645
- const result = await nfcAccessService.validateNFC({
1646
- nfcCode,
1647
- device,
1648
- userLocation: location || void 0,
1649
- skipLocationCheck: options.skipLocationCheck,
1650
- skipRepetitiveCheck: options.skipRepetitiveCheck
1651
- });
1652
- if (!result.success) {
1653
- throw new Error(result.message);
1654
- }
1655
- options.onSuccess?.(result.entrance);
1656
- await stopScanning();
1657
- } catch (err) {
1658
- const error2 = err;
1659
- setError(error2);
1660
- options.onError?.(error2);
1661
- await stopScanning();
1662
- }
1663
- },
1664
- [nfcAccessService, deviceAccessService, location, options, stopScanning]
1665
- );
1666
- const startScanning = useCallback4(async () => {
1667
- setIsScanning(true);
1668
- setError(null);
1669
- try {
1670
- await NfcManager.requestTechnology(NfcTech.Ndef, {
1671
- invalidateAfterFirstRead: true
1672
- });
1673
- const tag = await NfcManager.getTag();
1674
- await handleNFCTag(tag || {});
1675
- } catch (err) {
1676
- const error2 = err;
1677
- setError(error2);
1678
- options.onError?.(error2);
1679
- setIsScanning(false);
1680
- }
1681
- }, [handleNFCTag, options]);
1682
- useEffect3(() => {
1683
- if (options.autoStart) {
1684
- startScanning();
1685
- }
1686
- return () => {
1687
- stopScanning();
1688
- };
1689
- }, [options.autoStart, startScanning, stopScanning]);
1690
- return {
1691
- startScanning,
1692
- stopScanning,
1693
- isScanning,
1694
- error
1695
- };
1696
- }
1697
-
1698
- // src/hooks/usePassgageCheckIn.ts
1699
- import { useState as useState5, useCallback as useCallback5 } from "react";
1700
- function usePassgageCheckIn(options = {}) {
1701
- const { checkInService } = usePassgageAccess();
1702
- const { location } = useLocation();
1703
- const [isLoading, setIsLoading] = useState5(false);
1704
- const [error, setError] = useState5(null);
1705
- const getNearbyBranches = useCallback5(
1706
- async (params) => {
1707
- if (!location) {
1708
- return {
1709
- success: false,
1710
- error: "Location not available"
1711
- };
1712
- }
1713
- setIsLoading(true);
1714
- setError(null);
1715
- try {
1716
- const response = await checkInService.getNearbyBranches({
1717
- latitude: location.latitude,
1718
- longitude: location.longitude,
1719
- radius: params?.radius || options.radius
1720
- });
1721
- if (response.success && response.data) {
1722
- return {
1723
- success: true,
1724
- data: response.data
1725
- };
1726
- }
1727
- return {
1728
- success: false,
1729
- error: response.message || "Failed to fetch nearby branches"
1730
- };
1731
- } catch (err) {
1732
- const error2 = err;
1733
- setError(error2);
1734
- return {
1735
- success: false,
1736
- error: error2.message || "Failed to fetch nearby branches"
1737
- };
1738
- } finally {
1739
- setIsLoading(false);
1740
- }
1741
- },
1742
- [checkInService, location, options.radius]
1743
- );
1744
- const checkInEntry = useCallback5(
1745
- async (params) => {
1746
- setIsLoading(true);
1747
- setError(null);
1748
- try {
1749
- const result = await checkInService.checkIn({
1750
- branchId: params.branchId,
1751
- userId: params.userId,
1752
- entranceType: 0 /* ENTRY */,
1753
- userLocation: location || void 0
1754
- });
1755
- if (result.success) {
1756
- return {
1757
- success: true,
1758
- data: result.entrance
1759
- };
1760
- }
1761
- return {
1762
- success: false,
1763
- error: result.message || "Check-in failed"
1764
- };
1765
- } catch (err) {
1766
- const error2 = err;
1767
- setError(error2);
1768
- return {
1769
- success: false,
1770
- error: error2.message || "Check-in failed"
1771
- };
1772
- } finally {
1773
- setIsLoading(false);
1774
- }
1775
- },
1776
- [checkInService, location]
1777
- );
1778
- const checkInExit = useCallback5(
1779
- async (params) => {
1780
- setIsLoading(true);
1781
- setError(null);
1782
- try {
1783
- const result = await checkInService.checkIn({
1784
- branchId: params.branchId,
1785
- userId: params.userId,
1786
- entranceType: 1 /* EXIT */,
1787
- userLocation: location || void 0
1788
- });
1789
- if (result.success) {
1790
- return {
1791
- success: true,
1792
- data: result.entrance
1793
- };
1794
- }
1795
- return {
1796
- success: false,
1797
- error: result.message || "Check-out failed"
1798
- };
1799
- } catch (err) {
1800
- const error2 = err;
1801
- setError(error2);
1802
- return {
1803
- success: false,
1804
- error: error2.message || "Check-out failed"
1805
- };
1806
- } finally {
1807
- setIsLoading(false);
1808
- }
1809
- },
1810
- [checkInService, location]
1811
- );
1812
- return {
1813
- getNearbyBranches,
1814
- checkInEntry,
1815
- checkInExit,
1816
- isLoading,
1817
- error
1818
- };
1819
- }
1820
-
1821
- // src/hooks/usePassgageRemoteWork.ts
1822
- import { useState as useState6, useCallback as useCallback6 } from "react";
1823
- function usePassgageRemoteWork() {
1824
- const { remoteWorkService } = usePassgageAccess();
1825
- const [isLoading, setIsLoading] = useState6(false);
1826
- const [error, setError] = useState6(null);
1827
- const logEntry = useCallback6(
1828
- async (params) => {
1829
- setIsLoading(true);
1830
- setError(null);
1831
- try {
1832
- const result = await remoteWorkService.logRemoteWork({
1833
- userId: params.userId,
1834
- entranceType: 0 /* ENTRY */,
1835
- timestamp: params.timestamp,
1836
- description: params.description
1837
- });
1838
- if (result.success) {
1839
- return {
1840
- success: true,
1841
- data: result.entrance
1842
- };
1843
- }
1844
- return {
1845
- success: false,
1846
- error: result.message || "Failed to log entry"
1847
- };
1848
- } catch (err) {
1849
- const error2 = err;
1850
- setError(error2);
1851
- return {
1852
- success: false,
1853
- error: error2.message || "Failed to log entry"
1854
- };
1855
- } finally {
1856
- setIsLoading(false);
1857
- }
1858
- },
1859
- [remoteWorkService]
1860
- );
1861
- const logExit = useCallback6(
1862
- async (params) => {
1863
- setIsLoading(true);
1864
- setError(null);
1865
- try {
1866
- const result = await remoteWorkService.logRemoteWork({
1867
- userId: params.userId,
1868
- entranceType: 1 /* EXIT */,
1869
- timestamp: params.timestamp,
1870
- description: params.description
1871
- });
1872
- if (result.success) {
1873
- return {
1874
- success: true,
1875
- data: result.entrance
1876
- };
1877
- }
1878
- return {
1879
- success: false,
1880
- error: result.message || "Failed to log exit"
1881
- };
1882
- } catch (err) {
1883
- const error2 = err;
1884
- setError(error2);
1885
- return {
1886
- success: false,
1887
- error: error2.message || "Failed to log exit"
1888
- };
1889
- } finally {
1890
- setIsLoading(false);
1891
- }
1892
- },
1893
- [remoteWorkService]
1894
- );
1895
- return {
1896
- logEntry,
1897
- logExit,
1898
- isLoading,
1899
- error
1900
- };
1901
- }
1902
-
1903
1674
  // src/index.ts
1904
1675
  var SDK_VERSION = "1.0.4";
1905
- export {
1906
- ApiClient,
1907
- AuthService,
1908
- CheckInService,
1909
- DeviceAccessService,
1910
- DeviceDirection,
1911
- DeviceUsage,
1912
- endpoints_exports as Endpoints,
1913
- EntranceType,
1914
- LocationService,
1915
- NFCAccessService,
1916
- PassgageAccessProvider,
1917
- QRAccessService,
1918
- RemoteWorkService,
1919
- SDK_VERSION,
1920
- calculateDistance,
1921
- checkOnLocation,
1922
- checkRepetitiveRead,
1923
- clearReadRecords,
1924
- createApiClient,
1925
- formatDate,
1926
- formatDateTime,
1927
- formatISO,
1928
- formatTime,
1929
- parseISO,
1930
- useLocation,
1931
- usePassgageAccess,
1932
- usePassgageAuth,
1933
- usePassgageCheckIn,
1934
- usePassgageNFCScanner,
1935
- usePassgageQRScanner,
1936
- usePassgageRemoteWork,
1937
- validateCoordinates,
1938
- validateDeviceId,
1939
- validateNFCCode,
1940
- validateQRCode
1941
- };
1676
+
1677
+ export { ApiClient, AuthService, DeviceAccessService, DeviceDirection, DeviceUsage, endpoints_exports as Endpoints, EntranceType, LocationService, NfcAccessService, PassgageAccessProvider, QRAccessService, SDK_VERSION, addQrReadRecord, calculateDistance, checkOnLocation, checkRepetitiveRead, clearReadRecords, createApiClient, formatDate, formatDateTime, formatISO, formatTime, parseISO, reversedHexToDec, shouldValidateLocation, useLocation, usePassgageAccessContext, usePassgageNFCScanner, usePassgageQRScanner, validateCoordinates, validateDeviceId, validateLocation, validateNFCCode, validateQRCode };