@convep_mobilogy/react-native-qms-plugin 1.7.0 → 1.8.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 (28) hide show
  1. package/android/build.gradle +1 -1
  2. package/ios/QmsPlugin/QmsDashboardViewManager.mm +95 -53
  3. package/ios/QmsPlugin/QmsModule.mm +24 -1
  4. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Assets.car +0 -0
  5. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Headers/QmsPlugin.h +30 -0
  6. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
  7. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
  8. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
  9. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
  10. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
  11. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
  12. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
  13. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/QmsPluginFramework +0 -0
  14. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/_CodeSignature/CodeResources +83 -6
  15. package/ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/en.json +4 -4
  16. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Assets.car +0 -0
  17. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Headers/QmsPlugin.h +30 -0
  18. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-BoldItalic.ttf +0 -0
  19. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraBold.ttf +0 -0
  20. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-ExtraLight.ttf +0 -0
  21. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Italic.ttf +0 -0
  22. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Light.ttf +0 -0
  23. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-SemiBold.ttf +0 -0
  24. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/Montserrat-Thin.ttf +0 -0
  25. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/QmsPluginFramework +0 -0
  26. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/_CodeSignature/CodeResources +83 -6
  27. package/ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/en.json +4 -4
  28. package/package.json +1 -1
@@ -75,7 +75,7 @@ dependencies {
75
75
  implementation "com.facebook.react:react-android"
76
76
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
77
  implementation 'com.facebook.react:react-native:+'
78
- implementation "com.convep.qms:qms-plugin:1.24.0"
78
+ implementation "com.convep.qms:qms-plugin:1.25.1"
79
79
 
80
80
  implementation 'androidx.appcompat:appcompat:1.6.1'
81
81
 
@@ -3,6 +3,12 @@
3
3
  #import <QmsPluginFramework/QmsPluginFramework.h>
4
4
  #import <QmsPluginFramework/QmsPlugin.h>
5
5
 
6
+ // Forward declaration — QmsModule is defined in QmsModule.mm (same plugin target).
7
+ // We only need the class-method signature here; no header required.
8
+ @interface QmsModule : NSObject
9
+ + (nullable NSDictionary *)drainPendingLocalNotificationPayload;
10
+ @end
11
+
6
12
  static NSString * const kQmsThemePrimaryColorKey = @"QmsThemePrimaryColor";
7
13
  static NSString * const kQmsThemeHeaderTextColorKey = @"QmsThemeHeaderTextColor";
8
14
  static NSString * const kQmsThemeAccentColorKey = @"QmsThemeAccentColor";
@@ -120,6 +126,18 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
120
126
  [self forwardPropsToVC];
121
127
  [self routePayloadIfNeeded:self.payload force:NO];
122
128
  [self applyAllThemeImmediatelyIfNeeded];
129
+
130
+ // 3️⃣ Drain any pending local-notification payload (cold-launch tap).
131
+ // AppDelegate stores draft_reminder payloads in NSUserDefaults before
132
+ // this view exists; we pick them up here and route them exactly like
133
+ // any other payload — after a short delay so the VC hierarchy settles.
134
+ NSDictionary *pendingLocalPayload = [QmsModule drainPendingLocalNotificationPayload];
135
+ if (pendingLocalPayload) {
136
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)),
137
+ dispatch_get_main_queue(), ^{
138
+ [self routePayloadIfNeeded:pendingLocalPayload force:YES];
139
+ });
140
+ }
123
141
  }
124
142
  }
125
143
  }
@@ -293,6 +311,10 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
293
311
  [type isEqualToString:@"unattend_appt_reminder"];
294
312
  }
295
313
 
314
+ - (BOOL)isDraftReminderType:(NSString *)type {
315
+ return [type isEqualToString:@"draft_reminder"];
316
+ }
317
+
296
318
  - (void)applyPayloadContext:(NSDictionary *)payload {
297
319
  Class apiConfig = NSClassFromString(@"APIConfig");
298
320
  if (!apiConfig) return;
@@ -380,90 +402,110 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
380
402
  }
381
403
 
382
404
  - (void)presentIssueDetailViewControllerWithPayload:(NSDictionary *)payload title:(NSString *)title {
383
- // Class cls = NSClassFromString(@"IssueDetailViewController");
384
- //temp fix for now
385
- Class cls = NSClassFromString(@"IssuesViewController");
386
-
387
- if (!cls) return;
388
- UIViewController *vc = [[cls alloc] init];
389
- if (!vc) return;
390
- [self applyProjectContext:vc payload:payload title:title];
391
- NSString *issueId = [self stringFromPayload:payload key:@"issue_id"];
392
- if (issueId.length > 0) {
393
- @try { [vc setValue:issueId forKey:@"deepLinkIssueId"]; }
394
- @catch (__unused NSException *e) {}
395
- }
396
- [self presentDeepLinkVC:vc];
405
+ UIViewController *presenter = self.dashboardVC;
406
+ if (!presenter) return;
407
+ [QmsPluginUI presentIssueFromPayload:payload fromViewController:presenter];
397
408
  }
