import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'package:nhance_app_pwa/customAppBar/customAppBar.dart'; import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart'; import 'package:nhance_app_pwa/pages/service/SessionManager.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../config/environment.dart'; import '../../customAppBar/customFooter.dart'; import '../../customAppBar/responsive.dart'; import '../../customAppBar/tabs.dart'; import '../../customAppBar/toastHelper.dart'; import 'package:http/http.dart' as http; import '../../models/platform_helper_mobile.dart' if (dart.library.html) '../../models/platform_helper_other.dart'; import '../service/TokenService.dart'; import '../service/appVersionService.dart'; import '../service/common_update_mobile_dialog.dart'; import '../service/data_manager.dart'; import '../service/popup_helper.dart'; import '../session/authenticationService.dart'; class profile extends StatefulWidget { const profile({Key? key}) : super(key: key); @override State createState() => _profileState(); } class _profileState extends State { bool isLoading = false; late ApiService apiService; final AuthService _authService = AuthService(); int _currentIndex = 0; bool isActive = true; dynamic _token; dynamic empCodeString; dynamic empPrimaryId; dynamic client_id; dynamic policyList; dynamic policyDataIsEmpty = 1; dynamic policyHeading; dynamic policyName; dynamic EmployeePolicy; List> employeeDetails = []; dynamic argumentsData; dynamic selfRelationship; dynamic selfName; dynamic selfMobile; dynamic selfDesignation; dynamic selfDob; dynamic selfDoj; dynamic selfGender; dynamic selfEmailCorporate; dynamic selfEmailPersonal; dynamic selfEmpCode; dynamic selfFamilyFloaterKey; dynamic selfEmpStatus; dynamic client_branch_id; dynamic selfDetails; final dataManager = DataManager(); final session = SessionManager(); String installedVersion = ""; String? storeVersion = ""; bool showSetMpin = false; void _onTabChanged(int index) { setState(() { _currentIndex = index; }); } @override void initState() { super.initState(); apiService = ApiService(context); // Initialize ApiService here _loadToken(); // _checkMpinStatus(); if(!kIsWeb){ _checkMpinStatus(); loadVersionInfo(); } } @override void dispose() { super.dispose(); } Future _checkMpinStatus() async { print('check Mpin Status'); // if (kIsWeb) return; // ❌ skip web final prefs = await SharedPreferences.getInstance(); final String? isMpinSkipped = prefs.getString('is_mpin_skipped'); print('check Mpin Status'); print(isMpinSkipped); setState(() { showSetMpin = isMpinSkipped == "1"; print('check Mpin Status'); print(showSetMpin); }); } Future loadVersionInfo() async { print('App version:}'); installedVersion = await AppVersionService.getInstalledVersion(); storeVersion = await AppVersionService.getLatestStoreVersion( androidPackage: "nh.ind.nhance.benefits", // Android iosAppId: "6744743638", // iOS App Store ID ); setState(() {}); } Future _getAppVersion() async { try { PackageInfo packageInfo = await PackageInfo.fromPlatform(); print('App version: ${packageInfo.version}'); return packageInfo.version; } catch (e) { print('Error getting app version: $e'); return 'Unknown'; // Optional fallback } } Future _loadToken() async { print('_loadToken'); final String? token = await TokenService.getPostToken(); if (token != null && token.isNotEmpty) { // Decode the JWT token received from the API response Map? decodedToken = Jwt.parseJwt(token); print(decodedToken); client_branch_id = session.empClientBranchId; empCodeString = session.empCodeString; print(empCodeString); // Check if emp_code is correct empPrimaryId = session.empPrimaryId; client_id = session.client_id; print(client_id); await dataManager.loadSelfEmployeeProfile( clientId: session.client_id!, empCode: session.empCodeString!, clientBranchId: session.empClientBranchId!, ) .then((_) { selfDetails = dataManager.selfProfile; print('selfDetails $selfDetails'); }); getSelfEmployeeProfile(); } } String convertDate(String dateString) { DateTime date = DateTime.parse(dateString); DateFormat formatter = DateFormat('dd MMM yyyy'); return formatter.format(date); } Future getSelfEmployeeProfile() async { // final selfDetails = dataManager.selfProfile; print('profile'); print(profile); // if (client_id == null || empCodeString == null) { // return; // } // setState(() { // isLoading = true; // }); // print('check 1'); // final response = await apiService.getSelfEmployeeProfileDetails( // client_id!, empCodeString!, client_branch_id!); // print('check 1'); // if (response['status'] == 'success') { // if (response.containsKey('data')) { setState(() { // dynamic selfDetails = response['data']; // print(selfDetails); selfRelationship = selfDetails?['relationship']; selfName = selfDetails?['name']; selfMobile = selfDetails?['mobile']; selfDesignation = selfDetails?['designation']; selfDob = convertDate(selfDetails?['dob']); selfDoj = convertDate(selfDetails?['doj']); selfGender = selfDetails?['gender']; selfEmailCorporate = selfDetails?['email_corporate']; selfEmailPersonal = selfDetails?['email_personal']; selfEmpCode = selfDetails?['emp_code']; selfFamilyFloaterKey = selfDetails?['family_floater_key']; // print(clientDetails); selfEmpStatus = selfDetails?['emp_status']; // isLoading = false; }); // final SharedPreferences prefs = await SharedPreferences.getInstance(); // prefs.setString('selfEmpStatus', selfEmpStatus); // } else { // // Handle other status messages if needed // // ToastHelper.showErrorToast( // // context, 'API request failed with status: ${data['status']}'); // print('API request failed with status: ${response['status']}'); // } // } else { // print('API request failed with status: ${response['status']}'); // } } Future checkLoginPin() async { print('checkLoginPin'); try { final SharedPreferences prefs = await SharedPreferences.getInstance(); final empMobileNo = prefs.getString('empMobileNo'); final empEmailid = prefs.getString('empEmailid'); print('empMobileNo $empMobileNo'); print('empEmailid $empEmailid'); var params = {}; if (empMobileNo != null && empMobileNo.isNotEmpty) { params = {'mobile_number': empMobileNo}; } else if (empEmailid != null && empEmailid.isNotEmpty) { params = {'email_id': empEmailid}; } print('params $params'); final response = await http.post( Uri.parse(Environment.apiUrlEnrollment + 'checkMpin'), body: json.encode(params), headers: { HttpHeaders.contentTypeHeader: 'application/json', 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { if (data['data'] != null) { prefs.setString('mpinText', data['data']); } if (data['Mpin'] != null) { prefs.setString('mpin', data['Mpin']); } if (data['is_biometric_enabled'] != null) { prefs.setString( 'is_biometric_enabled', data['is_biometric_enabled']); } if (data['is_mpin_skipped'] != null) { prefs.setString('is_mpin_skipped', data['is_mpin_skipped']); return data['is_mpin_skipped'].toString(); } } } else { print('❌ API failed: ${response.statusCode}'); return null; } } catch (e) { print('❌ Error: $e'); return null; } return null; } Future logout(BuildContext context) async { // if (isMobilePlatform()) { final SharedPreferences prefs = await SharedPreferences.getInstance(); // Get the value of the mobile_number key String? mobileNumber = prefs.getString('empMobileNo'); String? mailID = prefs.getString('empEmailid'); final isMpinSkipped = await checkLoginPin(); print('isMpinSkipped $isMpinSkipped'); // bool? biometricStatus = prefs.getBool('biometricStatus') ?? false; // int? skipStatus = prefs.getInt('skipStatus') ?? 1; // Clear all keys await SessionManager().clear(); // await prefs.clear(); print('Local Storage Clear'); // html.window.localStorage.clear(); // Re-set the mobile_number key if (isMobilePlatform()) { if (mobileNumber != null) { await prefs.setString('empMobileNo', mobileNumber); print('empMobileNo $mobileNumber'); // await prefs.setBool('biometricStatus', biometricStatus!); // await prefs.setInt('skipStatus', skipStatus!); } if (mailID != null) { await prefs.setString('empEmailid', mailID); print('empEmailid $mailID'); // await prefs.setBool('biometricStatus', biometricStatus!); // await prefs.setInt('skipStatus', skipStatus!); } if (isMpinSkipped != null) { await prefs.setString('is_mpin_skipped', isMpinSkipped!); print('isMpinSkipped $isMpinSkipped'); } if (isMpinSkipped != null && isMpinSkipped == '0') { print('pinPage'); // return; context.go('/pinPage'); } else { print('login'); context.go('/login'); } } else { await prefs.clear(); ToastHelper.showSuccessToast(context, 'logout'); // Navigate to login page context.go('/login'); } // } else { // final prefs = await SharedPreferences.getInstance(); // await prefs.clear(); // Navigator.pushNamed(context, 'login'); // } } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) return; context.pop(); }, child: Scaffold( backgroundColor: Colors.white, appBar: CustomAppBar(), body: Stack(children: [ SingleChildScrollView( child: Container( padding: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.2, // 30% of screen width as horizontal padding vertical: MediaQuery.of(context).size.height * 0.03, // 5% of screen height as vertical padding ) : EdgeInsets.all(10), color: Colors.white, child: Column(children: [ if (selfName != null) Container( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: InkWell( onTap: () { context.pop(); }, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon( Icons .chevron_left, // Replace with your desired icon color: Color(0xFF000000), size: 30, ), ], ), ), ), Expanded( flex: 11, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // Adjust space between icon and text Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( selfName ?? '', textAlign: TextAlign.center, style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), ], ), ], ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: Container( alignment: Alignment.topLeft, padding: EdgeInsets.only(top: 10, left: 10), child: Text(''))), Expanded( flex: Responsive.isDesktop(context) ? 12 : 11, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // Adjust space between icon and text Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ RichText( text: TextSpan( children: [ TextSpan( text: 'Emp: Id - ', style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight .w600, // Bold style for "Emp: Id -" color: Color(0xFF000000), ), ), TextSpan( text: selfEmpCode ?? '', style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight .w400, // Normal style for the ID number color: Color(0xFF747474), ), ), ], ), ), ], ), ], ), ) ], ), // Add more rows as needed ], ), ), SizedBox(height: 15), if (selfName != null) Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 10), // Set the border radius here ), child: Column(children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), ), padding: Responsive.isDesktop(context) ? EdgeInsets.all(30) : EdgeInsets.all(15), child: Column(children: [ Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Color(0xFFBDBDBD), width: 1.0, // Adjust the width as needed ), ), ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only(top: 10, bottom: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 6, child: Container( alignment: Alignment.centerLeft, padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10) : EdgeInsets.only( top: 7, bottom: 7, left: 7, right: 7), child: Text( 'Gender', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, color: Color(0xFF777777), fontWeight: FontWeight.w500, ), ), ), ), Expanded( flex: 6, child: Container( alignment: Alignment.centerRight, child: Text( selfGender == 'M' ? 'Male' : 'Female', textAlign: TextAlign.end, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 16, color: Color(0xFF2D5A82), fontWeight: FontWeight.w400, ), ), ), ), ], )), Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Color(0xFFBDBDBD), width: 1.0, // Adjust the width as needed ), ), ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only(top: 10, bottom: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 6, child: Container( alignment: Alignment.centerLeft, padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10) : EdgeInsets.only( top: 7, bottom: 7, left: 7, right: 7), child: Text( 'Date of birth', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, color: Color(0xFF777777), fontWeight: FontWeight.w500, ), ), ), ), Expanded( flex: 6, child: Container( alignment: Alignment.centerRight, child: Text( selfDob ?? '', textAlign: TextAlign.end, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 16, color: Color(0xFF2D5A82), fontWeight: FontWeight.w400, ), ), ), ), ], )), Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Color(0xFFBDBDBD), width: 1.0, // Adjust the width as needed ), ), ), padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only(top: 10, bottom: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 4, child: Container( alignment: Alignment.centerLeft, padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10) : EdgeInsets.only( top: 7, bottom: 7, left: 7, right: 7), child: Text( 'Phone No', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, color: Color(0xFF777777), fontWeight: FontWeight.w500, ), ), ), ), Expanded( flex: 8, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( onTap: () async { // {"email_id":"example@mail.com","client_id":123,"new_mobile_number":"9876543210"} final updatedNumber = await showUpdateMobileDialog(context, apiService, client_id, selfEmailCorporate, selfMobile); if (updatedNumber != null && updatedNumber.isNotEmpty) { setState(() => selfMobile = updatedNumber); dataManager.loadSelfEmployeeProfile( clientId: session.client_id!, empCode: session.empCodeString!, clientBranchId: session.empClientBranchId!, ); } }, child: const Icon( Icons.edit, size: 18, color: Colors.blue, ), ), ), const SizedBox(width: 6), Text( selfMobile ?? '', style: GoogleFonts.poppins( fontSize: 16, color: Color(0xFF2D5A82), ), ) ], ), ) ], )), Container( padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15) : EdgeInsets.only(top: 10, bottom: 10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 6, child: Container( alignment: Alignment.centerLeft, padding: Responsive.isDesktop(context) ? EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10) : EdgeInsets.only( top: 7, bottom: 7, left: 7, right: 7), child: Text( 'Email id', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, color: Color(0xFF777777), fontWeight: FontWeight.w500, ), ), ), ), Expanded( flex: 6, child: Container( alignment: Alignment.centerRight, child: Text( selfEmailCorporate ?? '', textAlign: TextAlign.end, style: GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 16, color: Color(0xFF2D5A82), fontWeight: FontWeight.w400, ), ), ), ), ], )), ]), ) ])), SizedBox(height: 12), if (Responsive.isMobile(context) || Responsive.isTablet(context)) ...[ Container( child: Row( children: [ Expanded( flex: 12, child: Container( width: 150, // height: Responsive.isDesktop(context) ? 150 : 100, alignment: Alignment.center, child: ElevatedButton( onPressed: () { if (showSetMpin) { print('pinSettingPage'); context.go('/pinSettingPage'); // ✅ Set MPIN page } else { print('changePin'); context.go('/changePin'); // ✅ Change PIN page } }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // Adjust space between icon and text Text( showSetMpin ? 'Set MPIN' : 'Change PIN', style: GoogleFonts.poppins( color: Color(0xFFE26728)), ), ], ), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), side: BorderSide(color: Color(0xFFE26728)), ), ), ), )), ], ), ), SizedBox(height: 10), ], Container( // color: Colors.amberAccent, width: MediaQuery.of(context).size.width, child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ // ✅ Change Password Button if(Responsive.isDesktop(context))...[ _buildChangePasswordButton(context), const SizedBox(width: 10), ], // ✅ Logout Button Responsive.isDesktop(context) ? _buildLogoutButton(context) : Expanded( flex: 12, child: _buildLogoutButton(context)), ], ), ), SizedBox(height: Responsive.isDesktop(context) ? 40 : 10), // if (Responsive.isDesktop(context)) // Padding( // padding: const EdgeInsets.only(bottom: 16.0), // child: FutureBuilder( // future: _getAppVersion(), // Function to get the app version // builder: (context, snapshot) { // if (snapshot.connectionState == // ConnectionState.waiting) { // return Text( // 'Loading version...', // style: GoogleFonts.poppins( // fontSize: 12, color: Colors.grey), // textAlign: TextAlign.center, // ); // } else if (snapshot.hasError) { // return Text( // 'Error fetching version', // style: GoogleFonts.poppins( // fontSize: 12, color: Colors.red), // textAlign: TextAlign.center, // ); // } else { // return Text( // 'Version ${snapshot.data}', // style: GoogleFonts.poppins( // fontSize: 12, color: Colors.grey), // textAlign: TextAlign.center, // ); // } // }, // ), // ), if (Responsive.isMobile(context) || Responsive.isTablet(context)) Padding( padding: const EdgeInsets.only(bottom: 16.0), child: Text( 'Version ${installedVersion}', style: GoogleFonts.poppins( fontSize: 12, color: Colors.grey), textAlign: TextAlign.center, )) ]), )), if (isLoading) Container( color: Color(0x98FFFCE5), // Semi-transparent background child: Center( child: // Your GIF loader widget Image.asset( height: 60, width: 60, 'assets/nhance-loader.gif'), // Adjust path to your GIF loader ), ), if (Responsive.isDesktop(context)) Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, // Make the footer full width child: CustomFooter(), ), ), ]), // floatingActionButton: Responsive.isDesktop(context) // ? null // : FloatingActionButton( // onPressed: () { // Navigator.pushNamed(context, 'chatbot'); // }, // child: Icon(Icons.chat), // ), floatingActionButtonLocation: Responsive.isDesktop(context) ? null : FloatingActionButtonLocation.miniEndFloat, bottomNavigationBar: Responsive.isDesktop(context) ? null : CustomBottomNavigationBar( onTabChanged: (index) { // Add your navigation logic here // repositionBotman(); if (index == 0) { context.push('/home'); } else if (index == 1) { context.push('/claims'); } else if (index == 2) { context.push('/faqs'); } else if (index == 3) { context.push('/profile'); } else if (index == 4) { context.push('/help'); } // else if (index == 4) { // // context.push('/wellness'); // // Wellness tab clicked → show popup // if(!isRetailLoggedIn) // PopupHelper.showRedirectPopup( // context: context, // apiService: apiService, // empPrimaryId: session.empPrimaryId, // ); // } }, icons: [ Icons.home_outlined, Icons.sticky_note_2_outlined, Icons.question_answer_outlined, Icons.person_outline_outlined, Icons.headset_mic_outlined, ], labels: ["Home", "Claims", "FAQs", "Profile","Help"], initialIndex: 3, // Initial index of the bottom navigation bar ), )); } Widget _buildChangePasswordButton(BuildContext context) { return Container( alignment: Alignment.center, child: ElevatedButton( onPressed: () { // 👉 Navigate to Change Password Page using GoRouter final email = selfEmailCorporate ?? ''; // get from your session or state final clientId = client_id ?? ''; // set actual value here context.goNamed( 'changePassword', queryParameters: { 'email': email, 'client_id': clientId, }, ); }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFE26728), // Orange button shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.lock_open, color: Colors.white), const SizedBox(width: 8), Text( 'Change Password', style: GoogleFonts.poppins( color: Colors.white, fontWeight: FontWeight.w500, ), ), ], ), ), ); } Widget _buildLogoutButton(BuildContext context) { return Container( alignment: Alignment.center, child: ElevatedButton( onPressed: () => logout(context), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), side: const BorderSide(color: Color(0xFFE26728)), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.logout, color: Color(0xFFE26728)), const SizedBox(width: 8), Text( 'Logout', style: GoogleFonts.poppins(color: const Color(0xFFE26728)), ), ], ), ), ); } }