diff --git a/.env.development b/.env.development old mode 100644 new mode 100755 index 8902263..367bc8a --- a/.env.development +++ b/.env.development @@ -1,3 +1,3 @@ -API_URL=https://venbait.in/nhance/dev/employeeRest/ +API_URL=https://venbait.in/enrollment/employeeRest/ BASE_HREF=/nhance/app/dev/ ENV=development \ No newline at end of file diff --git a/.env.production b/.env.production old mode 100644 new mode 100755 index bb37520..2a5e516 --- a/.env.production +++ b/.env.production @@ -1,3 +1,3 @@ API_URL=https://app.nhanceindia.in/zenith/employeeRest/ -BASE_HREF=/app/ +BASE_HREF=/hr/ ENV=production \ No newline at end of file diff --git a/.env.test b/.env.test old mode 100644 new mode 100755 index 99da8dc..2a5e516 --- a/.env.test +++ b/.env.test @@ -1,3 +1,3 @@ -API_URL=https://venbait.in/nhance/test/employeeRest/ -BASE_HREF=/nhance/app/test/ -ENV=test \ No newline at end of file +API_URL=https://app.nhanceindia.in/zenith/employeeRest/ +BASE_HREF=/hr/ +ENV=production \ No newline at end of file diff --git a/.env.uat b/.env.uat old mode 100644 new mode 100755 index c44c4c8..d63a434 --- a/.env.uat +++ b/.env.uat @@ -1,3 +1,3 @@ -API_URL=https://dev.venbait.in/nhance/uat/employeeRest/ -BASE_HREF=/nhance/app/uat/ -ENV=uat \ No newline at end of file +API_URL=https://app.nhanceindia.in/zenith/employeeRest/ +BASE_HREF=/hr/ +ENV=production diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.metadata b/.metadata old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/analysis_options.yaml b/analysis_options.yaml old mode 100644 new mode 100755 diff --git a/android/.gitignore b/android/.gitignore old mode 100644 new mode 100755 diff --git a/android/app/build.gradle b/android/app/build.gradle old mode 100644 new mode 100755 diff --git a/android/app/google-services.json b/android/app/google-services.json old mode 100644 new mode 100755 diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml old mode 100644 new mode 100755 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml old mode 100644 new mode 100755 diff --git a/android/app/src/main/kotlin/com/example/nhancepolicy/MainActivity.kt b/android/app/src/main/kotlin/com/example/nhancepolicy/MainActivity.kt old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml old mode 100644 new mode 100755 diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml old mode 100644 new mode 100755 diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml old mode 100644 new mode 100755 diff --git a/android/build.gradle b/android/build.gradle old mode 100644 new mode 100755 diff --git a/android/gradle.properties b/android/gradle.properties old mode 100644 new mode 100755 diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties old mode 100644 new mode 100755 diff --git a/android/settings.gradle b/android/settings.gradle old mode 100644 new mode 100755 diff --git a/assets/Group_3.png b/assets/Group_3.png old mode 100644 new mode 100755 diff --git a/assets/Nhance-Logo-Final 1.png b/assets/Nhance-Logo-Final 1.png old mode 100644 new mode 100755 diff --git a/assets/Solid_gray.png b/assets/Solid_gray.png old mode 100644 new mode 100755 diff --git a/assets/Template_File.xlsx b/assets/Template_File.xlsx old mode 100644 new mode 100755 diff --git a/assets/Vector.png b/assets/Vector.png old mode 100644 new mode 100755 diff --git a/assets/hrLogin.jpg b/assets/hrLogin.jpg old mode 100644 new mode 100755 diff --git a/assets/login_web.jpg b/assets/login_web.jpg old mode 100644 new mode 100755 diff --git a/assets/mobileViewLogo.png b/assets/mobileViewLogo.png old mode 100644 new mode 100755 diff --git a/assets/navbarLogo.png b/assets/navbarLogo.png old mode 100644 new mode 100755 diff --git a/assets/nhance-loader.gif b/assets/nhance-loader.gif old mode 100644 new mode 100755 diff --git a/assets/nhance_client_logo.png b/assets/nhance_client_logo.png old mode 100644 new mode 100755 diff --git a/assets/policy.png b/assets/policy.png old mode 100644 new mode 100755 diff --git a/ios/.gitignore b/ios/.gitignore old mode 100644 new mode 100755 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist old mode 100644 new mode 100755 diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig old mode 100644 new mode 100755 index 592ceee..ec97fc6 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig old mode 100644 new mode 100755 index 592ceee..c4855bf --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..e549ee2 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png old mode 100644 new mode 100755 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md old mode 100644 new mode 100755 diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard old mode 100644 new mode 100755 diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard old mode 100644 new mode 100755 diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist old mode 100644 new mode 100755 diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h old mode 100644 new mode 100755 diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift old mode 100644 new mode 100755 diff --git a/lib.zip b/lib.zip new file mode 100755 index 0000000..862bc6e Binary files /dev/null and b/lib.zip differ diff --git a/lib/addons.dart b/lib/addons.dart old mode 100644 new mode 100755 index 2e2c34c..557511a --- a/lib/addons.dart +++ b/lib/addons.dart @@ -28,6 +28,7 @@ class _addOnsDetailsState extends State { late ApiService apiService; bool isLoading = true; bool isChecked = false; + bool login_by_hr = false; bool _addOnsDependentSwitcher = false; // Declare the _isSwitched variable here bool _topUpSiSwitcher = false; @@ -246,8 +247,19 @@ class _addOnsDetailsState extends State { empClientBranchId == null) { return; } + final SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('hrtoken')) { + setState(() { + login_by_hr = true; + }); + } final response = await apiService.getGpaEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GPA', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GPA', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { setState(() { @@ -275,8 +287,19 @@ class _addOnsDetailsState extends State { empClientBranchId == null) { return; } + final SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('hrtoken')) { + setState(() { + login_by_hr = true; + }); + } final response = await apiService.getGmcEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GMC', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GMC', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { // setState(() { gmcPolicies = response['data']; @@ -4542,7 +4565,7 @@ class _addOnsDetailsState extends State { String? gpaPolicyName = item['Policy_Name']; String? gpaECardDownload = item['eCardDownload']; - String? gpaSumInsured; + String? gpaSumInsured = item['si_value']; List gpaMappedFamilyFloaters = []; if (item['mapped_family_floaters'] != null) { @@ -4553,11 +4576,11 @@ class _addOnsDetailsState extends State { .where((element) => element['is_value_exist'] == true) .toList(); - if (getTrueObjects.length > 0) { - gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; - } else { - gpaSumInsured = item['Policy_Terms']['sumInsured2']; - } + // if (getTrueObjects.length > 0) { + // gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; + // } else { + // gpaSumInsured = item['Policy_Terms']['sumInsured2']; + // } int gpaOpenForEnrollment = int.parse(item['OpenForEnrollment']); List familyFloaterContainers = []; diff --git a/lib/customAppBar/customAppBar.dart b/lib/customAppBar/customAppBar.dart old mode 100644 new mode 100755 index 42262d1..5b57ef0 --- a/lib/customAppBar/customAppBar.dart +++ b/lib/customAppBar/customAppBar.dart @@ -21,7 +21,7 @@ class _CustomAppBarState extends State { @override void initState() { super.initState(); - _checkTokens(); + // _checkTokens(); } Future _checkTokens() async { @@ -31,7 +31,7 @@ class _CustomAppBarState extends State { // showBackToHR = prefs.getBool('showBackToHR')!; setState(() { - showBackToHR = prefs.getBool('showBackToHR')!; + // showBackToHR = prefs.getBool('showBackToHR'); // showBackToHR = (hrtoken != null && hrtoken.isNotEmpty) && // (token != null && token.isNotEmpty); // print((hrtoken != null && hrtoken.isNotEmpty)); diff --git a/lib/customAppBar/customAppBarChatbot.dart b/lib/customAppBar/customAppBarChatbot.dart new file mode 100755 index 0000000..3804783 --- /dev/null +++ b/lib/customAppBar/customAppBarChatbot.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:adaptive_navbar/adaptive_navbar.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../responsive.dart'; + +class CustomAppBarChatbot extends StatelessWidget + implements PreferredSizeWidget { + @override + Size get preferredSize => Size.fromHeight(kToolbarHeight); + + Future logout(BuildContext context) async { + final prefs = await SharedPreferences.getInstance(); + final String? token = prefs.getString('token'); + + if (token != null && token.isNotEmpty) { + await prefs.clear(); + Navigator.pushNamed(context, 'phone'); + } + } + + @override + Widget build(BuildContext context) { + final sw = MediaQuery.of(context).size.width; + final isPoliciesPage = Uri.base.fragment == 'policies'; + return ClipRRect( + borderRadius: Responsive.isDesktop(context) || isPoliciesPage + ? BorderRadius.zero + : BorderRadius.only( + bottomLeft: Radius.circular(32.0), + bottomRight: Radius.circular(32.0), + ), + child: AppBar( + backgroundColor: const Color(0xFFFFFBDE), + elevation: 0, // Set background color for AppBar + toolbarHeight: kToolbarHeight, + titleSpacing: 0.0, + automaticallyImplyLeading: false, + title: Padding( + padding: Responsive.isDesktop(context) + ? EdgeInsets.symmetric(horizontal: 16.0) + : EdgeInsets.symmetric(horizontal: 10), + child: Row( + children: [ + // Logo Column + Expanded( + flex: Responsive.isDesktop(context) ? 3 : 9, + child: Row( + mainAxisAlignment: Responsive.isDesktop(context) + ? MainAxisAlignment.spaceEvenly + : MainAxisAlignment + .start, // Adjust the alignment as needed + children: [ + Container( + margin: EdgeInsets.only( + top: 10, bottom: 10, left: 10, right: 10), + width: Responsive.isDesktop(context) ? 230 : 170, + height: Responsive.isDesktop(context) ? 230 : 170, + child: Image.asset( + 'assets/nhance_client_logo.png', + fit: BoxFit.contain, // Adjust the fit as needed + ), + ), + ], + ), + ), + // AdaptiveNavBar Column + + Expanded( + flex: Responsive.isDesktop(context) ? 9 : 3, + child: GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Icon( + Icons.close_outlined, // Replace with your desired icon + size: 24.0, // Adjust the icon size + color: Colors.black, // Adjust the icon color + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/customAppBar/customFooter.dart b/lib/customAppBar/customFooter.dart old mode 100644 new mode 100755 diff --git a/lib/customAppBar/enrollmentAppBar.dart b/lib/customAppBar/enrollmentAppBar.dart new file mode 100755 index 0000000..cf2fb87 --- /dev/null +++ b/lib/customAppBar/enrollmentAppBar.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:adaptive_navbar/adaptive_navbar.dart'; +import 'package:nhancepolicy/customAppBar/toastHelper.dart'; +import 'package:nhancepolicy/responsive.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:nhancepolicy/responsive.dart'; + +class CustomAppBar extends StatefulWidget implements PreferredSizeWidget { + @override + _CustomAppBarState createState() => _CustomAppBarState(); + + @override + Size get preferredSize => Size.fromHeight(kToolbarHeight); +} + +class _CustomAppBarState extends State { + bool showBackToHR = false; + // bool isLoading = true; // Add a loading state + // bool hideInactiveStatus = true; + + @override + void initState() { + super.initState(); + _checkTokens(); + } + + Future _checkTokens() async { + final prefs = await SharedPreferences.getInstance(); + final String? hrtoken = prefs.getString('hrtoken'); + final String? token = prefs.getString('token'); + // showBackToHR = prefs.getBool('showBackToHR')!; + + setState(() { + showBackToHR = prefs.getBool('showBackToHR')!; + // showBackToHR = (hrtoken != null && hrtoken.isNotEmpty) && + // (token != null && token.isNotEmpty); + // print((hrtoken != null && hrtoken.isNotEmpty)); + // print((token != null && token.isNotEmpty)); + // print('showBackToHR $showBackToHR'); + + // hideInactiveStatus = token != null && token.isNotEmpty; + }); + } + + Future hrLogout(BuildContext context) async { + final prefs = await SharedPreferences.getInstance(); + final String? hrtoken = prefs.getString('hrtoken'); + + if (hrtoken != null && hrtoken.isNotEmpty) { + prefs.setBool('showBackToHR', false); + await prefs.remove('hrSelectArgumentsData'); + prefs.remove('token'); + Navigator.pushNamed(context, 'hrDashboard'); + } else { + await prefs.clear(); + Navigator.pushNamed(context, 'phone'); + } + } + + Future logout(BuildContext context) async { + final prefs = await SharedPreferences.getInstance(); + final String? hrtoken = prefs.getString('hrtoken'); + final String? token = prefs.getString('token'); + + if (token != null && token.isNotEmpty) { + if (hrtoken != null && hrtoken.isNotEmpty) { + await prefs.clear(); + Navigator.pushNamed(context, 'hrLogin'); + } else { + await prefs.clear(); + Navigator.pushNamed(context, 'phone'); + } + } else if (hrtoken != null && hrtoken.isNotEmpty) { + await prefs.clear(); + Navigator.pushNamed(context, 'hrLogin'); + } + } + + @override + Widget build(BuildContext context) { + final sw = MediaQuery.of(context).size.width; + // if (isLoading) { + // // Show a loading indicator or a placeholder AppBar while waiting + // return AppBar( + // title: Text('Loading...'), + // ); + // } + return Scaffold( + backgroundColor: Color(0xFFFFFCE5), // Set background color for AppBar + appBar: PreferredSize( + preferredSize: widget.preferredSize, + child: SafeArea( + child: Container( + padding: Responsive.isDesktop(context) + ? EdgeInsets.symmetric(horizontal: 16.0) + : EdgeInsets.symmetric(horizontal: 0), + child: Row( + children: [ + // Logo Column + Expanded( + flex: Responsive.isDesktop(context) ? 3 : 9, + child: Row( + mainAxisAlignment: Responsive.isDesktop(context) + ? MainAxisAlignment.spaceEvenly + : MainAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 10, bottom: 10), + width: 150, + height: 150, + child: Image.asset( + 'assets/nhance_client_logo.png', + fit: BoxFit.contain, + ), + ), + ], + ), + ), + // AdaptiveNavBar Column + Expanded( + flex: Responsive.isDesktop(context) ? 9 : 3, + child: AdaptiveNavBar( + screenWidth: sw, + backgroundColor: Color(0xFFFFFCE5), + leading: + Container(), // Set an empty container as we have the logo separately + title: Text(''), + navBarItems: [ + // if (Responsive.isDesktop(context)) + // if (hideInactiveStatus) + // NavBarItem( + // text: "Inactive Policy", + // onTap: () { + // Navigator.pushNamed(context, 'oldPolicy'); + // }, + // ), + if (showBackToHR) + NavBarItem( + text: "Back To HR", + onTap: () { + hrLogout(context); + }, + ), + NavBarItem( + text: "Logout", + onTap: () async { + logout(context); + }, + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/customAppBar/toastHelper.dart b/lib/customAppBar/toastHelper.dart old mode 100644 new mode 100755 diff --git a/lib/email_verify.dart b/lib/email_verify.dart new file mode 100644 index 0000000..5309a6a --- /dev/null +++ b/lib/email_verify.dart @@ -0,0 +1,894 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:nhancepolicy/responsive.dart'; +import 'package:nhancepolicy/service/api_service.dart'; +import 'package:pinput/pinput.dart'; +import 'dart:async'; +import 'package:flutter/gestures.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; +import 'dart:io'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:jwt_decode/jwt_decode.dart'; + +import '../customAppBar/toastHelper.dart'; +import '../models/environment.dart'; +import '../models/platform_helper_mobile.dart' +if (dart.library.html) '../models/platform_helper_other.dart'; + +// import 'dart:html' as html; + +class MyEmailVerify extends StatefulWidget { + final String email; + + const MyEmailVerify({ + Key? key, + required this.email, + }) : super(key: key); + + @override + State createState() => _MyEmailVerifyState(); +} + +class _MyEmailVerifyState extends State { + late ApiService apiService; + TextEditingController _otpController = TextEditingController(); + final _formKey = GlobalKey(); + late Timer _timer; + int _secondsRemaining = 60; + bool _isTimerRunning = false; + + dynamic enrollmentEmpClientBranchId; + dynamic enrollmentEmpCodeString; + dynamic enrollmentEmpPrimaryId; + dynamic enrollmentGpaEmpName; + dynamic enrollmentClient_id; + dynamic enrollmentEmp_status; + + dynamic empCodeString; + dynamic empClientBranchId; + dynamic empPrimaryId; + dynamic gpaEmpName; + dynamic empClientId; + dynamic _token; + dynamic _postToken; + dynamic clientName; + dynamic clientLogo; + dynamic emp_status; + dynamic fCMToken; + late String verificationId; + final FirebaseAuth _auth = FirebaseAuth.instance; + bool _isLoading = false; + + late String _verificationId; + dynamic empMobileNo; + dynamic empEmailid; + + @override + void initState() { + super.initState(); + apiService = ApiService(context); + startTimer(); + } + + @override + void dispose() { + _timer.cancel(); + super.dispose(); + } + + + + void startTimer() { + _isTimerRunning = true; + _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) { + setState(() { + if (_secondsRemaining > 0) { + _secondsRemaining--; + } else { + _isTimerRunning = false; + _timer.cancel(); + } + }); + }); + } + + void verifyOTP(String otp) async { + try { + final response = await http.post( + Uri.parse(Environment.apiUrl + 'getVerifiedHrData'), + body: + json.encode({'email': widget.email, 'otp': _otpController.text}), + headers: { + HttpHeaders.contentTypeHeader: 'application/json', + }, + ); + + if (response.statusCode == 200) { + setState(() { + _isLoading = false; + }); + Map data = json.decode(response.body); + print('data: $data'); + _token = data['data']; + String status = data['status']; + + // Directly access the post_enrollment data + Map post = data['post_enrollment']; + print('post: $post'); + + _postToken = post['data']; + String postStatus = post['status']; + + if (postStatus == 'success') { + setState(() { + _isLoading = false; + }); + postSuccessData(post, data); + } else if (status == 'success') { + setState(() { + _isLoading = false; + }); + enrollmentSuccessData(data); + } else { + setState(() { + _isLoading = false; + }); + ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); + // Show a Snackbar if the OTP is invalid + print('Invalid OTP. Please try again'); + } + } else { + setState(() { + _isLoading = false; + }); + ToastHelper.showWarningToast(context, 'Something went wrong'); + throw Exception('Failed to verify OTP'); + } + } catch (e) { + setState(() { + _isLoading = false; + }); + print('Error: $e'); + ToastHelper.showWarningToast(context, 'Something went wrong'); + // Show a Snackbar if there's an error while verifying OTP + print('Failed to verify OTP. Please try again.'); + } + } + + void postSuccessData(post, data) async { + String status = data['status']; + String postStatus = post['status']; + + if (postStatus == 'success') { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('_postToken', post['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(post['data']); + print('decodedToken : $decodedToken'); + empClientBranchId = decodedToken['ref_id']; + prefs.setString('empClientBranchId', empClientBranchId); + empCodeString = decodedToken['emp_code'].toString(); + prefs.setString('empCode', empCodeString); + empPrimaryId = decodedToken['id']; + prefs.setString('empPrimaryId', empPrimaryId); + gpaEmpName = decodedToken['name'].toString(); + prefs.setString('gpaEmpName', gpaEmpName); + empClientId = decodedToken['client_id']; + prefs.setString('empClientId', empClientId); + // emp_status = decodedToken['emp_status']; + // prefs.setString('emp_status', emp_status); + // getClientLogoAndDetails(); + + print('Successfully Login'); + + // Redirect to another page + } + + if (status == 'success') { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('enrollToken', data['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(data['data']); + print('decodedToken : $decodedToken'); + enrollmentEmpClientBranchId = decodedToken['ref_id']; + prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId); + enrollmentEmpCodeString = decodedToken['emp_code'].toString(); + prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString); + enrollmentEmpPrimaryId = decodedToken['id']; + prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId); + enrollmentGpaEmpName = decodedToken['name'].toString(); + prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName); + enrollmentClient_id = decodedToken['client_id']; + prefs.setString('enrollmentClient_id', enrollmentClient_id); + // enrollmentEmp_status = decodedToken['emp_status']; + // prefs.setString('enrollmentEmp_status', enrollmentEmp_status); + } + + getClientLogoAndDetails(empClientId,empClientBranchId,post['data']); + + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final _postToken = prefs.getString('_postToken'); + + if (_postToken != null && _postToken.isNotEmpty) { + ToastHelper.showSuccessToast(context, 'Successfully Login'); + // if (emp_status == 'enrolled' || emp_status == 'active') { + Navigator.pushReplacementNamed(context, 'hrDashboard'); + // } else { + // Navigator.pushReplacementNamed(context, 'empDetails'); + // } + } + } + + + void enrollmentSuccessData(data) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('enrollToken', data['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(data['data']); + print('decodedToken : $decodedToken'); + enrollmentEmpClientBranchId = decodedToken['ref_id']; + prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId); + enrollmentEmpCodeString = decodedToken['emp_code'].toString(); + prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString); + enrollmentEmpPrimaryId = decodedToken['id']; + prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId); + enrollmentGpaEmpName = decodedToken['name'].toString(); + prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName); + enrollmentClient_id = decodedToken['client_id']; + prefs.setString('enrollmentClient_id', enrollmentClient_id); + // enrollmentEmp_status = decodedToken['emp_status']; + // prefs.setString('enrollmentEmp_status', enrollmentEmp_status); + getClientLogoAndDetails(enrollmentClient_id,enrollmentEmpClientBranchId,data['data']); + print('Successfully Login'); + + // Redirect to another page + final enrollToken = prefs.getString('enrollToken'); + + if (enrollToken != null && enrollToken.isNotEmpty) { + ToastHelper.showSuccessToast(context, 'Successfully Login'); + // if (emp_status == 'enrolled' || emp_status == 'active') { + // Navigator.pushReplacementNamed(context, 'home'); + // } else { + Navigator.pushReplacementNamed(context, 'hrDashboard'); + // } + } + + } + + void _resendOTP() { + setState(() { + _secondsRemaining = 60; + _isTimerRunning = true; + }); + startTimer(); + verifyMobileAndEmailNumber(); + } + + Future verifyMobileAndEmailNumber() async { + try { + // var enteredMobileNumber = mobileController.text; + final response = await http.post( + Uri.parse(Environment.apiUrl + 'verifyEmployeeEmailId'), + body: json.encode({'email': widget.email}), + headers: { + HttpHeaders.contentTypeHeader: 'application/json', + }, + ); + + if (response.statusCode == 200) { + Map data = json.decode(response.body); + bool userVerification = data['data']['user_verification']; + String message = data['data']['message']; + if (userVerification) { + ToastHelper.showSuccessToast( + context, 'Verification code sent to ${widget.email}'); + } else { + ToastHelper.showErrorToast(context, message); + print('Invalid mobile number'); + } + } else { + ToastHelper.showErrorToast(context, 'Something went wrong'); + throw Exception('Failed to verify mobile number'); + } + } catch (e) { + ToastHelper.showErrorToast(context, 'Something went wrong'); + print('Error: $e'); + } + } + + Future getClientLogoAndDetails(client_id,empRefId,token) async { + var url = Uri.parse(Environment.apiUrl + + 'getClientDetails?client_id=$client_id&client_branch_id=$empRefId'); + try { + var response = await http.get( + url, + headers: { + 'Authorization': + 'Bearer $token', // Add token to the Authorization header + }, + ); + if (response.statusCode == 200) { + // print('response.statusCode == 200'); + Map data = json.decode(response.body); + // print(data); + + if (data.containsKey('data')) { + dynamic clientDetails = data['data']; + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('clientLogo', clientDetails['client']['client_logo']); + prefs.setString('clientName', clientDetails['client']['client_name']); + setState(() { + // dynamic clientDetails = data['data']; + // print(clientDetails); + clientName = clientDetails['client']['client_name']; + print(clientName); + clientLogo = clientDetails['client']['client_logo']; + print(clientLogo); + }); + } else { + // Handle other status messages if needed + // ToastHelper.showErrorToast( + // context, 'API request failed with status: ${data['status']}'); + print('API request failed with status: ${data['status']}'); + } + } else { + // Handle other status codes + // ToastHelper.showErrorToast( + // context, 'Request failed with status: ${response.statusCode}'); + print('Request failed with status: ${response.statusCode}'); + } + } catch (e) { + // Handle exceptions + print('Exception occurred: $e'); + } + } + + @override + Widget build(BuildContext context) { + // Retrieve the passed mobile number value + // final String mobileNumber = + // ModalRoute.of(context)!.settings.arguments as String; + Size _size = MediaQuery.of(context).size; + EdgeInsets marginInsets = EdgeInsets.zero; + if (Responsive.isDesktop(context)) { + marginInsets = const EdgeInsets.only( + left: 0, + right: 0, + bottom: 0, + top: 0, + ); + } else if (Responsive.isMobile(context)) { + marginInsets = const EdgeInsets.only( + left: 25, // Example value for mobile + right: 25, // Example value for mobile + bottom: 0, // Example value for mobile + top: 0, // Example value for mobile + ); + } else if (Responsive.isTablet(context)) { + marginInsets = const EdgeInsets.only( + left: 25, // Example value for mobile + right: 25, // Example value for mobile + bottom: 0, // Example value for mobile + top: 0, // Example value for mobile + ); + } + final defaultPinTheme = PinTheme( + width: 56, + height: 56, + textStyle: TextStyle( + fontSize: 20, + color: Color.fromRGBO(30, 60, 87, 1), + fontWeight: FontWeight.w600, + ), + decoration: BoxDecoration( + border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)), + borderRadius: BorderRadius.circular(20), + ), + ); + + final focusedPinTheme = defaultPinTheme.copyDecorationWith( + border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)), + borderRadius: BorderRadius.circular(8), + ); + + final submittedPinTheme = defaultPinTheme.copyWith( + decoration: defaultPinTheme.decoration?.copyWith( + color: Color.fromRGBO(234, 239, 243, 1), + ), + ); + + return WillPopScope( + onWillPop: () async { + Navigator.pushReplacementNamed(context, 'login'); + return false; + }, + child: Scaffold( + body: SingleChildScrollView( + keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + child: Container( + height: _size.height, + color: Colors.white, + child: Stack( + children: [ + Visibility( + visible: _size.width <= 1100, + child: ClipRRect( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30), + ), + child: Container( + height: _size.height / 3, + width: double.infinity, + color: Color(0xFFFFFCE5), + child: Stack( + children: [ + Column( + children: [ + SizedBox( + height: _size.height / + 6.4), // Adjust the spacing between the rows + Row( + mainAxisAlignment: MainAxisAlignment + .center, // Align to the center + children: [ + Expanded( + flex: Responsive.isDesktop(context) + ? 10 + : 12, + child: Align( + alignment: Responsive.isDesktop(context) + ? Alignment.centerLeft + : Alignment.bottomCenter, + child: Image.asset( + 'assets/nhance_app_logo.png', + width: 150, + height: 150, + ), + ), + ), + if (!Responsive.isMobile(context) && + !Responsive.isTablet(context)) + Expanded( + flex: 2, + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + // Add your navigation logic here + // For example, you can use Navigator.push to navigate to another page + Navigator.pushNamed( + context, 'hrLogin'); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment + .end, // Align to the end (right) + children: [ + Text( + 'HR Login', + style: GoogleFonts.poppins( + color: Color( + 0xFF000000), // Text color + // Add other text styles as needed + ), + ), + SizedBox(width: 5), + Icon( + Icons + .east, // Icon for customer login + color: Colors + .black, // Adjust color as needed + ), + ], + ), + ), + ), + ), + ], + ), + ], + ), + ], + ), + ), + ), + ), + Container( + margin: marginInsets, + alignment: Alignment.bottomCenter, + child: SingleChildScrollView( + child: Form( + key: _formKey, + child: Column( + children: [ + Row( + children: [ + if (_size.width > 1100) + Expanded( + flex: _size.width < 1100 ? 6 : 12, + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints constraints) { + if (constraints.maxWidth > 600) { + return Image.asset( + 'assets/hrLogin.jpg', + height: _size.height, + fit: BoxFit.cover, + ); + } else { + return SizedBox(); + } + }, + ), + ), + Expanded( + flex: _size.width < 1100 ? 6 : 12, + child: Container( + margin: _size.width > 1100 + ? EdgeInsets.only(left: 20, right: 20) + : EdgeInsets.only(left: 0, right: 0), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + if (!Responsive.isMobile(context) && + !Responsive.isTablet(context)) + Row( + children: [ + Expanded( + flex: 10, + child: Align( + alignment: Responsive + .isDesktop(context) + ? Alignment.centerLeft + : Alignment + .bottomCenter, // Align to the start + child: _size.width <= 1100 + ? Image.asset( + 'assets/nhance_app_logo.png', + width: 150, + height: 150, + ) + : _size.width > 1100 + ? Image.asset( + 'assets/nhance_app_logo.png', + width: 150, + height: 150, + ) + : Image.asset( + 'assets/nhance_app_logo.png', + width: 150, + height: 150, + ), + )), + ], + ), + SizedBox(height: 10), + // SizedBox( + // height: Responsive.isDesktop(context) + // ? _size.height * 0.1 + // : 10, + // ), + Container( + margin: Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + "Welcome to Nhance", + style: GoogleFonts.poppins( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + SizedBox(height: 10), + Container( + margin: Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: + "Please enter the one-time usage code sent to your mobile number ${widget.email}", + style: TextStyle( + fontSize: 12, + height: 1.5, + color: Color(0xFF000000)), + children: [ + TextSpan( + text: " (Change Email)", + style: TextStyle( + fontSize: 12, + color: Color( + 0xFFE26728)), // Change color as desired + recognizer: + TapGestureRecognizer() + ..onTap = () { + // Navigate to the page where the user can change the phone number + Navigator.pushNamed( + context, 'hrLogin'); + }, + ), + ], + ), + ), + ), + SizedBox(height: 15), + Container( + margin: Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: Pinput( + length: 6, + // defaultPinTheme: defaultPinTheme, + // focusedPinTheme: focusedPinTheme, + // submittedPinTheme: submittedPinTheme, + showCursor: true, + controller: _otpController, + ), + ), + SizedBox(height: 10), + Container( + margin: Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: Row( + mainAxisAlignment: MainAxisAlignment + .end, // Align text to the right + children: [ + _isTimerRunning + ? Text( + "Resend OTP in $_secondsRemaining seconds", + style: + GoogleFonts.poppins( + color: + Colors.black), + ) + : InkWell( + onTap: () { + _resendOTP(); + }, + child: Text( + "Resend OTP", + style: + GoogleFonts.poppins( + color: Colors + .blue), + ), + ), + ], + ), + ), + SizedBox(height: 10), + Container( + margin: Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: SizedBox( + width: double.infinity, + height: 45, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: + Color(0xFF00989E), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10), + ), + ), + onPressed: () { + if (_formKey.currentState! + .validate()) { + _formKey.currentState! + .save(); // Save form fields before calling verifyOTP + verifyOTP( + _otpController.text); + } + }, + child: Text( + "Submit", + style: GoogleFonts.poppins( + color: Color(0xFFFFFFFF)), + ), + ), + ), + ), + // _size.width > 1100 + // ? Container( + // margin: EdgeInsets.symmetric( + // horizontal: 150), + // child: Column( + // children: [ + // SizedBox(height: 20), + // Text( + // "Benefits of Login", + // style: + // GoogleFonts.poppins( + // fontSize: 20, + // fontWeight: + // FontWeight.bold, + // ), + // ), + // SizedBox(height: 15), + // ], + // )) + // : SizedBox(), + // _size.width > 1100 + // ? Container( + // margin: EdgeInsets.symmetric( + // horizontal: 150), + // child: Row( + // mainAxisAlignment: + // MainAxisAlignment.center, + // children: [ + // Expanded( + // flex: 6, + // child: Container( + // padding: EdgeInsets + // .symmetric( + // vertical: 8), + // child: Row( + // mainAxisAlignment: + // MainAxisAlignment + // .center, + // children: [ + // Expanded( + // child: Container( + // padding: EdgeInsets + // .symmetric( + // vertical: + // 12), + // decoration: + // BoxDecoration( + // border: + // Border( + // right: + // BorderSide( + // width: 1, + // color: Colors + // .black, + // ), + // ), + // ), + // child: Column( + // children: [ + // Icon( + // Icons + // .policy, + // color: Color( + // 0xFFE26728)), + // SizedBox( + // height: + // 10), + // Text( + // "View Policy", + // style: GoogleFonts + // .poppins()), + // ], + // ), + // ), + // ), + // Expanded( + // child: Container( + // padding: EdgeInsets + // .symmetric( + // vertical: + // 12), + // child: Column( + // children: [ + // Icon( + // Icons + // .edit, + // color: Color( + // 0xFFE26728)), + // SizedBox( + // height: + // 10), + // Text( + // "Manage Claims", + // style: GoogleFonts + // .poppins()), + // ], + // ), + // ), + // ), + // ], + // ), + // ), + // ), + // ], + // ), + // ) + // : SizedBox( + // height: Responsive.isDesktop( + // context) + // ? _size.height * 0.1 + // : _size.height * 0.2, + // ), + SizedBox( + height: Responsive.isDesktop(context) + ? _size.height * 0.3 + : _size.height * 0.2, + ), + // SizedBox( + // height: _size.height * 0.1, + // ), + Container( + alignment: Alignment.bottomCenter, + padding: + EdgeInsets.symmetric(vertical: 8), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: + 'By continuing, you agree with our ', + style: GoogleFonts.poppins( + color: Colors.black, + fontSize: 9, + ), + children: [ + TextSpan( + text: 'privacy policy ', + style: GoogleFonts.poppins( + color: Color(0xFF00989E), + fontSize: 9, + ), + ), + TextSpan( + text: 'and ', + style: GoogleFonts.poppins( + color: Colors.black, + fontSize: 9, + ), + ), + TextSpan( + text: 'terms of use', + style: GoogleFonts.poppins( + color: Color(0xFF00989E), + fontSize: 9, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + + ], + ), + ], + ), + ), + ), + ), + ], + )), + ))); + } +} diff --git a/lib/empDetails.dart b/lib/empDetails.dart old mode 100644 new mode 100755 index 702de24..7501424 --- a/lib/empDetails.dart +++ b/lib/empDetails.dart @@ -5,7 +5,7 @@ import 'package:nhancepolicy/customAppBar/toastHelper.dart'; import 'package:nhancepolicy/models/environment.dart'; import 'package:nhancepolicy/service/api_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'customAppBar/customAppBar.dart'; +import 'package:nhancepolicy/customAppBar/enrollmentAppBar.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'package:http/http.dart' as http; import 'package:flutter/widgets.dart'; @@ -29,6 +29,7 @@ class empDetails extends StatefulWidget { class _empDetailsState extends State { late ApiService apiService; bool isLoading = true; + bool login_by_hr = false; dynamic _token; dynamic empCodeString; dynamic empPrimaryId; @@ -58,6 +59,7 @@ class _empDetailsState extends State { dynamic gmcSelfRelationship; dynamic gmcSelfDetails; dynamic gmcPolicyName; + dynamic gmc_client_policy_id; dynamic gmcPolicyType; dynamic gmcNotes; dynamic gmcGridMaster; @@ -94,6 +96,7 @@ class _empDetailsState extends State { dynamic hrPrimaryId; dynamic empRefId; dynamic empClientBranchId; + dynamic token; @override void initState() { @@ -143,7 +146,10 @@ class _empDetailsState extends State { prefs.setString('fromHrLoginMobileNo', mobileNumber); // Retrieve the passed mobile number value - dynamic login_by_hr = true; + + setState(() { + login_by_hr = true; + }); try { final response = await http.post( Uri.parse(Environment.apiUrl + 'getVerifiedUserData'), @@ -189,11 +195,11 @@ class _empDetailsState extends State { print('Successfully Login'); // Redirect to another page - final token = prefs.getString('token'); + token = prefs.getString('token'); print('final $token'); if (token != null && token.isNotEmpty) { // ToastHelper.showSuccessToast(context, 'Successfully Login'); - await getSelfEmployeeProfile(token); + await getTokenLoad(token); if (prefs.containsKey('clientLogo') && prefs.containsKey('clientName')) { clientLogo = prefs.getString('clientLogo'); @@ -253,7 +259,7 @@ class _empDetailsState extends State { // print(empPrimaryId); // Call the API when the page enters - getSelfEmployeeProfile(''); + // getSelfEmployeeProfile(''); if (prefs.containsKey('clientLogo') && prefs.containsKey('clientName')) { clientLogo = prefs.getString('clientLogo'); clientName = prefs.getString('clientName'); @@ -314,15 +320,24 @@ class _empDetailsState extends State { } } - Future getSelfEmployeeProfile(token) async { + Future getTokenLoad(token) async { + try { + final response = await apiService.getTokenLoadAPI(token); + } catch (e) { + // Handle exceptions + print('Exception occurred: $e'); + } + } + + Future getSelfEmployeeProfile(token, client_policy_id) async { try { if (client_id == null || empCodeString == null || empClientBranchId == null) { return; } - final response = await apiService.getSelfEmployeeProfileToApi( - token, client_id!, empCodeString!, empClientBranchId!); + final response = await apiService.getSelfEmployeeProfileToApi(token, + client_id!, empCodeString!, empClientBranchId!, client_policy_id); if (response['status'] == 'success') { if (response.containsKey('data')) { @@ -335,7 +350,8 @@ class _empDetailsState extends State { selfMobile = selfDetails['mobile']; selfDesignation = selfDetails['designation']; selfDob = convertDateFormat(selfDetails['dob']); - selfDoj = convertDateFormat(selfDetails['doj']); + // selfDoj = convertDateFormat(selfDetails['doj']); + selfDoj = convertDateFormat(selfDetails['date_coverage']); selfGender = selfDetails['gender']; selfEmailCorporate = selfDetails['email_corporate']; selfEmailPersonal = selfDetails['email_personal']; @@ -386,8 +402,14 @@ class _empDetailsState extends State { empClientBranchId == null) { return; } + final response = await apiService.getGpaEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GPA', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GPA', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { setState(() { @@ -415,8 +437,14 @@ class _empDetailsState extends State { empClientBranchId == null) { return; } + final response = await apiService.getGmcEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GMC', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GMC', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { setState(() { gmcPolicies = response['data']; @@ -651,6 +679,35 @@ class _empDetailsState extends State { _dobController.clear(); } + Future backFunction() async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final String? hrtoken = prefs.getString('hrtoken'); + + if (hrtoken != null && hrtoken.isNotEmpty) { + prefs.setBool('showBackToHR', false); + prefs.remove('token'); + + // Retrieve and decode `hrSelectArgumentsData` + final String? detailsString = prefs.getString('hrSelectArgumentsData'); + if (detailsString != null) { + final dynamic details = jsonDecode(detailsString); + print('Decoded details:'); + print(details); + + // Ensure that details is a Map before passing it + if (details is Map) { + Navigator.pushNamed(context, 'hrPolicyDetails', arguments: details); + } else { + print('Error: Decoded details is not a Map.'); + } + } else { + print('hrSelectArgumentsData is null.'); + } + } else { + print('hrtoken is null or empty.'); + } + } + @override Widget build(BuildContext context) { dynamic arguments = ModalRoute.of(context)!.settings.arguments; @@ -910,7 +967,33 @@ class _empDetailsState extends State { child: Row( children: [ Expanded( - flex: 12, + flex: 6, + child: Container( + width: 150, + height: 150, + alignment: Alignment.centerLeft, + child: ElevatedButton( + onPressed: () { + backFunction(); + }, + child: Text( + 'Back', + style: GoogleFonts.poppins( + color: Color(0xFFE26728)), + ), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(5), + side: BorderSide( + color: Color(0xFFE26728)), + ), + ), + ), + )), + Expanded( + flex: 6, child: Container( width: 150, height: 150, @@ -1486,8 +1569,8 @@ class _empDetailsState extends State { initialValue: selfDoj ?? '', decoration: InputDecoration( border: OutlineInputBorder(), - hintText: 'Date of Joining', - labelText: 'Date of Joining', + hintText: 'Date Coverage', + labelText: 'Date Coverage', contentPadding: EdgeInsets.symmetric( vertical: 10, horizontal: 15), ), @@ -1601,8 +1684,8 @@ class _empDetailsState extends State { initialValue: selfDoj ?? '', decoration: InputDecoration( border: OutlineInputBorder(), - hintText: 'Date of Joining', - labelText: 'Date of Joining', + hintText: 'Date Coverage', + labelText: 'Date Coverage', contentPadding: EdgeInsets.symmetric( vertical: 10, horizontal: 15), ), @@ -1658,7 +1741,8 @@ class _empDetailsState extends State { String? gpaPolicyName = item['Policy_Name']; String? gpaECardDownload = item['eCardDownload']; - String? gpaSumInsured; + String? client_policy_id = item['ClientPolicyId']; + String? gpaSumInsured = item['si_value']; List gpaMappedFamilyFloaters = []; if (item['mapped_family_floaters'] != null) { @@ -1669,11 +1753,11 @@ class _empDetailsState extends State { .where((element) => element['is_value_exist'] == true) .toList(); - if (getTrueObjects.length > 0) { - gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; - } else { - gpaSumInsured = item['Policy_Terms']['sumInsured2']; - } + // if (getTrueObjects.length > 0) { + // gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; + // } else { + // gpaSumInsured = item['Policy_Terms']['sumInsured2']; + // } int gpaOpenForEnrollment = int.parse(item['OpenForEnrollment']); List familyFloaterContainers = []; @@ -1762,7 +1846,9 @@ class _empDetailsState extends State { MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( - onTap: () { + onTap: () async { + await getSelfEmployeeProfile( + token, client_policy_id); openSelfForm('View'); }, child: Text( @@ -1907,6 +1993,7 @@ class _empDetailsState extends State { print(item); setState(() { gmcPolicyName = item['Policy_Name']; + gmc_client_policy_id = item['ClientPolicyId']; gmcFloaterTextHeading = item['floter_text_heading']; gmcFloaterTextDescription = item['floter_text_description']; gmcNotes = item['notes']; @@ -2059,8 +2146,10 @@ class _empDetailsState extends State { MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( - onTap: () { + onTap: () async { if (floaterData['relationship'] == 'Self') { + await getSelfEmployeeProfile( + token, gmc_client_policy_id); openSelfForm('View'); } else { openForm( diff --git a/lib/empReview.dart b/lib/empReview.dart old mode 100644 new mode 100755 index 23d0588..93a4ce2 --- a/lib/empReview.dart +++ b/lib/empReview.dart @@ -28,6 +28,7 @@ class _empReviewDetailsState extends State { late ApiService apiService; bool isLoading = true; bool isChecked = false; + bool login_by_hr = false; bool topUpSiIsChecked = false; // Declare the _isSwitched variable here bool topUpParentIsChecked = false; // Declare the _isSwitched variable here bool addOnsDependentIsChecked = @@ -310,8 +311,19 @@ class _empReviewDetailsState extends State { empClientBranchId == null) { return; } + final SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('hrtoken')) { + setState(() { + login_by_hr = true; + }); + } final response = await apiService.getGpaEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GPA', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GPA', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { setState(() { @@ -339,8 +351,19 @@ class _empReviewDetailsState extends State { empClientBranchId == null) { return; } + final SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('hrtoken')) { + setState(() { + login_by_hr = true; + }); + } final response = await apiService.getGmcEmpPolicyDetailsToApi( - empPrimaryId, empCodeString!, client_id!, 'GMC', empClientBranchId!); + empPrimaryId, + empCodeString!, + client_id!, + 'GMC', + empClientBranchId!, + login_by_hr); if (response['status'] == 'success') { setState(() { gmcPolicies = response['data']; @@ -2554,7 +2577,7 @@ class _empReviewDetailsState extends State { String? gpaPolicyName = item['Policy_Name']; String? gpaPolicyType = item['type']; String? gpaECardDownload = item['eCardDownload']; - String? gpaSumInsured; + String? gpaSumInsured = item['si_value']; List gpaMappedFamilyFloaters = []; if (item['mapped_family_floaters'] != null) { @@ -2565,11 +2588,11 @@ class _empReviewDetailsState extends State { .where((element) => element['is_value_exist'] == true) .toList(); - if (getTrueObjects.length > 0) { - gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; - } else { - gpaSumInsured = item['Policy_Terms']['sumInsured2']; - } + // if (getTrueObjects.length > 0) { + // gpaSumInsured = getTrueObjects[0]["data"]["basic_cover_si"]; + // } else { + // gpaSumInsured = item['Policy_Terms']['sumInsured2']; + // } int gpaOpenForEnrollment = int.parse(item['OpenForEnrollment']); List familyFloaterContainers = []; diff --git a/lib/excel_verification.dart b/lib/excel_verification.dart old mode 100644 new mode 100755 diff --git a/lib/firebase-config.dart b/lib/firebase-config.dart old mode 100644 new mode 100755 diff --git a/lib/home.dart b/lib/home.dart old mode 100644 new mode 100755 diff --git a/lib/hrDashboard.dart b/lib/hrDashboard.dart old mode 100644 new mode 100755 index 9a9cf78..d3c9317 --- a/lib/hrDashboard.dart +++ b/lib/hrDashboard.dart @@ -23,19 +23,22 @@ class hrDashboard extends StatefulWidget { State createState() => _hrDashboardState(); } -class _hrDashboardState extends State { +class _hrDashboardState extends State with SingleTickerProviderStateMixin { late ApiService apiService; + late TabController _tabController; bool isLoading = false; late String _token; dynamic getPolicyNo; // bool _isLoading = false; dynamic getPolicyNameDetails; - dynamic clintID; + dynamic enrollmentClient_id; dynamic policy_name; dynamic getCardArrays = []; dynamic clientName; dynamic clientLogo; - dynamic empRefId; + dynamic empClientBranchId; + dynamic enrollmentEmpClientBranchId; + dynamic empClientId; final List cardColors = [ Color(0xFFFFE3D9), Color(0xFFFFD9EE), @@ -43,12 +46,19 @@ class _hrDashboardState extends State { Color(0xFFE4DFFF), ]; ScrollController _scrollController = ScrollController(); + int selectedIndex = 0; @override void initState() { super.initState(); apiService = ApiService(context); // Initialize ApiService here _loadToken(); + _tabController = TabController(length: 4, vsync: this); + _tabController.addListener(() { + setState(() { + selectedIndex = _tabController.index; + }); + }); // Future.delayed(Duration(seconds: 3), () { // setState(() { // isLoading = false; @@ -59,27 +69,37 @@ class _hrDashboardState extends State { @override void dispose() { super.dispose(); + _tabController.dispose(); } Future _loadToken() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); - final token = prefs.getString('hrtoken'); - if (token != null && token.isNotEmpty) { - setState(() { - _token = token; - }); - Map? decodedToken = Jwt.parseJwt(token); - clintID = decodedToken['client_id'].toString(); - empRefId = prefs.getString('empRefId'); - print(empRefId); - print(clintID); + final _postToken = prefs.getString('_postToken'); + final enrollToken = prefs.getString('enrollToken'); + if (_postToken != null && _postToken.isNotEmpty) { + Map? decodedToken = Jwt.parseJwt(_postToken); + empClientId = decodedToken['client_id'].toString(); + empClientBranchId = prefs.getString('empClientBranchId'); + print(empClientId); + print(empClientBranchId); if (prefs.containsKey('clientLogo') && prefs.containsKey('clientName')) { clientLogo = prefs.getString('clientLogo'); clientName = prefs.getString('clientName'); } else { - getClientLogoAndDetails(); + getClientLogoAndDetails(empClientBranchId,empClientId,_postToken); } - getCashDepositDetails(clintID); + getCashDepositDetails(empClientBranchId,empClientId,_postToken); + } else if (enrollToken != null && enrollToken.isNotEmpty) { + Map? decodedToken = Jwt.parseJwt(enrollToken); + enrollmentClient_id = decodedToken['client_id'].toString(); + enrollmentEmpClientBranchId = prefs.getString('enrollmentEmpClientBranchId'); + if (prefs.containsKey('clientLogo') && prefs.containsKey('clientName')) { + clientLogo = prefs.getString('clientLogo'); + clientName = prefs.getString('clientName'); + } else { + getClientLogoAndDetails(enrollmentEmpClientBranchId,enrollmentClient_id,enrollToken); + } + getCashDepositDetails(enrollmentEmpClientBranchId,enrollmentClient_id,enrollToken); } else { // Token is empty or null, handle accordingly (e.g., navigate to login screen) // For now, let's navigate to the login screen @@ -88,15 +108,15 @@ class _hrDashboardState extends State { } } - Future getClientLogoAndDetails() async { + Future getClientLogoAndDetails(clintBranchId,clintID,token) async { var url = Uri.parse(Environment.apiUrl + - 'getClientDetails?client_id=$clintID&client_branch_id=$empRefId'); + 'getClientDetails?client_id=$clintID&client_branch_id=$clintBranchId'); try { var response = await http.get( url, headers: { 'Authorization': - 'Bearer $_token', // Add token to the Authorization header + 'Bearer $token', // Add token to the Authorization header }, ); if (response.statusCode == 200) { @@ -135,21 +155,26 @@ class _hrDashboardState extends State { } } - Future getCashDepositDetails(String clintID) async { + Future getCashDepositDetails(clintBranchId,clintID,token) async { + print('IN'); + isLoading = true; // setState(() { // _isLoading = true; // }); try { - if (clintID == null || empRefId == null) { + if (clintBranchId == null || clintID == null) { return; } final response = - await apiService.getCashDepositDetailsToApi(clintID!, empRefId!); + await apiService.getCashDepositDetailsToApi(clintID!, clintBranchId!,token); if (response['status'] == 'success') { isLoading = false; setState(() { + print('response'); + print(response['data']); getCardArrays = List>.from(response['data']); + print('getCardArrays'); print(getCardArrays); }); } else { @@ -197,6 +222,18 @@ class _hrDashboardState extends State { } } + final List> policies = List.generate(10, (index) { + return { + "policyNo": index % 2 == 0 + ? "GMC - S70000/48/2025/401" + : "GMC - 4016/X0/351234479/00/000", + "insurer": "ICICI Lombard General Insurance Company Limited", + "draft": "1234", + "enrolled": "4", + "total": "1234", + }; + }); + @override Widget build(BuildContext context) { if (getCardArrays == []) { @@ -303,6 +340,81 @@ class _hrDashboardState extends State { ), ), SizedBox(height: 16), + Container( + padding: const EdgeInsets.all(5), + decoration: BoxDecoration( + color: Color(0xFFC4E3E6), // 🔹 Background behind the TabBar + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.transparent), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.15), + blurRadius: 4, + offset: const Offset(0, 4), + ), + ], + ), + child: TabBar( + controller: _tabController, + isScrollable: true, + labelPadding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0), + // indicator: BoxDecoration( + // color: const Color(0xFF00999E), // Selected tab background + // borderRadius: BorderRadius.circular(12), + // boxShadow: [ + // BoxShadow( + // color: Colors.black.withOpacity(0.2), + // blurRadius: 4, + // offset: const Offset(0, 2), + // ) + // ], + // ), + dividerColor: Colors.transparent, + indicatorColor: Colors.transparent, + labelColor: Colors.white, + unselectedLabelColor: const Color(0xFF828282), + tabs: [ + CustomTab(icon: Icons.grid_view, label: 'Pre Enrollment', isSelected: selectedIndex == 0), + CustomTab(icon: Icons.verified_user, label: 'Active Policies', isSelected: selectedIndex == 1), + CustomTab(icon: Icons.desktop_windows, label: 'CD', isSelected: selectedIndex == 2), + CustomTab(icon: Icons.receipt_long, label: 'Claims', isSelected: selectedIndex == 3), + ], + ), + ), + + + // Expanded TabBarView + SizedBox( + height: 400, // Adjust height based on your layout + child: TabBarView( + controller: _tabController, + children: [ + // Pre Enrollment Tab + Card( + elevation: 5, + color: Colors.white, + child: Container( + child: GridView.builder( + itemCount: getCardArrays.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, // Adjust for screen size (e.g., use 2 or 3 for tablets) + crossAxisSpacing: 16, + mainAxisSpacing: 0, + childAspectRatio: 2, + ), + itemBuilder: (context, index) { + return buildPolicyCard(getCardArrays[index]); + }, + ), + ) + ), + + Center(child: Text("Active Policies")), + Center(child: Text("CD")), + Center(child: Text("Claims")), + ], + ), + ), // if (getCardArrays.length != 0) // Card( // elevation: 0, @@ -412,263 +524,263 @@ class _hrDashboardState extends State { // ])), // ), // SizedBox(height: 16), - if (getCardArrays.length != 0) - Card( - elevation: 0, - color: Colors.white, - child: Padding( - padding: Responsive.isDesktop(context) - ? EdgeInsets.all(20) - : EdgeInsets.all(10), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: List.generate( - numExpanded, - (index) { - var insurerName = getCardArrays[index] - ['insurerName']; - var policyDetails = - getCardArrays[index] - ['policyDetails']; - - // Determine the color for the policyDetails based on the index of the card in getCardArrays - var cardColorIndex = - getCardArrays.indexOf( - getCardArrays[index]) % - cardColors.length; - var cardColor = - cardColors[cardColorIndex]; - - return Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - insurerName, - style: GoogleFonts.poppins( - fontSize: 18, - fontWeight: FontWeight.w600, - color: Colors.black, - ), - ), - SizedBox(height: 8), - Row( - children: [ - IconButton( - icon: - Icon(Icons.arrow_back), - onPressed: () { - _scrollController - .animateTo( - _scrollController - .offset - - 300, - duration: Duration( - milliseconds: 500), - curve: Curves.easeInOut, - ); - }, - ), - Expanded( - child: - SingleChildScrollView( - scrollDirection: - Axis.horizontal, - controller: - _scrollController, - dragStartBehavior: - DragStartBehavior - .start, - child: Row( - children: List.generate( - policyDetails.length, - (index) => Container( - width: 300, - height: - policyHeight, - child: - GestureDetector( - onTap: () { - Navigator.pushNamed( - context, - 'hrPolicyDetails', - arguments: - policyDetails[ - index]); - }, - child: - MouseRegion( - cursor: - SystemMouseCursors - .click, - child: Card( - elevation: 3, - color: - cardColor, - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - ListTile( - title: - SizedBox( - height: - 50, - child: - Text( - '${policyDetails[index]['policy_name']} - (${policyDetails[index]['type']})', - style: - GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF000000), - height: 1.5, - ), - softWrap: - true, - ), - ), - ), - SizedBox( - height: - 8), - Padding( - padding: EdgeInsets.only( - left: - 15, - right: - 15), - child: - Row( - children: [ - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - 'Draft', - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF000000), - height: 1.5, - ), - ), - Text( - policyDetails[index]['membersCountOfDraft'].toString(), - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Color(0xFF000000), - height: 1.5, - ), - ), - ], - ), - ), - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - 'Enrolled', - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF000000), - height: 1.5, - ), - ), - Text( - policyDetails[index]['membersCountOfEnrolled'].toString(), - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Color(0xFF000000), - height: 1.5, - ), - ), - ], - ), - ), - Expanded( - flex: 4, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - 'Total', - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF000000), - height: 1.5, - ), - ), - Text( - policyDetails[index]['totalMembersCount'].toString(), - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Color(0xFF000000), - height: 1.5, - ), - ), - ], - ), - ), - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ), - ), - ), - IconButton( - icon: Icon( - Icons.arrow_forward), - onPressed: () { - _scrollController - .animateTo( - _scrollController - .offset + - 300, - duration: Duration( - milliseconds: 500), - curve: Curves.easeInOut, - ); - }, - ), - ], - ), - SizedBox(height: 20), - ], - ); - }, - ), - ), - ), - ], - ), - ], - ), - ), - ) + // if (getCardArrays.length != 0) + // Card( + // elevation: 0, + // color: Colors.white, + // child: Padding( + // padding: Responsive.isDesktop(context) + // ? EdgeInsets.all(20) + // : EdgeInsets.all(10), + // child: Column( + // children: [ + // Row( + // children: [ + // Expanded( + // child: Column( + // crossAxisAlignment: + // CrossAxisAlignment.start, + // children: List.generate( + // numExpanded, + // (index) { + // var insurerName = getCardArrays[index] + // ['insurerName']; + // var policyDetails = + // getCardArrays[index] + // ['policyDetails']; + // + // // Determine the color for the policyDetails based on the index of the card in getCardArrays + // var cardColorIndex = + // getCardArrays.indexOf( + // getCardArrays[index]) % + // cardColors.length; + // var cardColor = + // cardColors[cardColorIndex]; + // + // return Column( + // crossAxisAlignment: + // CrossAxisAlignment.start, + // children: [ + // Text( + // insurerName, + // style: GoogleFonts.poppins( + // fontSize: 18, + // fontWeight: FontWeight.w600, + // color: Colors.black, + // ), + // ), + // SizedBox(height: 8), + // Row( + // children: [ + // IconButton( + // icon: + // Icon(Icons.arrow_back), + // onPressed: () { + // _scrollController + // .animateTo( + // _scrollController + // .offset - + // 300, + // duration: Duration( + // milliseconds: 500), + // curve: Curves.easeInOut, + // ); + // }, + // ), + // Expanded( + // child: + // SingleChildScrollView( + // scrollDirection: + // Axis.horizontal, + // controller: + // _scrollController, + // dragStartBehavior: + // DragStartBehavior + // .start, + // child: Row( + // children: List.generate( + // policyDetails.length, + // (index) => Container( + // width: 300, + // height: + // policyHeight, + // child: + // GestureDetector( + // onTap: () { + // Navigator.pushNamed( + // context, + // 'hrPolicyDetails', + // arguments: + // policyDetails[ + // index]); + // }, + // child: + // MouseRegion( + // cursor: + // SystemMouseCursors + // .click, + // child: Card( + // elevation: 3, + // color: + // cardColor, + // child: Column( + // crossAxisAlignment: + // CrossAxisAlignment + // .start, + // children: [ + // ListTile( + // title: + // SizedBox( + // height: + // 50, + // child: + // Text( + // '${policyDetails[index]['policy_name']} - (${policyDetails[index]['type']})', + // style: + // GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w500, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // softWrap: + // true, + // ), + // ), + // ), + // SizedBox( + // height: + // 8), + // Padding( + // padding: EdgeInsets.only( + // left: + // 15, + // right: + // 15), + // child: + // Row( + // children: [ + // Expanded( + // flex: 4, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Text( + // 'Draft', + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w500, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // Text( + // policyDetails[index]['membersCountOfDraft'].toString(), + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w400, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // ], + // ), + // ), + // Expanded( + // flex: 4, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Text( + // 'Enrolled', + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w500, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // Text( + // policyDetails[index]['membersCountOfEnrolled'].toString(), + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w400, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // ], + // ), + // ), + // Expanded( + // flex: 4, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Text( + // 'Total', + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w500, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // Text( + // policyDetails[index]['totalMembersCount'].toString(), + // style: GoogleFonts.poppins( + // fontSize: 16, + // fontWeight: FontWeight.w400, + // color: Color(0xFF000000), + // height: 1.5, + // ), + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ), + // ), + // ), + // ), + // ), + // ), + // ), + // IconButton( + // icon: Icon( + // Icons.arrow_forward), + // onPressed: () { + // _scrollController + // .animateTo( + // _scrollController + // .offset + + // 300, + // duration: Duration( + // milliseconds: 500), + // curve: Curves.easeInOut, + // ); + // }, + // ), + // ], + // ), + // SizedBox(height: 20), + // ], + // ); + // }, + // ), + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ) ], ), ), @@ -695,204 +807,167 @@ class _hrDashboardState extends State { } } - void openForm(dynamic floaterData, dynamic insurerName, dynamic clintId, - dynamic insurerId, dynamic cardColors) { - print(clintId); - print(insurerId); - print(floaterData); - print(floaterData); - print('test'); - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - elevation: 0, - backgroundColor: Colors.transparent, - content: SizedBox( - width: 1000, - child: SingleChildScrollView( - child: Card( - elevation: 0, - child: Column( - children: [ - Container( - child: Column( - children: [ - Container( - padding: - EdgeInsets.all(10), // Set your desired padding - color: - cardColors, // Set your desired background color - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 10, - child: Container( - alignment: Alignment.centerLeft, - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Text(insurerName ?? '', - style: GoogleFonts.poppins( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.black, - )), - ], - ), - ), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment - .centerRight, // Align text to the center - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () { - downloadExcel( - clintId, insurerId, insurerName); - }, - child: Icon( - Icons - .download, // Replace with your desired icon - color: Colors - .black, // Replace with your desired icon color - ), - ), - ), - ), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment - .centerRight, // Align text to the center - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () { - Navigator.of(context).pop(); - }, - child: Icon( - Icons - .close, // Replace with your desired icon - color: Colors - .black, // Replace with your desired icon color - ), - ), - ), - ), - ), - ], - ), - ), - SizedBox(height: 15), - Row( - children: [ - Expanded( - child: SingleChildScrollView( - child: _buildDataTable(context, floaterData), - ), - ) - ], - ), - ], - ), - ), - ], - ), + Widget buildPolicyCard(Map policy) { + return Card( + elevation: 3, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + policy['type'] ?? '', + style: const TextStyle( + fontWeight: FontWeight.w600, + fontSize: 14, ), ), - ), - ); - }, + const SizedBox(height: 4), + Text( + policy['policy_name'] ?? '', + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildCountBox(policy['membersCountOfDraft'].toString(), "Draft"), + _buildCountBox(policy['membersCountOfEnrolled'].toString(), "Enrolled"), + _buildCountBox(policy['totalMembersCount'].toString(), "Total"), + ], + ), + ], + ), + ), ); } - Widget _buildDataTable(BuildContext context, dynamic tableData) { - print('tableData'); - print(tableData); - - // Check if tableData is a list - if (tableData is List) { - // If tableData is a list and not empty - if (tableData.isNotEmpty && tableData[0] is Map) { - return Card( - elevation: 0, // Set elevation to 0 for no shadow - child: PaginatedDataTable( - rowsPerPage: 10, // Adjust rows per page as needed - columns: [ - DataColumn(label: Text('Date')), - DataColumn(label: Text('Description')), - DataColumn(label: Text('Transaction Type')), - DataColumn(label: Text('Amount')), - DataColumn(label: Text('Balance')), - ], - source: _DependenceDataSource(context, tableData), + Widget _buildCountBox(String count, String label) { + return Column( + children: [ + Container( + width: 50, + height: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: const Color(0xFFDFF1F3), + borderRadius: BorderRadius.circular(8), ), - ); - } else { - // If tableData is empty or not in the expected format - return Text('No Data Available', textAlign: TextAlign.center); - } - } else { - // If tableData is not a list, return a message indicating invalid data - return Text('Invalid Data Format', textAlign: TextAlign.center); - } - } -} - -class _DependenceDataSource extends DataTableSource { - final List> _data; - final BuildContext context; - _DependenceDataSource(this.context, List tableData) - : _data = tableData.map((e) => e as Map).toList(); - - @override - DataRow getRow(int index) { - final row = _data[index]; - - // Format date of birth to "July 10, 1996" - String created_Date = - row['created_at'] != null ? formatDateString(row['created_at']) : 'N/A'; - - return DataRow( - // Setting row background color - cells: [ - DataCell(Text(created_Date)), - DataCell(Text(row['description'] ?? 'N/A')), - DataCell(Text(row['transaction_type'].toString() ?? '')), - DataCell(Text(row['amount'] ?? 'N/A')), - DataCell(Text(row['balance'] ?? 'N/A')), + child: Text( + count, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600), + ), + ), + const SizedBox(height: 6), + Text(label, style: const TextStyle(fontSize: 12, color: Colors.black87)), ], ); } - @override - bool get isRowCountApproximate => false; +} + +class CustomTab extends StatelessWidget { + final IconData icon; + final String label; + final bool isSelected; + + const CustomTab({ + required this.icon, + required this.label, + required this.isSelected, + }); @override - int get rowCount => _data.length; - - @override - int get selectedRowCount => 0; - - String formatDateString(String dateString) { - // Parse the input date string - DateTime inputDate = DateTime.parse(dateString); - - // Format the date as DD-MM-YYYY HH:mm A - String formattedDate = DateFormat('dd-MM-yyyy hh:mm a').format(inputDate); - - return formattedDate; + Widget build(BuildContext context) { + return Tab( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 6), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + decoration: BoxDecoration( + color: isSelected ? const Color(0xFF00999E) : Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + if (isSelected) + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 4, + offset: const Offset(0, 2), + ) + else + BoxShadow( + color: Colors.grey.withOpacity(0.2), + blurRadius: 2, + offset: const Offset(0, 1), + ), + ], + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(icon, size: 18, color: isSelected ? Colors.white : const Color(0xFF828282)), + const SizedBox(width: 6), + Text( + label, + style: TextStyle( + fontWeight: FontWeight.w600, + color: isSelected ? Colors.white : const Color(0xFF828282), + ), + ), + ], + ), + ), + ); } } + +class PolicyCard extends StatelessWidget { + final Map policy; + + const PolicyCard({required this.policy}); + + @override + Widget build(BuildContext context) { + return Card( + elevation: 4, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(policy["policyNo"], + style: const TextStyle(fontWeight: FontWeight.bold)), + const SizedBox(height: 4), + Text(policy["insurer"], + style: const TextStyle(fontSize: 11, color: Colors.grey)), + const Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStatusBox("Draft", policy["draft"]), + _buildStatusBox("Enrolled", policy["enrolled"]), + _buildStatusBox("Total", policy["total"]), + ], + ) + ], + ), + ), + ); + } + + Widget _buildStatusBox(String label, String value) { + return Column( + children: [ + Text(value, + style: const TextStyle( + fontWeight: FontWeight.bold, color: Colors.teal)), + const SizedBox(height: 2), + Text(label, style: const TextStyle(fontSize: 11, color: Colors.grey)), + ], + ); + } +} \ No newline at end of file diff --git a/lib/hrHome.dart b/lib/hrHome.dart old mode 100644 new mode 100755 diff --git a/lib/hrLogin.dart b/lib/hrLogin.dart old mode 100644 new mode 100755 index 68851a4..fc373a8 --- a/lib/hrLogin.dart +++ b/lib/hrLogin.dart @@ -13,6 +13,8 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:flutter_animated_button/flutter_animated_button.dart'; +import 'email_verify.dart'; + class MyHrLogin extends StatefulWidget { const MyHrLogin({Key? key}); @@ -21,80 +23,107 @@ class MyHrLogin extends StatefulWidget { } class _MyPhoneState extends State { + final TextEditingController emailController = TextEditingController(); TextEditingController countryController = TextEditingController(); TextEditingController mobileController = TextEditingController(); final _formKey = GlobalKey(); + bool _isCheckingToken = false; + dynamic empMobileNo; + dynamic empEmailid; + final FirebaseAuth _auth = FirebaseAuth.instance; late String _verificationId; int? _resendToken; bool _isLoading = false; + bool isEmailFieldVisible = false; @override void initState() { countryController.text = "+91"; super.initState(); - checkTokenAvailability(); } - Future checkTokenAvailability() async { - final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String? hrtoken = prefs.getString('hrtoken'); - - if (hrtoken != null && hrtoken.isNotEmpty) { - // Token available, navigate to home page - Navigator.pushReplacementNamed(context, 'hrDashboard', - arguments: {'mobile': ''}); - } + void toggleField() { + setState(() { + isEmailFieldVisible = !isEmailFieldVisible; + }); } - void toggleLoginType() { - Navigator.pushNamed(context, 'phone'); // Navigate to another page - } - - Future verifyMobileNumber() async { + Future verifyMobileAndEmailNumber() async { try { - setState(() { - _isLoading = true; - }); - var enteredMobileNumber = mobileController.text; - final response = await http.post( - Uri.parse(Environment.apiUrl + 'verifyHrWithMobileNumber'), - body: json.encode({'mobile_number': enteredMobileNumber}), - headers: { - HttpHeaders.contentTypeHeader: 'application/json', - }, - ); + if (_formKey.currentState!.validate()) { + setState(() { + _isLoading = true; + }); - if (response.statusCode == 200) { - Map data = json.decode(response.body); - bool userVerification = data['data']['user_verification']; - String message = data['data']['message']; - if (userVerification) { - _verifyPhoneNumber(); - // ToastHelper.showSuccessToast(context, message); - // Navigator.pushNamed(context, 'hrVerify', - // arguments: enteredMobileNumber); + // Determine the API and the payload based on the visible field + String apiEndpoint = isEmailFieldVisible + ? Environment.apiUrl + 'verifyHrWithEmail' + : Environment.apiUrl + 'verifyHrWithMobileNumber'; + + Map payload = isEmailFieldVisible + ? {'email': emailController.text} + : {'mobile_no': mobileController.text}; + + // var enteredMobileNumber = mobileController.text; + final response = await http.post( + Uri.parse(apiEndpoint), + body: json.encode(payload), + headers: { + HttpHeaders.contentTypeHeader: 'application/json', + }, + ); + + if (response.statusCode == 200) { + Map data = json.decode(response.body); + bool userVerification = data['data']['user_verification']; + String message = data['data']['message']; + if (userVerification) { + final SharedPreferences prefs = + await SharedPreferences.getInstance(); + // var enteredMobileNumber = mobileController.text; + // prefs.setString('empMobileNo', enteredMobileNumber); + if (isEmailFieldVisible) { + print('isEmailFieldVisible $isEmailFieldVisible'); + prefs.setString('empEmail', emailController.text); + print('${emailController.text}'); + ToastHelper.showSuccessToast( + context, 'Verification code sent to ${emailController.text}'); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MyEmailVerify( + email: emailController.text, // Pass the phone number + ), + ), + ); + } else { + _verifyPhoneNumber(); + } + + // ToastHelper.showSuccessToast(context, message); + } else { + setState(() { + _isLoading = false; + }); + ToastHelper.showErrorToast(context, message); + print('Invalid mobile number'); + } } else { setState(() { _isLoading = false; }); - ToastHelper.showErrorToast(context, message); - print('Invalid mobile number'); + ToastHelper.showErrorToast(context, 'Something went wrong'); + throw Exception('Failed to verify mobile number'); } - } else { - setState(() { - _isLoading = false; - }); - ToastHelper.showErrorToast(context, 'Failed to verify mobile number'); - throw Exception('Failed to verify mobile number'); } } catch (e) { setState(() { _isLoading = false; }); - print('Error: $e'); ToastHelper.showErrorToast(context, 'Something went wrong'); + print('Error: $e'); } } @@ -107,30 +136,49 @@ class _MyPhoneState extends State { timeout: const Duration(seconds: 60), verificationCompleted: (PhoneAuthCredential credential) async { await _auth.signInWithCredential(credential); - ToastHelper.showSuccessToast(context, 'Verified Successfully!'); - setState(() { - _isLoading = false; - }); + // ToastHelper.showSuccessToast(context, 'Verified Successfully!'); + // setState(() { + // _isLoading = false; + // }); }, verificationFailed: (FirebaseAuthException e) { - ToastHelper.showSuccessToast(context, 'Verification Failed!'); - if (e.code == 'invalid-phone-number') { - print('The provided phone number is not valid.'); + print('Verification Failed: ${e.code} - ${e.message}'); + String errorMessage; + if (e.code == 'invalid-app-credential') { + errorMessage = 'Invalid Credential. Please try again.'; + } else if (e.code == 'invalid-phone-number') { + errorMessage = 'The provided phone number is not valid.'; + } else if (e.code == 'too-many-requests') { + errorMessage = 'Too many requests. Try again later.'; + } else { + errorMessage = 'Verification Failed: ${e.message}'; } + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + duration: Duration(seconds: 2), + ), + ); + + ToastHelper.showSuccessToast(context, errorMessage); setState(() { _isLoading = false; }); }, - codeSent: (String verificationId, int? resendToken) { + codeSent: (String verificationId, int? resendToken) async { setState(() { _verificationId = verificationId; _resendToken = resendToken; }); + + // When getting the verificationId + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('verificationId', _verificationId); + + ToastHelper.showSuccessToast( context, 'Verification code sent to ${enteredMobileNumber}'); - setState(() { - _isLoading = false; - }); + Navigator.push( context, MaterialPageRoute( @@ -142,11 +190,16 @@ class _MyPhoneState extends State { ), ), ); + setState(() { + _isLoading = false; + }); }, - codeAutoRetrievalTimeout: (String verificationId) { + codeAutoRetrievalTimeout: (String verificationId) async{ setState(() { _verificationId = verificationId; }); + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('verificationId', verificationId); ToastHelper.showSuccessToast(context, 'Code auto-retrieval timed out.'); setState(() { _isLoading = false; @@ -168,7 +221,9 @@ class _MyPhoneState extends State { print('The provided phone number is not valid.'); } }, - codeSent: (String verificationId, int? resendToken) { + codeSent: (String verificationId, int? resendToken) async{ + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('verificationId', verificationId); setState(() { _verificationId = verificationId; _resendToken = resendToken; @@ -187,7 +242,9 @@ class _MyPhoneState extends State { ), ); }, - codeAutoRetrievalTimeout: (String verificationId) { + codeAutoRetrievalTimeout: (String verificationId) async{ + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('verificationId', verificationId); setState(() { _verificationId = verificationId; }); @@ -254,7 +311,7 @@ class _MyPhoneState extends State { onTap: () { // Add your navigation logic here // For example, you can use Navigator.push to navigate to another page - Navigator.pushNamed(context, 'phone'); + Navigator.pushNamed(context, 'hrLogin'); }, child: Row( children: [ @@ -388,41 +445,41 @@ class _MyPhoneState extends State { !Responsive.isTablet(context)) Row( children: [ - Expanded( - flex: 4, - child: Align( - alignment: Alignment.centerLeft, - child: AnimatedButton( - animatedOn: - AnimatedOn.onHover, - onPress: () { - Navigator.pushNamed( - context, 'phone'); - }, - onChanges: (change) {}, - height: 30, - width: 150, - text: 'Member Login', - isReverse: true, - selectedTextColor: - Colors.black, - transitionType: TransitionType - .RIGHT_CENTER_ROUNDER, - textStyle: - GoogleFonts.poppins( - fontSize: 16, - letterSpacing: 0, - color: Color(0xFF00989E), - fontWeight: FontWeight.w300, - ), - backgroundColor: Colors.white, - selectedBackgroundColor: - Color(0xFF00989E), - borderColor: - Color(0xFF00989E), - borderWidth: 1, - ), - )), + // Expanded( + // flex: 4, + // child: Align( + // alignment: Alignment.centerLeft, + // child: AnimatedButton( + // animatedOn: + // AnimatedOn.onHover, + // onPress: () { + // Navigator.pushNamed( + // context, 'phone'); + // }, + // onChanges: (change) {}, + // height: 30, + // width: 150, + // text: 'Member Login', + // isReverse: true, + // selectedTextColor: + // Colors.black, + // transitionType: TransitionType + // .RIGHT_CENTER_ROUNDER, + // textStyle: + // GoogleFonts.poppins( + // fontSize: 16, + // letterSpacing: 0, + // color: Color(0xFF00989E), + // fontWeight: FontWeight.w300, + // ), + // backgroundColor: Colors.white, + // selectedBackgroundColor: + // Color(0xFF00989E), + // borderColor: + // Color(0xFF00989E), + // borderWidth: 1, + // ), + // )), Expanded( flex: 8, child: Align( @@ -452,38 +509,17 @@ class _MyPhoneState extends State { Container( margin: Responsive.isDesktop(context) ? EdgeInsets.symmetric( - horizontal: 150) - : EdgeInsets.symmetric(horizontal: 0), + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), child: Row( mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Text( - "Welcome to Nhance", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - SizedBox( - height: 15, - ), - Container( - margin: Responsive.isDesktop(context) - ? EdgeInsets.symmetric( - horizontal: 150) - : EdgeInsets.symmetric(horizontal: 0), - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, + MainAxisAlignment.center, children: [ Expanded( child: Text( - "Login to manage the employee enrollment and overall health insurance programme of your organisation", - style: TextStyle( + "Login with your ${isEmailFieldVisible ? 'email' : 'mobile number'} and OTP to review and enroll for exciting health benefits for you and your family", + style: GoogleFonts.poppins( fontSize: 12, color: Color(0xFF000000)), textAlign: TextAlign.center, @@ -495,110 +531,209 @@ class _MyPhoneState extends State { SizedBox( height: 20, ), - Container( - height: 55, - margin: Responsive.isDesktop(context) - ? EdgeInsets.symmetric( + Column( + children: [ + isEmailFieldVisible + ? Container( + height: 55, + margin: Responsive + .isDesktop(context) + ? EdgeInsets.symmetric( horizontal: 150) - : EdgeInsets.symmetric(horizontal: 0), - decoration: BoxDecoration( - border: Border.all( - width: 1, color: Colors.grey), - borderRadius: BorderRadius.circular(10), - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - SizedBox( - width: 10, - ), - SizedBox( - width: 40, - child: TextField( - controller: countryController, - keyboardType: - TextInputType.number, - decoration: InputDecoration( - border: InputBorder.none, - ), - ), - ), - Text( - "|", - style: TextStyle( - fontSize: 33, + : EdgeInsets.symmetric( + horizontal: 0), + decoration: BoxDecoration( + border: Border.all( + width: 1, color: Colors.grey), + borderRadius: + BorderRadius.circular( + 10), ), - SizedBox( - width: 10, + child: TextFormField( + controller: + emailController, + keyboardType: + TextInputType + .emailAddress, + decoration: + InputDecoration( + border: + InputBorder.none, + hintText: + "Enter your email", + contentPadding: + EdgeInsets + .symmetric( + horizontal: + 10), + ), + validator: (value) { + if (value == null || + value.isEmpty) { + return 'Please enter your email'; + } + if (!RegExp( + r'^[^@]+@[^@]+\.[^@]+') + .hasMatch(value)) { + return 'Please enter a valid email'; + } + return null; + }, ), - Expanded( - child: TextFormField( - controller: mobileController, - keyboardType: TextInputType.phone, - decoration: InputDecoration( - border: InputBorder.none, - hintText: - "Enter your mobile number", + ) + : Container( + height: 55, + margin: Responsive + .isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: Colors.grey), + borderRadius: + BorderRadius.circular( + 10), + ), + child: Row( + children: [ + SizedBox(width: 10), + SizedBox( + width: 40, + child: TextField( + controller: + countryController, + keyboardType: + TextInputType + .number, + decoration: + InputDecoration( + border: + InputBorder + .none, + ), + ), + ), + Text( + "|", + style: TextStyle( + fontSize: 33, + color: + Colors.grey), + ), + SizedBox(width: 10), + Expanded( + child: TextFormField( + controller: + mobileController, + keyboardType: + TextInputType + .phone, + decoration: + InputDecoration( + border: + InputBorder + .none, + hintText: + "Enter your mobile number", + ), + validator: (value) { + if (value == + null || + value + .isEmpty) { + return 'Please enter your mobile number'; + } + if (value + .length != + 10) { + return 'Mobile number must be 10 digits'; + } + return null; + }, + inputFormatters: [ + FilteringTextInputFormatter + .digitsOnly, + LengthLimitingTextInputFormatter( + 10), + ], + ), + ), + ], + ), + ), + SizedBox(height: 15), + Container( + margin: + Responsive.isDesktop(context) + ? EdgeInsets.symmetric( + horizontal: 150) + : EdgeInsets.symmetric( + horizontal: 0), + child: SizedBox( + width: double.infinity, + height: 45, + child: ElevatedButton( + style: + ElevatedButton.styleFrom( + backgroundColor: + Color(0xFF00989E), + shape: + RoundedRectangleBorder( + borderRadius: + BorderRadius.circular( + 10), + ), + ), + onPressed: _isLoading + ? null + : verifyMobileAndEmailNumber, + child: _isLoading + ? CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation< + Color>( + Color(0xFF00989E), + ), + ) + : Text( + isEmailFieldVisible + ? "Login with Email OTP" + : "Login with Mobile OTP", + style: GoogleFonts + .poppins( + color: Color( + 0xFFFFFFFF), + ), ), - validator: (value) { - if (value == null || - value.isEmpty) { - return 'Please enter your mobile number'; - } - if (value.length != 10) { - return 'Mobile number must be 10 digits'; - } - return null; - }, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly, - LengthLimitingTextInputFormatter( - 10), - ], ), ), - ], - ), + ), + SizedBox(height: 15), + MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: toggleField, + child: Text( + isEmailFieldVisible + ? "Login with Mobile No" + : "Login with Email", + style: TextStyle( + color: Color(0xFF00989E), + ), + ), + ), + ), + ], ), SizedBox( - height: 20, + height: _size.width <= 1100 ? 0 : 0, ), - Container( - margin: Responsive.isDesktop(context) - ? EdgeInsets.symmetric( - horizontal: 150) - : EdgeInsets.symmetric(horizontal: 0), - child: SizedBox( - width: double.infinity, - height: 45, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF00989E), - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - ), - onPressed: _isLoading - ? null - : verifyMobileNumber, - child: _isLoading - ? CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation< - Color>( - Color(0xFF00989E)), - ) - : Text( - "Login With OTP", - style: TextStyle( - color: Color(0xFFFFFFFF)), - ), - ), - ), + SizedBox( + height: _size.width <= 1100 ? 0 : 0, ), SizedBox( height: _size.width <= 1100 ? 0 : 0, diff --git a/lib/hrPolicyDetails.dart b/lib/hrPolicyDetails.dart old mode 100644 new mode 100755 index e485c32..8ce54c8 --- a/lib/hrPolicyDetails.dart +++ b/lib/hrPolicyDetails.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:nhancepolicy/customAppBar/customAppBar.dart'; +import 'package:nhancepolicy/customAppBar/enrollmentAppBar.dart'; import 'package:nhancepolicy/excel_verification.dart'; import 'package:nhancepolicy/models/environment.dart'; import 'package:nhancepolicy/service/api_service.dart'; @@ -66,9 +66,11 @@ class _HrPolicyDetailsState extends State } Future _loadToken() async { + print('1'); final SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('hrtoken'); if (token != null && token.isNotEmpty) { + print('2'); setState(() { _token = token; }); @@ -84,11 +86,24 @@ class _HrPolicyDetailsState extends State } } + Future _saveArgumentsDataToLocalStorage(argumentsData) async { + print('6'); + print('argumentsData'); + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('hrSelectArgumentsData', jsonEncode(argumentsData)); + } + Future getPolicyDetails() async { + print('3'); try { + print('4'); setState(() { if (argumentsData != null && argumentsData is Map) { + print('5'); + _saveArgumentsDataToLocalStorage(argumentsData); + print('7'); if (argumentsData['type'] == 'GPA') { + print('8'); _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; @@ -165,10 +180,12 @@ class _HrPolicyDetailsState extends State } Future getEmployeeAndDependence(clintID, getPolicyNo) async { + print('9'); setState(() { isLoading = true; }); try { + print('10'); final response = await apiService.getEmployeeAndDependenceToApi( clintID!, getPolicyNo!, empRefId!); if (response['status'] == 'success') { @@ -331,6 +348,7 @@ class _HrPolicyDetailsState extends State print(arguments); if (arguments != null && arguments is Map) { argumentsData = arguments; + print('argumentsData $argumentsData'); } if (filteredData == []) { return Scaffold( @@ -426,7 +444,12 @@ class _HrPolicyDetailsState extends State cursor: SystemMouseCursors .click, child: GestureDetector( - onTap: () { + onTap: () async { + final prefs = + await SharedPreferences + .getInstance(); + await prefs.remove( + 'hrSelectArgumentsData'); Navigator.pushNamed( context, 'hrDashboard'); @@ -755,12 +778,14 @@ class _HrPolicyDetailsState extends State rowsPerPage: filteredData.length, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), + DataColumn(label: Text('TPA ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), - DataColumn(label: Text('Date of Joining')), + // DataColumn(label: Text('Date of Joining')), + DataColumn(label: Text('Date Coverage')), DataColumn(label: Text('Email')), DataColumn(label: Text('SI')), DataColumn(label: Text('Grade')), @@ -792,7 +817,10 @@ class _DependenceDataSource0 extends DataTableSource { } // Format date of birth to "July 10, 1996" String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; - String doj = row['doj'] != null ? formatDateString(row['doj']) : 'N/A'; + // String doj = row['doj'] != null ? formatDateString(row['doj']) : 'N/A'; + String dateCoverage = row['date_coverage'] != null + ? formatDateString(row['date_coverage']) + : 'N/A'; return DataRow( color: MaterialStateColor.resolveWith( @@ -804,12 +832,14 @@ class _DependenceDataSource0 extends DataTableSource { ? () => _navigateToAnotherPage(row) : null, // Navigation only for 'Self' rows ), + DataCell(Text(row['tpa_id'].toString(), style: textStyle)), DataCell(Text(row['name'].toString(), style: textStyle)), DataCell(Text(row['relationship'].toString(), style: textStyle)), DataCell(Text(dob, style: textStyle)), DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)), DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)), - DataCell(Text(doj, style: textStyle)), + // DataCell(Text(doj, style: textStyle)), + DataCell(Text(dateCoverage, style: textStyle)), DataCell(Text(row['email_corporate'] ?? 'N/A', style: textStyle)), DataCell(Text(row['basic_cover_si'] ?? 'N/A', style: textStyle)), DataCell(Text(row['grade'] ?? 'N/A', style: textStyle)), diff --git a/lib/hrVerify.dart b/lib/hrVerify.dart old mode 100644 new mode 100755 index 8e9c4d2..b65fa6e --- a/lib/hrVerify.dart +++ b/lib/hrVerify.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:nhancepolicy/customAppBar/toastHelper.dart'; import 'package:nhancepolicy/models/environment.dart'; +import 'package:nhancepolicy/service/api_service.dart'; import 'package:pinput/pinput.dart'; import 'dart:async'; import 'package:flutter/gestures.dart'; @@ -32,30 +33,49 @@ class MyHrVerify extends StatefulWidget { } class _MyVerifyState extends State { + TextEditingController countryController = TextEditingController(); + late ApiService apiService; TextEditingController _otpController = TextEditingController(); final _formKey = GlobalKey(); late Timer _timer; - int _secondsRemaining = 30; + int _secondsRemaining = 60; bool _isTimerRunning = false; - dynamic _token; + + dynamic enrollmentEmpClientBranchId; + dynamic enrollmentEmpCodeString; + dynamic enrollmentEmpPrimaryId; + dynamic enrollmentGpaEmpName; + dynamic enrollmentClient_id; + dynamic enrollmentEmp_status; + + dynamic empClientBranchId; dynamic empCodeString; dynamic empPrimaryId; dynamic gpaEmpName; dynamic client_id; + dynamic emp_status; + + dynamic _token; + dynamic _postToken; dynamic clientName; dynamic clientLogo; - dynamic empRefId; + dynamic fCMToken; late String verificationId; late String mobileNumber; final FirebaseAuth _auth = FirebaseAuth.instance; bool _isLoading = false; + dynamic empMobileNo; + dynamic empEmailid; + late String _verificationId; @override void initState() { super.initState(); - checkTokenAvailability(); + countryController.text = "+91"; + apiService = ApiService(context); + // checkTokenAvailability(); verificationId = widget.verificationId; mobileNumber = widget.mobileNumber; print('Received verificationId: $verificationId'); @@ -64,8 +84,19 @@ class _MyVerifyState extends State { // Handle the case where verificationId is not provided Navigator.pop(context); } - // Start the timer when the widget is initialized startTimer(); + // Equivalent to componentDidMount + _auth.authStateChanges().listen((User? user) { + if (user != null) { + // If user is already signed in, log them out + logOutFirebase(); + } + }); + } + + void logOutFirebase() async { + await _auth.signOut(); + print('User signed out'); } @override @@ -74,6 +105,7 @@ class _MyVerifyState extends State { super.dispose(); } + void startTimer() { _isTimerRunning = true; _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) { @@ -88,67 +120,12 @@ class _MyVerifyState extends State { }); } - Future checkTokenAvailability() async { - final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String? hrtoken = prefs.getString('hrtoken'); - - if (hrtoken != null && hrtoken.isNotEmpty) { - // Token available, navigate to home page - Navigator.pushReplacementNamed(context, 'hrDashboard'); - } - } - - Future resendOTP(String mobileNumber) async { - print(mobileNumber); - // Update the UI as needed - setState(() { - _secondsRemaining = 30; - _isTimerRunning = true; - }); - startTimer(); - try { - final response = await http.post( - Uri.parse(Environment.apiUrl + 'verifyHrWithMobileNumber'), - body: json.encode({'mobile_number': mobileNumber}), - headers: { - HttpHeaders.contentTypeHeader: 'application/json', - }, - ); - - if (response.statusCode == 200) { - // Handle successful response - ToastHelper.showSuccessToast(context, 'OTP resent successfully.'); - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar( - // content: Text('OTP resent successfully.'), - // ), - // ); - } else { - // Handle other response status codes - ToastHelper.showErrorToast(context, 'Failed to resend OTP'); - throw Exception('Failed to resend OTP'); - } - } catch (e) { - // Handle API call errors - print('Error: $e'); - ToastHelper.showErrorToast(context, 'Something went wrong'); - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar( - // content: Text('Failed to resend OTP. Please try again.'), - // ), - // ); - } - } - void generateToken(bool otpVerifyStatus) async { - // Retrieve the passed mobile number value - // final String mobileNumber = - // ModalRoute.of(context)!.settings.arguments as String; try { final response = await http.post( Uri.parse(Environment.apiUrl + 'getVerifiedHrData'), body: json.encode({ - 'mobile_number': mobileNumber, + 'mobile_no': mobileNumber, 'otp_verification': otpVerifyStatus }), headers: { @@ -157,103 +134,229 @@ class _MyVerifyState extends State { ); if (response.statusCode == 200) { + setState(() { + _isLoading = false; + }); Map data = json.decode(response.body); + print('data: $data'); _token = data['data']; - print(data); String status = data['status']; - print(status); - if (status == 'success') { - final SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString('hrtoken', data['data']); - // Decode the JWT token received from the API response - Map? decodedToken = Jwt.parseJwt(data['data']); - print('decodedToken'); - print(decodedToken); - empRefId = decodedToken['ref_id']; - print('empRefId'); - print(empRefId); - prefs.setString('empRefId', empRefId); - empCodeString = decodedToken['emp_code'].toString(); - prefs.setString('empCode', empCodeString); - empPrimaryId = decodedToken['id']; - prefs.setString('empPrimaryId', empPrimaryId); - gpaEmpName = decodedToken['name'].toString(); - prefs.setString('gpaEmpName', gpaEmpName); - client_id = decodedToken['client_id']; - prefs.setString('client_id', client_id); - getClientLogoAndDetails(); + // Directly access the post_enrollment data + Map post = data['post_enrollment']; + print('post: $post'); - print('Successfully Login'); - final hrtoken = prefs.getString('hrtoken'); - if (hrtoken != null && hrtoken.isNotEmpty) { - ToastHelper.showSuccessToast(context, 'Successfully Login'); - Navigator.pushNamed(context, 'hrDashboard'); - } else { - // Token is empty or null, handle accordingly (e.g., navigate to login screen) - // For now, let's navigate to the login screen - ToastHelper.showErrorToast(context, 'Session Out'); - Navigator.pushReplacementNamed(context, 'hrLogin'); - } - // Redirect to another page - } else { - ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again.'); - // Show a Snackbar if the OTP is invalid - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar( - // content: Text('Invalid OTP. Please try again.'), - // ), - // ); - } - } else { - ToastHelper.showErrorToast(context, 'Failed to verify OTP'); - throw Exception('Failed to verify OTP'); - } - } catch (e) { - print('Error: $e'); - ToastHelper.showErrorToast( - context, 'Failed to verify OTP. Please try again.'); - // Show a Snackbar if there's an error while verifying OTP - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar( - // content: Text('Failed to verify OTP. Please try again.'), - // ), - // ); - } - } + _postToken = post['data']; + String postStatus = post['status']; - void verifyOTP(String otp) async { - try { - setState(() { - _isLoading = true; - }); - PhoneAuthCredential credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: otp, - ); - - await FirebaseAuth.instance - .signInWithCredential(credential) - .then((user) async { - if (user != null) { - // Handle successful verification - ToastHelper.showSuccessToast(context, 'Successfully Login...!'); - bool otpVerifyStatus = true; - generateToken(otpVerifyStatus); + if (postStatus == 'success') { + setState(() { + _isLoading = false; + }); + postSuccessData(post, data); + } else if (status == 'success') { + setState(() { + _isLoading = false; + }); + enrollmentSuccessData(data); } else { setState(() { _isLoading = false; }); ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); + // Show a Snackbar if the OTP is invalid + print('Invalid OTP. Please try again'); } - }); + } else { + setState(() { + _isLoading = false; + }); + ToastHelper.showWarningToast(context, 'Something went wrong'); + throw Exception('Failed to verify OTP'); + } } catch (e) { setState(() { _isLoading = false; }); print('Error: $e'); - ToastHelper.showErrorToast( - context, 'Failed to verify OTP. Please try again.'); + ToastHelper.showWarningToast(context, 'Something went wrong'); + // Show a Snackbar if there's an error while verifying OTP + print('Failed to verify OTP. Please try again.'); + } + } + + void postSuccessData(post, data) async { + String status = data['status']; + String postStatus = post['status']; + + if (postStatus == 'success') { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('_postToken', post['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(post['data']); + print('decodedToken : $decodedToken'); + empClientBranchId = decodedToken['ref_id']; + prefs.setString('empClientBranchId', empClientBranchId); + empCodeString = decodedToken['emp_code'].toString(); + prefs.setString('empCode', empCodeString); + empPrimaryId = decodedToken['id']; + prefs.setString('empPrimaryId', empPrimaryId); + gpaEmpName = decodedToken['name'].toString(); + prefs.setString('gpaEmpName', gpaEmpName); + client_id = decodedToken['client_id']; + prefs.setString('client_id', client_id); + emp_status = decodedToken['emp_status']; + prefs.setString('emp_status', emp_status); + + } + + if (status == 'success') { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('enrollToken', data['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(data['data']); + print('decodedToken : $decodedToken'); + enrollmentEmpClientBranchId = decodedToken['ref_id']; + prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId); + enrollmentEmpCodeString = decodedToken['emp_code'].toString(); + prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString); + enrollmentEmpPrimaryId = decodedToken['id']; + prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId); + enrollmentGpaEmpName = decodedToken['name'].toString(); + prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName); + enrollmentClient_id = decodedToken['client_id']; + prefs.setString('enrollmentClient_id', enrollmentClient_id); + // enrollmentEmp_status = decodedToken['emp_status']; + // prefs.setString('enrollmentEmp_status', enrollmentEmp_status); + } + + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final _postToken = prefs.getString('_postToken'); + + if (_postToken != null && _postToken.isNotEmpty) { + ToastHelper.showSuccessToast(context, 'Successfully Login'); + // if (emp_status == 'enrolled' || emp_status == 'active') { + Navigator.pushReplacementNamed(context, 'hrDashboard'); + // } else { + // Navigator.pushReplacementNamed(context, 'empDetails'); + // } + } + + } + + void enrollmentSuccessData(data) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('enrollToken', data['data']); + + // Decode the JWT token received from the API response + Map? decodedToken = Jwt.parseJwt(data['data']); + print('decodedToken : $decodedToken'); + enrollmentEmpClientBranchId = decodedToken['ref_id']; + prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId); + enrollmentEmpCodeString = decodedToken['emp_code'].toString(); + prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString); + enrollmentEmpPrimaryId = decodedToken['id']; + prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId); + enrollmentGpaEmpName = decodedToken['name'].toString(); + prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName); + enrollmentClient_id = decodedToken['client_id']; + prefs.setString('enrollmentClient_id', enrollmentClient_id); + // enrollmentEmp_status = decodedToken['emp_status']; + // prefs.setString('enrollmentEmp_status', enrollmentEmp_status); + + print('Successfully Login'); + + // Redirect to another page + final enrollToken = prefs.getString('enrollToken'); + + if (enrollToken != null && enrollToken.isNotEmpty) { + ToastHelper.showSuccessToast(context, 'Successfully Login'); + // if (emp_status == 'enrolled' || emp_status == 'active') { + // Navigator.pushReplacementNamed(context, 'home'); + // } else { + Navigator.pushReplacementNamed(context, 'hrDashboard'); + // } + } + + } + + void verifyOTP(String otp) async { + try { + // setState(() { + // _isLoading = true; + // }); + // Later, in verify screen: + SharedPreferences prefs = await SharedPreferences.getInstance(); + dynamic verificationId = prefs.getString('verificationId'); + + final credential = PhoneAuthProvider.credential( + verificationId: verificationId, // Make sure this is up-to-date + smsCode: otp, + ); + + // final userCredential = await FirebaseAuth.instance.signInWithCredential(credential); + // await FirebaseAuth.instance.signInWithCredential(credential); + + // if (userCredential.user != null) { + bool otpVerifyStatus = true; + generateToken(otpVerifyStatus); + // } else { + // ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again.'); + // } + + // await FirebaseAuth.instance.signInWithCredential(credential).then((userCredential) async { + // if (userCredential.user != null) { + // bool otpVerifyStatus = true; + // generateToken(otpVerifyStatus); + // } else { + // setState(() { + // _isLoading = false; + // }); + // ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); + // } + // }); + } on FirebaseAuthException catch (e) { + if (e.code == 'code-expired') { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('OTP expired. Please request a new one.'), + duration: Duration(seconds: 2), + ), + ); + ToastHelper.showErrorToast(context, 'OTP expired. Please request a new one.'); + } else if (e.code == 'invalid-verification-code') { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Invalid OTP entered. Please try again.'), + duration: Duration(seconds: 2), + ), + ); + ToastHelper.showErrorToast(context, 'Invalid OTP entered. Please try again.'); + } else if (e.code == 'session-expired') { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Session expired. Try restarting the verification.'), + duration: Duration(seconds: 2), + ), + ); + ToastHelper.showErrorToast(context, 'Session expired. Try restarting the verification.'); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Error: ${e.message}'), + duration: Duration(seconds: 2), + ), + ); + ToastHelper.showErrorToast(context, 'Error: ${e.message}'); + } + } catch (e) { + // setState(() { + // _isLoading = false; + // }); + print('Error: $e'); + ToastHelper.showErrorToast(context, 'Failed to verify OTP. Please try again.'); } } @@ -266,53 +369,6 @@ class _MyVerifyState extends State { widget.onResendCode(widget.mobileNumber, widget.resendToken); } - Future getClientLogoAndDetails() async { - var url = Uri.parse(Environment.apiUrl + - 'getClientDetails?client_id=$client_id&client_branch_id=$empRefId'); - try { - var response = await http.get( - url, - headers: { - 'Authorization': - 'Bearer $_token', // Add token to the Authorization header - }, - ); - if (response.statusCode == 200) { - // print('response.statusCode == 200'); - Map data = json.decode(response.body); - // print(data); - - if (data.containsKey('data')) { - dynamic clientDetails = data['data']; - final SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString('clientLogo', clientDetails['client']['client_logo']); - prefs.setString('clientName', clientDetails['client']['client_name']); - setState(() { - // dynamic clientDetails = data['data']; - // print(clientDetails); - clientName = clientDetails['client']['client_name']; - print(clientName); - clientLogo = clientDetails['client']['client_logo']; - print(clientLogo); - }); - } else { - // Handle other status messages if needed - // ToastHelper.showErrorToast( - // context, 'API request failed with status: ${data['status']}'); - print('API request failed with status: ${data['status']}'); - } - } else { - // Handle other status codes - // ToastHelper.showErrorToast( - // context, 'Request failed with status: ${response.statusCode}'); - print('Request failed with status: ${response.statusCode}'); - } - } catch (e) { - // Handle exceptions - print('Exception occurred: $e'); - } - } - @override Widget build(BuildContext context) { // Retrieve the passed mobile number value diff --git a/lib/main.dart b/lib/main.dart old mode 100644 new mode 100755 index 8003f8f..4a25a4e --- a/lib/main.dart +++ b/lib/main.dart @@ -16,15 +16,17 @@ import 'package:nhancepolicy/hrPolicyDetails.dart'; import 'package:nhancepolicy/oldPolicy.dart'; import 'package:firebase_core/firebase_core.dart'; +import 'email_verify.dart'; + Future main() async { // await dotenv.load(fileName: Environment.fileName); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: const FirebaseOptions( - apiKey: 'AIzaSyAZdKJco4fe0e1HP1A249BVZzA3WMYb_3g', - appId: '1:508866094093:android:9969e766daa5b770366144', - messagingSenderId: '508866094093', - projectId: 'nhance-app-4fedb')); + apiKey: 'AIzaSyCSvDM5fG2blDBE69Cae3S-iYRwwNBy7xo', + appId: '1:1084115316849:web:ce28f12a426f285d6c6bd0', + messagingSenderId: '1084115316849', + projectId: 'nhance-ee8d1')); await dotenv.load(fileName: Environment.fileName); runApp(MaterialApp( @@ -32,6 +34,9 @@ Future main() async { debugShowCheckedModeBanner: false, routes: { 'phone': (context) => MyPhone(), + 'mailVerify': (context) => MyEmailVerify( + email: '', + ), 'verify': (context) => MyVerify( verificationId: '', mobileNumber: '', diff --git a/lib/models/environment.dart b/lib/models/environment.dart old mode 100644 new mode 100755 diff --git a/lib/models/platform_helper_mobile.dart b/lib/models/platform_helper_mobile.dart new file mode 100755 index 0000000..1a917e8 --- /dev/null +++ b/lib/models/platform_helper_mobile.dart @@ -0,0 +1,5 @@ +import 'dart:io'; + +bool isMobilePlatform() { + return Platform.isAndroid || Platform.isIOS; +} diff --git a/lib/models/platform_helper_other.dart b/lib/models/platform_helper_other.dart new file mode 100755 index 0000000..4c467d0 --- /dev/null +++ b/lib/models/platform_helper_other.dart @@ -0,0 +1,3 @@ +bool isMobilePlatform() { + return false; +} diff --git a/lib/oldPolicy.dart b/lib/oldPolicy.dart old mode 100644 new mode 100755 diff --git a/lib/phone.dart b/lib/phone.dart old mode 100644 new mode 100755 diff --git a/lib/responsive.dart b/lib/responsive.dart old mode 100644 new mode 100755 diff --git a/lib/service/api_service.dart b/lib/service/api_service.dart old mode 100644 new mode 100755 index 8de0f82..9ea4f38 --- a/lib/service/api_service.dart +++ b/lib/service/api_service.dart @@ -23,6 +23,10 @@ class ApiService { _hrtoken = hrprefs.getString('hrtoken') ?? ''; } + Future getTokenLoadAPI(token) async { + _token = token; + } + Future> getClientLogoAndDetailsToApi( String clientId, String empCode, String branchID) async { print(_token); @@ -39,14 +43,18 @@ class ApiService { } Future> getSelfEmployeeProfileToApi( - token, String clientId, String empCode, String branchID) async { + token, + String clientId, + String empCode, + String branchID, + String client_policy_id) async { print(_token); _token = await token; if (_token == null) { await _initializeToken(); } final url = Uri.parse( - '${Environment.apiUrl}getEmployeeProfile?emp_code=$empCode&client_id=$clientId&client_branch_id=$branchID'); + '${Environment.apiUrl}getEmployeeProfile?emp_code=$empCode&client_id=$clientId&client_branch_id=$branchID&client_policy_id=$client_policy_id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', }; @@ -67,14 +75,19 @@ class ApiService { return response; } - Future> getGpaEmpPolicyDetailsToApi(String empPrimaryId, - String empCode, String clientId, String policy, String branchID) async { + Future> getGpaEmpPolicyDetailsToApi( + String empPrimaryId, + String empCode, + String clientId, + String policy, + String branchID, + login_by_hr) async { print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( - '${Environment.apiUrl}getEmployeePolicy?id=$empPrimaryId&emp_code=$empCode&client_id=$clientId&policy=$policy&client_branch_id=$branchID'); + '${Environment.apiUrl}getEmployeePolicy?id=$empPrimaryId&emp_code=$empCode&client_id=$clientId&policy=$policy&client_branch_id=$branchID&login_by_hr=$login_by_hr'); final headers = { 'Authorization': 'Bearer $_token' ?? '', }; @@ -82,14 +95,19 @@ class ApiService { return response; } - Future> getGmcEmpPolicyDetailsToApi(String empPrimaryId, - String empCode, String clientId, String policy, String branchID) async { + Future> getGmcEmpPolicyDetailsToApi( + String empPrimaryId, + String empCode, + String clientId, + String policy, + String branchID, + login_by_hr) async { print(_token); if (_token == null) { await _initializeToken(); } final url = Uri.parse( - '${Environment.apiUrl}getEmployeePolicy?id=$empPrimaryId&emp_code=$empCode&client_id=$clientId&policy=$policy&client_branch_id=$branchID'); + '${Environment.apiUrl}getEmployeePolicy?id=$empPrimaryId&emp_code=$empCode&client_id=$clientId&policy=$policy&client_branch_id=$branchID&login_by_hr=$login_by_hr'); final headers = { 'Authorization': 'Bearer $_token' ?? '', }; @@ -394,15 +412,15 @@ class ApiService { //HR API STARTS Future> getCashDepositDetailsToApi( - String clintID, String empRefId) async { - print(_hrtoken); - if (_hrtoken == null) { + String clintID, String empRefId, String token) async { + print(token); + if (token == null) { await _initializeToken(); } final url = Uri.parse( - '${Environment.apiUrl}getCashDepositData?client_id=$clintID&client_branch_id=$empRefId'); + '${Environment.apiUrl}getPolicyLevelEmployeeSummaryData?client_id=$clintID&client_branch_id=$empRefId'); final headers = { - 'Authorization': 'Bearer $_hrtoken' ?? '', + 'Authorization': 'Bearer $token' ?? '', }; final response = await _makeGetRequest(url, headers); return response; diff --git a/lib/verify.dart b/lib/verify.dart old mode 100644 new mode 100755 index efc3ecf..e0b3f54 --- a/lib/verify.dart +++ b/lib/verify.dart @@ -221,7 +221,7 @@ class _MyVerifyState extends State { .then((user) async { if (user != null) { // Handle successful verification - ToastHelper.showSuccessToast(context, 'Successfully Login...!'); + // ToastHelper.showSuccessToast(context, 'Successfully Login...!'); bool otpVerifyStatus = true; generateToken(otpVerifyStatus); } else { diff --git a/linux/.gitignore b/linux/.gitignore old mode 100644 new mode 100755 diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc old mode 100644 new mode 100755 diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h old mode 100644 new mode 100755 diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake old mode 100644 new mode 100755 diff --git a/linux/main.cc b/linux/main.cc old mode 100644 new mode 100755 diff --git a/linux/my_application.cc b/linux/my_application.cc old mode 100644 new mode 100755 diff --git a/linux/my_application.h b/linux/my_application.h old mode 100644 new mode 100755 diff --git a/macos/.gitignore b/macos/.gitignore old mode 100644 new mode 100755 diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig old mode 100644 new mode 100755 index c2efd0b..4b81f9b --- a/macos/Flutter/Flutter-Debug.xcconfig +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig old mode 100644 new mode 100755 index c2efd0b..5caa9d1 --- a/macos/Flutter/Flutter-Release.xcconfig +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift old mode 100644 new mode 100755 diff --git a/macos/Podfile b/macos/Podfile new file mode 100644 index 0000000..29c8eb3 --- /dev/null +++ b/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png old mode 100644 new mode 100755 diff --git a/macos/Runner/Base.lproj/MainMenu.xib b/macos/Runner/Base.lproj/MainMenu.xib old mode 100644 new mode 100755 diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig old mode 100644 new mode 100755 diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig old mode 100644 new mode 100755 diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig old mode 100644 new mode 100755 diff --git a/macos/Runner/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig old mode 100644 new mode 100755 diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements old mode 100644 new mode 100755 diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist old mode 100644 new mode 100755 diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift old mode 100644 new mode 100755 diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements old mode 100644 new mode 100755 diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift old mode 100644 new mode 100755 diff --git a/pubspec.yaml b/pubspec.yaml old mode 100644 new mode 100755 diff --git a/test/widget_test.dart b/test/widget_test.dart old mode 100644 new mode 100755 diff --git a/web/assets/Sample.xlsx b/web/assets/Sample.xlsx old mode 100644 new mode 100755 diff --git a/web/assets/nhance-loader.gif b/web/assets/nhance-loader.gif old mode 100644 new mode 100755 diff --git a/web/favicon.png b/web/favicon.png old mode 100644 new mode 100755 diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png old mode 100644 new mode 100755 diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png old mode 100644 new mode 100755 diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png old mode 100644 new mode 100755 diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png old mode 100644 new mode 100755 diff --git a/web/index.html b/web/index.html old mode 100644 new mode 100755 index fdeef8e..c1eb5a8 --- a/web/index.html +++ b/web/index.html @@ -81,15 +81,19 @@ // Your web app's Firebase configuration const firebaseConfig = { - apiKey: "AIzaSyDg6lonV9STSIwJ4x261tcTGALEhX98LqY", - authDomain: "nhance-app-4fedb.firebaseapp.com", - projectId: "nhance-app-4fedb", - storageBucket: "nhance-app-4fedb.appspot.com", - messagingSenderId: "508866094093", - appId: "1:508866094093:web:82f8ad47ccb63688366144" + apiKey: "AIzaSyCSvDM5fG2blDBE69Cae3S-iYRwwNBy7xo", + authDomain: "nhance-ee8d1.firebaseapp.com", + projectId: "nhance-ee8d1", + storageBucket: "nhance-ee8d1.firebasestorage.app", + messagingSenderId: "1084115316849", + appId: "1:1084115316849:web:ce28f12a426f285d6c6bd0" }; +// Initialize Firebase +const app = initializeApp(firebaseConfig); + + // Initialize Firebase const app = initializeApp(firebaseConfig); diff --git a/web/manifest.json b/web/manifest.json old mode 100644 new mode 100755 diff --git a/windows/.gitignore b/windows/.gitignore old mode 100644 new mode 100755 diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc old mode 100644 new mode 100755 diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h old mode 100644 new mode 100755 diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake old mode 100644 new mode 100755 diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc old mode 100644 new mode 100755 diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp old mode 100644 new mode 100755 diff --git a/windows/runner/flutter_window.h b/windows/runner/flutter_window.h old mode 100644 new mode 100755 diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp old mode 100644 new mode 100755 diff --git a/windows/runner/resource.h b/windows/runner/resource.h old mode 100644 new mode 100755 diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico old mode 100644 new mode 100755 diff --git a/windows/runner/runner.exe.manifest b/windows/runner/runner.exe.manifest old mode 100644 new mode 100755 diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp old mode 100644 new mode 100755 diff --git a/windows/runner/utils.h b/windows/runner/utils.h old mode 100644 new mode 100755 diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp old mode 100644 new mode 100755 diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h old mode 100644 new mode 100755