398
409
 
399
410
  - (void)presentAppointmentDetailsViewControllerWithPayload:(NSDictionary *)payload title:(NSString *)title {
400
- // Class cls = NSClassFromString(@"AppointmentDetailsViewController");
401
- //temp fix for now
402
- Class cls = NSClassFromString(@"AppointmentViewMoreViewController");
403
- if (!cls) return;
404
- UIViewController *vc = [[cls alloc] init];
405
- if (!vc) return;
406
- [self applyProjectContext:vc payload:payload title:title];
407
-
408
- // Pass the appointment ID so the VC can fetch its own data.
409
- // The deep-link payload carries "appointment_id" (or "id" as a fallback).
410
- NSString *appointmentIdStr = [self stringFromPayload:payload key:@"appointment_id"]
411
- ?: [self stringFromPayload:payload key:@"id"];
412
- if (appointmentIdStr.length > 0) {
413
- NSNumber *appointmentId = @([appointmentIdStr integerValue]);
414
- @try { [vc setValue:appointmentId forKey:@"appointmentId"]; }
415
- @catch (__unused NSException *e) {}
416
- }
417
- [self presentDeepLinkVC:vc];
411
+ // Delegates to QmsPluginUI which primes APIConfig (project_id / plan_id) before
412
+ // presenting AppointmentDetailsViewController — same pattern as the dashboard deep-link.
413
+ UIViewController *presenter = self.dashboardVC;
414
+ if (!presenter) return;
415
+ [QmsPluginUI presentAppointmentFromPayload:payload fromViewController:presenter];
418
416
  }
419
417
 
420
418
  - (void)presentDashboardViewControllerWithPayload:(NSDictionary *)payload title:(NSString *)title {
421
- Class cls = NSClassFromString(@"DashboardViewController");
422
- if (!cls) return;
419
+ // Fetch the project list, find the matching project + unit by project_id/plan_id,
420
+ // and present a fully-configured DashboardViewController — same as the normal
421
+ // ProjectViewController → UnitViewController → DashboardViewController flow.
422
+ // The loading overlay and modal presentation are managed inside the framework method.
423
+ UIViewController *presenter = self.dashboardVC;
424
+ if (!presenter) return;
425
+ [QmsPluginUI presentDashboardFromPayload:payload fromViewController:presenter];
426
+ }
427
+
428
+ - (void)presentDraftListingViewControllerWithPayload:(NSDictionary *)payload {
429
+ UIViewController *presenter = self.dashboardVC;
430
+ if (!presenter) return;
431
+
432
+ Class cls = NSClassFromString(@"DraftListingViewController");
433
+ if (!cls) {
434
+ NSLog(@"🧭 [DraftReminder] DraftListingViewController class not found");
435
+ return;
436
+ }
437
+
423
438
  UIViewController *vc = [[cls alloc] init];
424
439
  if (!vc) return;
425
- // DashboardViewController uses unitID/unitName instead of projectCode/projectName.
426
- @try {
427
- NSString *projName = [self projectNameFromTitle:title];
428
- NSString *projectId = [self stringFromPayload:payload key:@"project_id"];
429
- if (projName.length > 0) [vc setValue:projName forKey:@"unitName"];
430
- if (projectId.length > 0) [vc setValue:projectId forKey:@"unitID"];
431
- } @catch (__unused NSException *e) {}
440
+
441
+ // Pass project name if available so the listing filters to the right project
442
+ NSString *projectName = payload[@"project_name"];
443
+ if (projectName.length > 0) {
444
+ @try { [vc setValue:projectName forKey:@"projectName"]; }
445
+ @catch (__unused NSException *e) {}
446
+ }
447
+
432
448
  [self presentDeepLinkVC:vc];
433
449
  }
434
450
 
