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 '../../features/chatbot/application/chatbot_reset_helper.dart'; import '../session/authenticationService.dart'; import 'package:nhance_app_pwa/logger.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 { logDebug('check Mpin Status'); // if (kIsWeb) return; // ❌ skip web final prefs = await SharedPreferences.getInstance(); final String? isMpinSkipped = prefs.getString('is_mpin_skipped'); logDebug('check Mpin Status'); logDebug(isMpinSkipped); setState(() { showSetMpin = isMpinSkipped == "1"; logDebug('check Mpin Status'); logDebug(showSetMpin); }); } Future loadVersionInfo() async { logDebug('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(); logDebug('App version: ${packageInfo.version}'); return packageInfo.version; } catch (e) { logDebug('Error getting app version: $e'); return 'Unknown'; // Optional fallback } } Future _loadToken() async { logDebug('_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); logDebug(decodedToken); client_branch_id = session.empClientBranchId; empCodeString = session.empCodeString; logDebug(empCodeString); // Check if emp_code is correct empPrimaryId = session.empPrimaryId; client_id = session.client_id; logDebug(client_id); await dataManager.loadSelfEmployeeProfile( clientId: session.client_id!, empCode: session.empCodeString!, clientBranchId: session.empClientBranchId!, ) .then((_) { selfDetails = dataManager.selfProfile; logDebug('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; logDebug('profile'); logDebug(profile); // if (client_id == null || empCodeString == null) { // return; // } // setState(() { // isLoading = true; // }); // logDebug('check 1'); // final response = await apiService.getSelfEmployeeProfileDetails( // client_id!, empCodeString!, client_branch_id!); // logDebug('check 1'); // if (response['status'] == 'success') { // if (response.containsKey('data')) { setState(() { // dynamic selfDetails = response['data']; // logDebug(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']; // logDebug(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']}'); // logDebug('API request failed with status: ${response['status']}'); // } // } else { // logDebug('API request failed with status: ${response['status']}'); // } } Future checkLoginPin() async { logDebug('checkLoginPin'); try { final SharedPreferences prefs = await SharedPreferences.getInstance(); final empMobileNo = prefs.getString('empMobileNo'); final empEmailid = prefs.getString('empEmailid'); logDebug('empMobileNo $empMobileNo'); logDebug('empEmailid $empEmailid'); var params = {}; if (empMobileNo != null && empMobileNo.isNotEmpty) { params = {'mobile_number': empMobileNo}; } else if (empEmailid != null && empEmailid.isNotEmpty) { params = {'email_id': empEmailid}; } logDebug('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 { logDebug('❌ API failed: ${response.statusCode}'); return null; } } catch (e) { logDebug('❌ Error: $e'); return null; } return null; } Future logout(BuildContext context) async { ChatbotResetHelper.resetChatbot(context); // 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(); logDebug('isMpinSkipped $isMpinSkipped'); // bool? biometricStatus = prefs.getBool('biometricStatus') ?? false; // int? skipStatus = prefs.getInt('skipStatus') ?? 1; // Clear all keys await SessionManager().clear(); // await prefs.clear(); logDebug('Local Storage Clear'); // html.window.localStorage.clear(); // Re-set the mobile_number key if (isMobilePlatform()) { if (mobileNumber != null) { await prefs.setString('empMobileNo', mobileNumber); logDebug('empMobileNo $mobileNumber'); // await prefs.setBool('biometricStatus', biometricStatus!); // await prefs.setInt('skipStatus', skipStatus!); } if (mailID != null) { await prefs.setString('empEmailid', mailID); logDebug('empEmailid $mailID'); // await prefs.setBool('biometricStatus', biometricStatus!); // await prefs.setInt('skipStatus', skipStatus!); } if (isMpinSkipped != null) { await prefs.setString('is_mpin_skipped', isMpinSkipped!); logDebug('isMpinSkipped $isMpinSkipped'); } if (isMpinSkipped != null && isMpinSkipped == '0') { logDebug('pinPage'); // return; context.go('/pinPage'); } else { logDebug('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 ) : const EdgeInsets.fromLTRB(16, 8, 16, 24), color: Colors.white, child: Column(children: [ if (selfName != null) ...[ if (Responsive.isDesktop(context)) _buildDesktopProfileHeader() else _buildMobileProfileHeader(), ], SizedBox(height: Responsive.isDesktop(context) ? 15 : 20), if (selfName != null) ...[ if (Responsive.isDesktop(context)) _buildDesktopProfileCard() else _buildMobileProfileCard(), ], SizedBox(height: 12), if (Responsive.isDesktop(context)) _buildDesktopProfileActions() else _buildMobileProfileActions(), SizedBox(height: Responsive.isDesktop(context) ? 40 : 16), if (!Responsive.isDesktop(context)) Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.only(bottom: 16.0), child: Text( 'Version ${installedVersion}', style: GoogleFonts.poppins( fontSize: 12, color: Colors.grey, ), textAlign: TextAlign.start, ), ), ), ]), )), 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 ), )); } TextStyle _profileLabelStyle(BuildContext context) { return GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 13, color: const Color(0xFF777777), fontWeight: FontWeight.w500, ); } TextStyle _profileValueStyle(BuildContext context) { return GoogleFonts.poppins( fontSize: Responsive.isDesktop(context) ? 16 : 14, color: const Color(0xFF2D5A82), fontWeight: FontWeight.w400, ); } Widget _buildDesktopProfileHeader() { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 1, child: InkWell( onTap: () => context.pop(), child: const Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon( Icons.chevron_left, color: Color(0xFF000000), size: 30, ), ], ), ), ), Expanded( flex: 11, child: Row( mainAxisAlignment: MainAxisAlignment.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: const EdgeInsets.only(top: 10, left: 10), child: const Text(''), ), ), Expanded( flex: 12, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ RichText( text: TextSpan( children: [ TextSpan( text: 'Emp: Id - ', style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), TextSpan( text: selfEmpCode ?? '', style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w400, color: Color(0xFF747474), ), ), ], ), ), ], ), ), ], ), ], ); } Widget _buildMobileProfileHeader() { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: () => context.pop(), borderRadius: BorderRadius.circular(8), child: const Padding( padding: EdgeInsets.only(top: 2, right: 8), child: Icon( Icons.chevron_left, color: Color(0xFF000000), size: 28, ), ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( selfName ?? '', textAlign: TextAlign.start, style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), const SizedBox(height: 6), RichText( textAlign: TextAlign.start, text: TextSpan( children: [ TextSpan( text: 'Emp: Id - ', style: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF000000), ), ), TextSpan( text: selfEmpCode ?? '', style: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF747474), ), ), ], ), ), ], ), ), ], ); } Widget _buildDesktopProfileFieldRow({ required BuildContext context, required String label, required Widget value, int labelFlex = 6, int valueFlex = 6, bool showBottomBorder = true, }) { return Container( decoration: showBottomBorder ? const BoxDecoration( border: Border( bottom: BorderSide( color: Color(0xFFBDBDBD), width: 1.0, ), ), ) : null, padding: const EdgeInsets.only( top: 15, bottom: 15, left: 15, right: 15, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: labelFlex, child: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.only( top: 10, bottom: 10, left: 10, right: 10, ), child: Text( label, textAlign: TextAlign.start, style: _profileLabelStyle(context), ), ), ), Expanded( flex: valueFlex, child: Container( alignment: Alignment.centerRight, child: value, ), ), ], ), ); } Widget _buildMobileProfileField({ required BuildContext context, required String label, required Widget value, bool showDivider = true, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 14), child: SizedBox( width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, textAlign: TextAlign.start, style: _profileLabelStyle(context), ), const SizedBox(height: 8), SizedBox( width: double.infinity, child: value, ), ], ), ), ), if (showDivider) const Divider( height: 1, thickness: 1, color: Color(0xFFBDBDBD), ), ], ); } Widget _buildDesktopProfileCard() { return Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Column( children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.all(30), child: Column( children: [ _buildDesktopProfileFieldRow( context: context, label: 'Gender', value: Text( selfGender == 'M' ? 'Male' : 'Female', textAlign: TextAlign.end, style: _profileValueStyle(context), ), ), _buildDesktopProfileFieldRow( context: context, label: 'Date of birth', value: Text( selfDob ?? '', textAlign: TextAlign.end, style: _profileValueStyle(context), ), ), _buildDesktopProfileFieldRow( context: context, label: 'Phone No', labelFlex: 4, valueFlex: 8, value: _buildPhoneValueRow(context, alignEnd: true), ), _buildDesktopProfileFieldRow( context: context, label: 'Email id', showBottomBorder: false, value: Text( selfEmailCorporate ?? '', textAlign: TextAlign.end, style: _profileValueStyle(context), ), ), ], ), ), ], ), ); } Widget _buildMobileProfileCard() { return Card( color: Colors.white, surfaceTintColor: Colors.white, elevation: 2, margin: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Container( width: double.infinity, color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildMobileProfileField( context: context, label: 'Gender', value: Text( selfGender == 'M' ? 'Male' : 'Female', textAlign: TextAlign.start, style: _profileValueStyle(context), ), ), _buildMobileProfileField( context: context, label: 'Date of birth', value: Text( selfDob ?? '', textAlign: TextAlign.start, style: _profileValueStyle(context), ), ), _buildMobileProfileField( context: context, label: 'Phone No', value: _buildPhoneValueRow(context), ), _buildMobileProfileField( context: context, label: 'Email id', showDivider: false, value: Text( selfEmailCorporate ?? '', textAlign: TextAlign.start, softWrap: true, style: _profileValueStyle(context), ), ), ], ), ), ); } Widget _buildPhoneValueRow(BuildContext context, {bool alignEnd = false}) { final editIcon = GestureDetector( onTap: () async { 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, ), ); if (alignEnd) { return Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ editIcon, const SizedBox(width: 8), Text( selfMobile ?? '', textAlign: TextAlign.end, style: _profileValueStyle(context), ), ], ); } return Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( selfMobile ?? '', textAlign: TextAlign.start, style: _profileValueStyle(context), ), const SizedBox(width: 8), editIcon, ], ); } Widget _buildDesktopProfileActions() { return Container( width: MediaQuery.of(context).size.width, child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ _buildChangePasswordButton(context), const SizedBox(width: 10), _buildLogoutButton(context), ], ), ); } Widget _buildMobileProfileActions() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox( height: 48, child: OutlinedButton( onPressed: () { if (showSetMpin) { context.go('/pinSettingPage'); } else { context.go('/changePin'); } }, style: OutlinedButton.styleFrom( backgroundColor: Colors.white, side: const BorderSide(color: Color(0xFFE26728)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), alignment: Alignment.centerLeft, padding: const EdgeInsets.symmetric(horizontal: 16), ), child: Text( showSetMpin ? 'Set MPIN' : 'Change PIN', style: GoogleFonts.poppins( color: Color(0xFFE26728), fontWeight: FontWeight.w500, ), ), ), ), const SizedBox(height: 12), SizedBox( height: 48, child: OutlinedButton( onPressed: () => logout(context), style: OutlinedButton.styleFrom( backgroundColor: Colors.white, side: const BorderSide(color: Color(0xFFE26728)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), alignment: Alignment.centerLeft, padding: const EdgeInsets.symmetric(horizontal: 16), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.logout, color: Color(0xFFE26728), size: 20), const SizedBox(width: 8), Text( 'Logout', style: GoogleFonts.poppins( color: Color(0xFFE26728), fontWeight: FontWeight.w500, ), ), ], ), ), ), ], ); } 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)), ), ], ), ), ); } }