435
451
  - (void)routePayloadIfNeeded:(NSDictionary *)payload force:(BOOL)force {
436
- if (![payload isKindOfClass:[NSDictionary class]] || payload.count == 0) return;
437
- if (!_didSetupVC || !self.dashboardVC) return;
438
- if (_didRouteInitialPayload && !force) return;
452
+ NSLog(@"🧭 [QmsDashboardView] routePayloadIfNeeded — force=%d payload.count=%lu _didSetupVC=%d _didRouteInitialPayload=%d",
453
+ force, (unsigned long)payload.count, _didSetupVC, _didRouteInitialPayload);
454
+
455
+ if (![payload isKindOfClass:[NSDictionary class]] || payload.count == 0) {
456
+ NSLog(@"⚠️ [QmsDashboardView] routePayloadIfNeeded: payload invalid/empty — bailing");
457
+ return;
458
+ }
459
+ if (!_didSetupVC || !self.dashboardVC) {
460
+ NSLog(@"⚠️ [QmsDashboardView] routePayloadIfNeeded: VC not ready yet (_didSetupVC=%d dashboardVC=%@) — bailing",
461
+ _didSetupVC, self.dashboardVC ? @"exists" : @"nil");
462
+ return;
463
+ }
464
+ if (_didRouteInitialPayload && !force) {
465
+ NSLog(@"⚠️ [QmsDashboardView] routePayloadIfNeeded: already routed and force=NO — bailing");
466
+ return;
467
+ }
439
468
 
440
469
  _didRouteInitialPayload = YES;
441
470
  [self applyPayloadContext:payload];
442
471
 
443
472
  NSString *type = [self stringFromPayload:payload key:@"type"];
444
473
  NSString *title = [self stringFromPayload:payload key:@"title"];
445
- NSLog(@"🧭 routePayloadIfNeeded type=%@ project_id=%@ plan_id=%@ title=%@",
446
- type ?: @"",
447
- [self stringFromPayload:payload key:@"project_id"] ?: @"",
448
- [self stringFromPayload:payload key:@"plan_id"] ?: @"",
449
- title ?: @"");
474
+ NSLog(@"🧭 [QmsDashboardView] routePayloadIfNeeded — type=%@ project_id=%@ plan_id=%@ issue_id=%@ appointment_id=%@ title=%@",
475
+ type ?: @"(none)",
476
+ [self stringFromPayload:payload key:@"project_id"] ?: @"(none)",
477
+ [self stringFromPayload:payload key:@"plan_id"] ?: @"(none)",
478
+ [self stringFromPayload:payload key:@"issue_id"] ?: @"(none)",
479
+ [self stringFromPayload:payload key:@"appointment_id"] ?: @"(none)",
480
+ title ?: @"(none)");
450
481
 
451
482
  if ([self isIssueType:type]) {
452
- NSLog(@"🧭 routing issue type → IssueDetailViewController");
483
+ NSLog(@"🧭 [QmsDashboardView] routing → presentIssueFromPayload (issue type: %@)", type);
453
484
  [self presentIssueDetailViewControllerWithPayload:payload title:title ?: @""];
454
485
  } else if ([self isAppointmentType:type]) {
455
- NSLog(@"🧭 routing appointment type → AppointmentDetailsViewController");
486
+ NSLog(@"🧭 [QmsDashboardView] routing → presentAppointmentFromPayload (appointment type: %@)", type);
456
487
  [self presentAppointmentDetailsViewControllerWithPayload:payload title:title ?: @""];
457
488
  } else if ([type isEqualToString:@"clearance_letter"]) {
458
- NSLog(@"🧭 routing clearance_letter → DashboardViewController");
489
+ NSLog(@"🧭 [QmsDashboardView] routing → presentDashboardFromPayload (clearance_letter)");
490
+ [self presentDashboardViewControllerWithPayload:payload title:title ?: @""];
491
+ } else if ([self isDraftReminderType:type]) {
492
+ NSLog(@"🧭 [QmsDashboardView] routing → presentDraftListingViewController (draft_reminder)");
493
+ // [self presentDraftListingViewControllerWithPayload:payload];
459
494
  [self presentDashboardViewControllerWithPayload:payload title:title ?: @""];
460
495
  } else {
461
- NSLog(@"🧭 no route matched for type=%@", type ?: @"");
496
+ NSLog(@"🧭 [QmsDashboardView] routePayloadIfNeeded — no route matched for type=%@", type ?: @"(none)");
462
497
  }
463
498
  }
464
499
 
465
500
  - (void)handleRoutePayloadNotification:(NSNotification *)note {
501
+ NSLog(@"📬 [QmsDashboardView] handleRoutePayloadNotification received — userInfo class=%@", NSStringFromClass([note.userInfo class]));
466
502
  NSDictionary *payload = [note.userInfo isKindOfClass:[NSDictionary class]] ? note.userInfo : nil;
503
+ if (!payload) {
504
+ NSLog(@"⚠️ [QmsDashboardView] handleRoutePayloadNotification: userInfo is not a dict, dropping");
505
+ return;
506
+ }
507
+ NSLog(@"📬 [QmsDashboardView] handleRoutePayloadNotification — _didSetupVC=%d dashboardVC=%@",
508
+ _didSetupVC, _dashboardVC ? @"exists" : @"nil");
467
509
  [self routePayloadIfNeeded:payload force:YES];
468
510
  }
469
511
 
@@ -11,6 +11,7 @@ static NSString * const kQmsThemeHeaderIconColorKey = @"QmsThemeHeaderIconColor"
11
11
  static NSString * const kQmsThemeAccentColorKey = @"QmsThemeAccentColor";
12
12
  static NSString * const kQmsThemeFontFamilyKey = @"QmsThemeFontFamily";
13
13
  static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotification";
14
+ static NSString * const kQmsPendingLocalNotifKey = @"QmsPendingLocalNotificationPayload";
14
15
 
15
16
  @interface QmsModule : NSObject <RCTBridgeModule>
16
17
  @property (nonatomic, strong) UIView *bannerView;
@@ -20,6 +21,17 @@ static NSString * const kQmsRoutePayloadNotification = @"QmsRoutePayloadNotifica
20
21
 
21
22
  RCT_EXPORT_MODULE(QmsModule)
22
23
 
24
+ /// Drain the pending local-notification payload written by AppDelegate on cold-launch tap.
25
+ /// Returns nil (and removes the stored value) if nothing is pending.
26
+ + (nullable NSDictionary *)drainPendingLocalNotificationPayload {
27
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
28
+ id stored = [ud objectForKey:kQmsPendingLocalNotifKey];
29
+ if (![stored isKindOfClass:[NSDictionary class]]) return nil;
30
+ [ud removeObjectForKey:kQmsPendingLocalNotifKey];
31
+ NSLog(@"📬 [QmsModule] Drained pending local notification payload: %@", stored);
32
+ return (NSDictionary *)stored;
33
+ }
34
+
23
35
  - (dispatch_queue_t)methodQueue {
24
36
  return dispatch_get_main_queue();
25
37
  }
@@ -60,7 +72,18 @@ RCT_EXPORT_MODULE(QmsModule)
60
72
  }
61
73
 
62
74
  - (void)routePayload:(NSDictionary *)payload {
63
- if (![payload isKindOfClass:[NSDictionary class]] || payload.count == 0) return;
75
+ NSLog(@"📨 [QmsModule] routePayload called — payload class=%@", NSStringFromClass([payload class]));
76
+ if (![payload isKindOfClass:[NSDictionary class]] || payload.count == 0) {
77
+ NSLog(@"⚠️ [QmsModule] routePayload: invalid or empty payload, aborting");
78
+ return;
79
+ }
80
+ NSLog(@"📨 [QmsModule] routePayload posting QmsRoutePayloadNotification — type=%@ project_id=%@ plan_id=%@ issue_id=%@ appointment_id=%@",
81
+ payload[@"type"] ?: payload[@"data"][@"type"] ?: @"(none)",
82
+ payload[@"project_id"] ?: payload[@"data"][@"project_id"] ?: @"(none)",
83
+ payload[@"plan_id"] ?: payload[@"data"][@"plan_id"] ?: @"(none)",
84
+ payload[@"issue_id"] ?: payload[@"data"][@"issue_id"] ?: @"(none)",
85
+ payload[@"appointment_id"] ?: payload[@"data"][@"appointment_id"] ?: @"(none)");
86
+ NSLog(@"📨 [QmsModule] full payload: %@", payload);
64
87
  [[NSNotificationCenter defaultCenter] postNotificationName:kQmsRoutePayloadNotification
65
88
  object:nil
66
89
  userInfo:payload];
@@ -8,6 +8,36 @@ NS_ASSUME_NONNULL_BEGIN
8
8
 
9
9
  + (UIViewController *)makeViewController;
10
10
 
11
+ /// Fetches project list data and presents DashboardViewController fully configured
12
+ /// for the given FCM deep-link payload. The payload must contain at minimum
13
+ /// `project_id` and `plan_id`. Auth/base-URL must already be configured in APIConfig
14
+ /// (i.e. the SDK has already been initialised by the user opening the app).
15
+ ///
16
+ /// @param payload The FCM notification data dictionary.
17
+ /// @param presenter The view controller from which the dashboard will be presented modally.
18
+ + (void)presentDashboardFromPayload:(NSDictionary *)payload
19
+ fromViewController:(UIViewController *)presenter;
20
+
21
+ /// Configures APIConfig with the project/plan context from the payload, then
22
+ /// presents AppointmentDetailsViewController modally. The payload must contain
23
+ /// `project_id`, `plan_id`, and `appointment_id` (or `id` as a fallback).
24
+ /// Auth/base-URL must already be configured in APIConfig.
25
+ ///
26
+ /// @param payload The FCM notification data dictionary.
27
+ /// @param presenter The view controller from which the appointment screen will be presented.
28
+ + (void)presentAppointmentFromPayload:(NSDictionary *)payload
29
+ fromViewController:(UIViewController *)presenter;
30
+
31
+ /// Fetches the issue list, finds the matching issue by `issue_id` from the payload,
32
+ /// and presents IssueDetailViewController fully configured. The payload must contain
33
+ /// at minimum `project_id`, `plan_id`, and `issue_id`. Auth/base-URL must already
34
+ /// be configured in APIConfig.
35
+ ///
36
+ /// @param payload The FCM notification data dictionary.
37
+ /// @param presenter The view controller from which the issue screen will be presented.
38
+ + (void)presentIssueFromPayload:(NSDictionary *)payload
39
+ fromViewController:(UIViewController *)presenter;
40
+
11
41
  @end
12
42
 
13
43
  NS_ASSUME_NONNULL_END
@@ -6,11 +6,11 @@
6
6
  <dict>
7
7
  <key>Assets.car</key>
8
8
  <data>
9
- fjJF2g7Dr6PYcAtKjkhFisFZtwo=
9
+ TWfalcvk3qO6mG21qB5bdrcMBjM=
10
10
  </data>
11
11
  <key>Headers/QmsPlugin.h</key>
12
12
  <data>
13
- 46196FWEMwEuy8Dd/6jLyvdFEok=
13
+ /jmzwY1kiBwDfgZJ8i6EPSgavTU=
14
14
  </data>
15
15
  <key>Headers/QmsPluginFramework.h</key>
16
16
  <data>
@@ -28,6 +28,26 @@
28
28
  <data>
29
29
  vnwUOAcKtjfhFxaRXk5QkDcm3Mg=
30
30
  </data>
31
+ <key>Montserrat-BoldItalic.ttf</key>
32
+ <data>
33
+ zTeJrlXMcCd2r90v0aga4Wxp+/Q=
34
+ </data>
35
+ <key>Montserrat-ExtraBold.ttf</key>
36
+ <data>
37
+ hPFnduIJnTtX2O0jm3bm+jKEsuc=
38
+ </data>
39
+ <key>Montserrat-ExtraLight.ttf</key>
40
+ <data>
41
+ zHokqGLxd5vbv3immEu5rpMkoSg=
42
+ </data>
43
+ <key>Montserrat-Italic.ttf</key>
44
+ <data>
45
+ rvTmoa8YSWRM4ek0tKuQWekW2Ic=
46
+ </data>
47
+ <key>Montserrat-Light.ttf</key>
48
+ <data>
49
+ M5fNmOUTZcielc0RMOAUG9pQUd4=
50
+ </data>
31
51
  <key>Montserrat-Medium.ttf</key>
32
52
  <data>
33
53
  d/NVNBXYWMZTuupFqsqyAZZ3YzQ=
@@ -36,6 +56,14 @@
36
56
  <data>
37
57
  7BPvHyyZ+HgNby6z+fJ++J8wFhs=
38
58
  </data>
59
+ <key>Montserrat-SemiBold.ttf</key>
60
+ <data>
61
+ efdGFtaLh9bPiXmP5yJZA2MmVno=
62
+ </data>
63
+ <key>Montserrat-Thin.ttf</key>
64
+ <data>
65
+ VQ5uHZkjael+nwCqca5IKmpjJtc=
66
+ </data>
39
67
  <key>bm.json</key>
40
68
  <data>
41
69
  J8m1xUyQbIm7FjEl6dgNTLhSBVU=
@@ -46,7 +74,7 @@
46
74
  </data>
47
75
  <key>en.json</key>
48
76
  <data>
49
- VVzs7WooJcpgIgoeBEO/MWoK1Jo=
77
+ VeWo6AyHrREEY0vQ5PaYJwdMY1g=
50
78
  </data>
51
79
  </dict>
52
80
  <key>files2</key>
@@ -55,14 +83,14 @@
55
83
  <dict>
56
84
  <key>hash2</key>
57
85
  <data>
58
- ruOPkgStvsoXTtWqWY1ZAjNWMXEpbI/trZfA6nErsP8=
86
+ 6l4RTp5ZrLIp0kzkUpLOxcL0TNvCePYwUcTD/aPlyG4=
59
87
  </data>
60
88
  </dict>
61
89
  <key>Headers/QmsPlugin.h</key>
62
90
  <dict>
63
91
  <key>hash2</key>
64
92
  <data>
65
- uuQ2Omt7lnrShVFriPpMiXZhx8kx6Km97GxC3m1ro+A=
93
+ 5YE/tWhfpg+TSsnziCLpEp2m4bzkKkH4oKHM990abTc=
66
94
  </data>
67
95
  </dict>
68
96
  <key>Headers/QmsPluginFramework.h</key>
@@ -86,6 +114,41 @@
86
114
  f6k9fapcL4gaZycinCEXgt5rdgCPvWNGs9dmTo/IP0M=
87
115
  </data>
88
116
  </dict>
117
+ <key>Montserrat-BoldItalic.ttf</key>
118
+ <dict>
119
+ <key>hash2</key>
120
+ <data>
121
+ ABpZsPLFQQgAM7g8pt+szgMJXZnKo1lINfUbfG2c51g=
122
+ </data>
123
+ </dict>
124
+ <key>Montserrat-ExtraBold.ttf</key>
125
+ <dict>
126
+ <key>hash2</key>
127
+ <data>
128
+ XPCiMTPMzjX54RW427+QQ0IBgnvCRl0S+dkbvwLPlGY=
129
+ </data>
130
+ </dict>
131
+ <key>Montserrat-ExtraLight.ttf</key>
132
+ <dict>
133
+ <key>hash2</key>
134
+ <data>
135
+ GsDgBpJUjjFCENEGGd5lYiVFf9RcebVtJCzfc5z3J48=
136
+ </data>
137
+ </dict>
138
+ <key>Montserrat-Italic.ttf</key>
139
+ <dict>
140
+ <key>hash2</key>
141
+ <data>
142
+ fofA+Ws5+7kZswrviZEyPQsldknzkeZFa88DwjFEj0k=
143
+ </data>
144
+ </dict>
145
+ <key>Montserrat-Light.ttf</key>
146
+ <dict>
147
+ <key>hash2</key>
148
+ <data>
149
+ lj13LJxEs8QBslfWk60mAG/HvVQhWVfVE1a0DjY1P4Q=
150
+ </data>
151
+ </dict>
89
152
  <key>Montserrat-Medium.ttf</key>
90
153
  <dict>
91
154
  <key>hash2</key>
@@ -100,6 +163,20 @@
100
163
  75z5nwF1vvUwuIk0vZBPz1b3c87G/U37jMr3ziu9OV4=
101
164
  </data>
102
165
  </dict>
166
+ <key>Montserrat-SemiBold.ttf</key>
167
+ <dict>
168
+ <key>hash2</key>
169
+ <data>
170
+ nE2zgUh1QQ59ZP3I5pZ2w7hJaLsVvzrOizlExZ+8VrY=
171
+ </data>
172
+ </dict>
173
+ <key>Montserrat-Thin.ttf</key>
174
+ <dict>
175
+ <key>hash2</key>
176
+ <data>
177
+ qMAnFkOz0iN+EeE+5ZACTUmzW3dgFJWOYP5hV8P1I/o=
178
+ </data>
179
+ </dict>
103
180
  <key>bm.json</key>
104
181
  <dict>
105
182
  <key>hash2</key>
@@ -118,7 +195,7 @@
118
195
  <dict>
119
196
  <key>hash2</key>
120
197
  <data>
121
- J+yu4eRtwfh0rvCBzxhG7H7PpaBcDv9V13qZ8TRhBmU=
198
+ 1loRLBPvXhMxef8cbl/CEpfB0j0axeW+shU+jSRHK8w=
122
199
  </data>
123
200
  </dict>
124
201
  </dict>
@@ -524,11 +524,11 @@
524
524
  "SIGN_UP_SUBTITLE": "Please enter required details to continue.",
525
525
  "APPOINTMENT_FOR_UNIT": "Appointment for unit",
526
526
  "STEP_1": "Step 1/3",
527
- "STEP_1_TITLE": "Select your preferred date",
527
+ "STEP_1_TITLE": "Select your preferred date.",
528
528
  "STEP_2": " Step 2/3",
529
- "STEP_2_TITLE": "Select your preferred time",
529
+ "STEP_2_TITLE": "Select your preferred time.",
530
530
  "STEP_3": "Step 3/3",
531
- "STEP_3_TITLE": "Confirm your appointment",
531
+ "STEP_3_TITLE": "Confirm your appointment.",
532
532
  "OWNER_SIGN_UP": "Owner Sign Up",
533
533
  "NO_RECORD_FOUND": "No Record Found",
534
534
  "ASK_CS": "Would you like our Customer Support Team to contact you",
@@ -724,7 +724,7 @@
724
724
  "ISSUES_SELECTED": "Issue(s) selected",
725
725
  "ENTER_REMARKS_HERE": "Enter remarks here...",
726
726
  "WITHDRAWING": "Withdrawing",
727
- "WITHDRAW_ALERT_MESSAGE": "Confirm to withdraw issue?",
727
+ "WITHDRAW_ALERT_MESSAGE": "Confirm to withdraw this issue?",
728
728
  "WITHDRAW_ISSUES_SUCCESS_LABEL": "You have succesfully withdrawn",
729
729
  "FILTER_ISSUE_LIST": "Filter Issue",
730
730
  "APPLY": "Apply",
@@ -8,6 +8,36 @@ NS_ASSUME_NONNULL_BEGIN
8
8
 
9
9
  + (UIViewController *)makeViewController;
10
10
 
11
+ /// Fetches project list data and presents DashboardViewController fully configured
12
+ /// for the given FCM deep-link payload. The payload must contain at minimum
13
+ /// `project_id` and `plan_id`. Auth/base-URL must already be configured in APIConfig
14
+ /// (i.e. the SDK has already been initialised by the user opening the app).
15
+ ///
16
+ /// @param payload The FCM notification data dictionary.
17
+ /// @param presenter The view controller from which the dashboard will be presented modally.
18
+ + (void)presentDashboardFromPayload:(NSDictionary *)payload
19
+ fromViewController:(UIViewController *)presenter;
20
+
21
+ /// Configures APIConfig with the project/plan context from the payload, then
22
+ /// presents AppointmentDetailsViewController modally. The payload must contain
23
+ /// `project_id`, `plan_id`, and `appointment_id` (or `id` as a fallback).
24
+ /// Auth/base-URL must already be configured in APIConfig.
25
+ ///
26
+ /// @param payload The FCM notification data dictionary.
27
+ /// @param presenter The view controller from which the appointment screen will be presented.
28
+ + (void)presentAppointmentFromPayload:(NSDictionary *)payload
29
+ fromViewController:(UIViewController *)presenter;
30
+
31
+ /// Fetches the issue list, finds the matching issue by `issue_id` from the payload,
32
+ /// and presents IssueDetailViewController fully configured. The payload must contain
33
+ /// at minimum `project_id`, `plan_id`, and `issue_id`. Auth/base-URL must already
34
+ /// be configured in APIConfig.
35
+ ///
36
+ /// @param payload The FCM notification data dictionary.
37
+ /// @param presenter The view controller from which the issue screen will be presented.
38
+ + (void)presentIssueFromPayload:(NSDictionary *)payload
39
+ fromViewController:(UIViewController *)presenter;
40
+
11
41
  @end
12
42
 
13
43
  NS_ASSUME_NONNULL_END
@@ -6,11 +6,11 @@
6
6
  <dict>
7
7
  <key>Assets.car</key>
8
8
  <data>
9
- fjJF2g7Dr6PYcAtKjkhFisFZtwo=
9
+ TWfalcvk3qO6mG21qB5bdrcMBjM=
10
10
  </data>
11
11
  <key>Headers/QmsPlugin.h</key>
12
12
  <data>
13
- 46196FWEMwEuy8Dd/6jLyvdFEok=
13
+ /jmzwY1kiBwDfgZJ8i6EPSgavTU=
14
14
  </data>
15
15
  <key>Headers/QmsPluginFramework.h</key>
16
16
  <data>
@@ -28,6 +28,26 @@
28
28
  <data>
29
29
  vnwUOAcKtjfhFxaRXk5QkDcm3Mg=
30
30
  </data>
31
+ <key>Montserrat-BoldItalic.ttf</key>
32
+ <data>
33
+ zTeJrlXMcCd2r90v0aga4Wxp+/Q=
34
+ </data>
35
+ <key>Montserrat-ExtraBold.ttf</key>
36
+ <data>
37
+ hPFnduIJnTtX2O0jm3bm+jKEsuc=
38
+ </data>
39
+ <key>Montserrat-ExtraLight.ttf</key>
40
+ <data>
41
+ zHokqGLxd5vbv3immEu5rpMkoSg=
42
+ </data>
43
+ <key>Montserrat-Italic.ttf</key>
44
+ <data>
45
+ rvTmoa8YSWRM4ek0tKuQWekW2Ic=
46
+ </data>
47
+ <key>Montserrat-Light.ttf</key>
48
+ <data>
49
+ M5fNmOUTZcielc0RMOAUG9pQUd4=
50
+ </data>
31
51
  <key>Montserrat-Medium.ttf</key>
32
52
  <data>
33
53
  d/NVNBXYWMZTuupFqsqyAZZ3YzQ=
@@ -36,6 +56,14 @@
36
56
  <data>
37
57
  7BPvHyyZ+HgNby6z+fJ++J8wFhs=
38
58
  </data>
59
+ <key>Montserrat-SemiBold.ttf</key>
60
+ <data>
61
+ efdGFtaLh9bPiXmP5yJZA2MmVno=
62
+ </data>
63
+ <key>Montserrat-Thin.ttf</key>
64
+ <data>
65
+ VQ5uHZkjael+nwCqca5IKmpjJtc=
66
+ </data>
39
67
  <key>bm.json</key>
40
68
  <data>
41
69
  J8m1xUyQbIm7FjEl6dgNTLhSBVU=
@@ -46,7 +74,7 @@
46
74
  </data>
47
75
  <key>en.json</key>
48
76
  <data>
49
- VVzs7WooJcpgIgoeBEO/MWoK1Jo=
77
+ VeWo6AyHrREEY0vQ5PaYJwdMY1g=
50
78
  </data>
51
79
  </dict>
52
80
  <key>files2</key>
@@ -55,14 +83,14 @@
55
83
  <dict>
56
84
  <key>hash2</key>
57
85
  <data>
58
- ruOPkgStvsoXTtWqWY1ZAjNWMXEpbI/trZfA6nErsP8=
86
+ 6l4RTp5ZrLIp0kzkUpLOxcL0TNvCePYwUcTD/aPlyG4=
59
87
  </data>
60
88
  </dict>
61
89
  <key>Headers/QmsPlugin.h</key>
62
90
  <dict>
63
91
  <key>hash2</key>
64
92
  <data>
65
- uuQ2Omt7lnrShVFriPpMiXZhx8kx6Km97GxC3m1ro+A=
93
+ 5YE/tWhfpg+TSsnziCLpEp2m4bzkKkH4oKHM990abTc=
66
94
  </data>
67
95
  </dict>
68
96
  <key>Headers/QmsPluginFramework.h</key>
@@ -86,6 +114,41 @@
86
114
  f6k9fapcL4gaZycinCEXgt5rdgCPvWNGs9dmTo/IP0M=
87
115
  </data>
88
116
  </dict>
117
+ <key>Montserrat-BoldItalic.ttf</key>
118
+ <dict>
119
+ <key>hash2</key>
120
+ <data>
121
+ ABpZsPLFQQgAM7g8pt+szgMJXZnKo1lINfUbfG2c51g=
122
+ </data>
123
+ </dict>
124
+ <key>Montserrat-ExtraBold.ttf</key>
125
+ <dict>
126
+ <key>hash2</key>
127
+ <data>
128
+ XPCiMTPMzjX54RW427+QQ0IBgnvCRl0S+dkbvwLPlGY=
129
+ </data>
130
+ </dict>
131
+ <key>Montserrat-ExtraLight.ttf</key>
132
+ <dict>
133
+ <key>hash2</key>
134
+ <data>
135
+ GsDgBpJUjjFCENEGGd5lYiVFf9RcebVtJCzfc5z3J48=
136
+ </data>
137
+ </dict>
138
+ <key>Montserrat-Italic.ttf</key>
139
+ <dict>
140
+ <key>hash2</key>
141
+ <data>
142
+ fofA+Ws5+7kZswrviZEyPQsldknzkeZFa88DwjFEj0k=
143
+ </data>
144
+ </dict>
145
+ <key>Montserrat-Light.ttf</key>
146
+ <dict>
147
+ <key>hash2</key>
148
+ <data>
149
+ lj13LJxEs8QBslfWk60mAG/HvVQhWVfVE1a0DjY1P4Q=
150
+ </data>
151
+ </dict>
89
152
  <key>Montserrat-Medium.ttf</key>
90
153
  <dict>
91
154
  <key>hash2</key>
@@ -100,6 +163,20 @@
100
163
  75z5nwF1vvUwuIk0vZBPz1b3c87G/U37jMr3ziu9OV4=
101
164
  </data>
102
165
  </dict>
166
+ <key>Montserrat-SemiBold.ttf</key>
167
+ <dict>
168
+ <key>hash2</key>
169
+ <data>
170
+ nE2zgUh1QQ59ZP3I5pZ2w7hJaLsVvzrOizlExZ+8VrY=
171
+ </data>
172
+ </dict>
173
+ <key>Montserrat-Thin.ttf</key>
174
+ <dict>
175
+ <key>hash2</key>
176
+ <data>
177
+ qMAnFkOz0iN+EeE+5ZACTUmzW3dgFJWOYP5hV8P1I/o=
178
+ </data>
179
+ </dict>
103
180
  <key>bm.json</key>
104
181
  <dict>
105
182
  <key>hash2</key>
@@ -118,7 +195,7 @@
118
195
  <dict>
119
196
  <key>hash2</key>
120
197
  <data>
121
- J+yu4eRtwfh0rvCBzxhG7H7PpaBcDv9V13qZ8TRhBmU=
198
+ 1loRLBPvXhMxef8cbl/CEpfB0j0axeW+shU+jSRHK8w=
122
199
  </data>
123
200
  </dict>
124
201
  </dict>
@@ -524,11 +524,11 @@
524
524
  "SIGN_UP_SUBTITLE": "Please enter required details to continue.",
525
525
  "APPOINTMENT_FOR_UNIT": "Appointment for unit",
526
526
  "STEP_1": "Step 1/3",
527
- "STEP_1_TITLE": "Select your preferred date",
527
+ "STEP_1_TITLE": "Select your preferred date.",
528
528
  "STEP_2": " Step 2/3",
529
- "STEP_2_TITLE": "Select your preferred time",
529
+ "STEP_2_TITLE": "Select your preferred time.",
530
530
  "STEP_3": "Step 3/3",
531
- "STEP_3_TITLE": "Confirm your appointment",
531
+ "STEP_3_TITLE": "Confirm your appointment.",
532
532
  "OWNER_SIGN_UP": "Owner Sign Up",
533
533
  "NO_RECORD_FOUND": "No Record Found",
534
534
  "ASK_CS": "Would you like our Customer Support Team to contact you",
@@ -724,7 +724,7 @@
724
724
  "ISSUES_SELECTED": "Issue(s) selected",
725
725
  "ENTER_REMARKS_HERE": "Enter remarks here...",
726
726
  "WITHDRAWING": "Withdrawing",
727
- "WITHDRAW_ALERT_MESSAGE": "Confirm to withdraw issue?",
727
+ "WITHDRAW_ALERT_MESSAGE": "Confirm to withdraw this issue?",
728
728
  "WITHDRAW_ISSUES_SUCCESS_LABEL": "You have succesfully withdrawn",
729
729
  "FILTER_ISSUE_LIST": "Filter Issue",
730
730
  "APPLY": "Apply",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@convep_mobilogy/react-native-qms-plugin",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "To handle defect managment",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",