This commit is contained in:
Surendiran 2026-02-13 10:25:27 +05:30
parent 5d0566e338
commit 511a671c06
20 changed files with 1482 additions and 1800 deletions

View File

@ -19,12 +19,12 @@ if (project.hasProperty('google-services.json')) {
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { if (flutterVersionCode == null) {
flutterVersionCode = '53' flutterVersionCode = '54'
} }
def flutterVersionName = localProperties.getProperty('flutter.versionName') def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) { if (flutterVersionName == null) {
flutterVersionName = '2.0.15' flutterVersionName = '2.0.16'
} }
def keystoreProperties = new Properties() def keystoreProperties = new Properties()

View File

@ -9,7 +9,6 @@ import 'package:nhance_app_pwa/customAppBar/responsive.dart';
import 'package:nhance_app_pwa/customAppBar/toastHelper.dart'; import 'package:nhance_app_pwa/customAppBar/toastHelper.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../config/environment.dart'; import '../config/environment.dart';
import '../models/platform_helper_mobile.dart' import '../models/platform_helper_mobile.dart'
if (dart.library.html) '../models/platform_helper_other.dart'; if (dart.library.html) '../models/platform_helper_other.dart';
@ -29,7 +28,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
bool showBackToHR = true; bool showBackToHR = true;
bool hideInactiveStatus = true; bool hideInactiveStatus = true;
dynamic empStatus; dynamic empStatus;
dynamic _postToken; // dynamic _postToken;
bool isTokenAvailable = false; bool isTokenAvailable = false;
late ApiService apiService; late ApiService apiService;
final session = SessionManager(); final session = SessionManager();
@ -44,16 +43,28 @@ class _CustomAppBarState extends State<CustomAppBar> {
Future<void> checkEnrollToken() async { Future<void> checkEnrollToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() { setState(() {
isTokenAvailable = prefs.getString('enrollToken') != null; isTokenAvailable = prefs.getString('pre_token') != null;
}); });
} }
Future<void> getEmpStatus() async { Future<void> getEmpStatus() async {
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
// final empStatusValue = prefs.getString('enrollmentEmp_status');
final postTokenValue = prefs.getString('post_token');
setState(() { setState(() {
empStatus = prefs.getString('enrollmentEmp_status'); // // empStatus: null-safe + empty-safe
// _postToken = prefs.getString('_postToken'); // empStatus = (empStatusValue != null && empStatusValue.isNotEmpty)
isTokenAvailable = prefs.getString('_postToken') != null; // ? empStatusValue
// : null;
// token availability: null + empty check
isTokenAvailable =
postTokenValue != null && postTokenValue.trim().isNotEmpty;
debugPrint('empStatus: $empStatus');
debugPrint('isTokenAvailable: $isTokenAvailable');
}); });
} }
@ -80,7 +91,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
body: json.encode(params), body: json.encode(params),
headers: { headers: {
HttpHeaders.contentTypeHeader: 'application/json', HttpHeaders.contentTypeHeader: 'application/json',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'APP-SIGNATURE':
'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
}, },
); );
@ -95,7 +107,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
prefs.setString('mpin', data['Mpin']); prefs.setString('mpin', data['Mpin']);
} }
if (data['is_biometric_enabled'] != null) { if (data['is_biometric_enabled'] != null) {
prefs.setString('is_biometric_enabled', data['is_biometric_enabled']); prefs.setString(
'is_biometric_enabled', data['is_biometric_enabled']);
} }
if (data['is_mpin_skipped'] != null) { if (data['is_mpin_skipped'] != null) {
prefs.setString('is_mpin_skipped', data['is_mpin_skipped']); prefs.setString('is_mpin_skipped', data['is_mpin_skipped']);
@ -169,8 +182,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final sw = MediaQuery.of(context).size.width; final sw = MediaQuery.of(context).size.width;
@ -207,19 +218,19 @@ class _CustomAppBarState extends State<CustomAppBar> {
), ),
// AdaptiveNavBar Column // AdaptiveNavBar Column
if (!isTokenAvailable) if (!isTokenAvailable)
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
NavBarItem( NavBarItem(
text: "Logout", text: "Logout",
onTap: () async { onTap: () async {
logout(context); logout(context);
}, },
), ),
], ],
), ),
// if (empStatus == 'enrolled') // if (empStatus == 'enrolled')
if (isTokenAvailable) if (isTokenAvailable && Responsive.isDesktop(context))
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -236,21 +247,9 @@ class _CustomAppBarState extends State<CustomAppBar> {
}, },
), ),
NavBarItem( NavBarItem(
text: "Help", text: "FAQs",
onTap: () { onTap: () {
context.push('/help'); context.push('/faqs');
},
),
NavBarItem(
text: "Wellness",
onTap: () {
// context.push('/wellness');
// Wellness tab clicked show popup
PopupHelper.showRedirectPopup(
context: context,
apiService: apiService,
empPrimaryId: session.empPrimaryId,
);
}, },
), ),
NavBarItem( NavBarItem(
@ -259,6 +258,29 @@ class _CustomAppBarState extends State<CustomAppBar> {
context.push('/profile'); context.push('/profile');
}, },
), ),
NavBarItem(
text: "Help",
onTap: () {
context.push('/help');
},
),
// NavBarItem(
// text: "Wellness",
// onTap: () => handleMenuTap(() {
// PopupHelper.showRedirectPopup(
// context: context,
// apiService: apiService,
// empPrimaryId: session.empPrimaryId,
// );
// }),
// ),
NavBarItem(
text: "Logout",
onTap: () {
logout(context);
},
),
], ],
), ),
], ],
@ -269,6 +291,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
); );
} }
} }
class NavBarItem extends StatelessWidget { class NavBarItem extends StatelessWidget {
final String text; final String text;
final VoidCallback? onTap; final VoidCallback? onTap;

View File

@ -71,6 +71,8 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
// final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; // final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
// final FirebaseAuth _auth = FirebaseAuth.instance; // final FirebaseAuth _auth = FirebaseAuth.instance;
bool _isLoading = false; bool _isLoading = false;
bool _isOtpVerified = false;
late String _verificationId; late String _verificationId;
dynamic empMobileNo; dynamic empMobileNo;
@ -204,7 +206,13 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
} }
void verifyOTP(String otp) async { void verifyOTP(String otp) async {
if (_isLoading) return; // prevent double tap
setState(() {
_isLoading = true;
});
try { try {
// print('EMAIL PARAMS : ${widget.email} - OTP : $otp'); // print('EMAIL PARAMS : ${widget.email} - OTP : $otp');
final Map<String, dynamic> payload = (widget.type == 'mobile') final Map<String, dynamic> payload = (widget.type == 'mobile')
? {'otp': _otpController.text, 'mobile_number': widget.value} ? {'otp': _otpController.text, 'mobile_number': widget.value}
@ -220,9 +228,6 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
); );
print('response : ${response.statusCode}'); print('response : ${response.statusCode}');
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
print('data: $data'); print('data: $data');
@ -271,43 +276,40 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
if (postStatus == 'success') { if (postStatus == 'success') {
setState(() { setState(() {
_isLoading = false; _isOtpVerified = true; // LOCK
}); });
postSuccessData(post, data); postSuccessData(post, data);
} else if (status == 'success') { } else if (status == 'success') {
setState(() { setState(() {
_isLoading = false; _isOtpVerified = true; // LOCK
}); });
enrollmentSuccessData(data); enrollmentSuccessData(data);
} else { } else {
setState(() {
_isLoading = false;
});
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear(); prefs.clear();
ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); ToastHelper.showErrorToast(context, 'OTP verification failed. Please try again.');
// Show a Snackbar if the OTP is invalid // Show a Snackbar if the OTP is invalid
print('Invalid OTP. Please try again'); print('OTP verification failed. Please try again.');
} }
} else { } else {
setState(() {
_isLoading = false;
});
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear(); prefs.clear();
ToastHelper.showWarningToast(context, 'Something went wrong'); ToastHelper.showWarningToast(context, 'Something went wrong');
throw Exception('Failed to verify OTP'); throw Exception('Failed to verify OTP');
} }
} catch (e) { } catch (e) {
setState(() {
_isLoading = false;
});
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear(); prefs.clear();
print('Error: $e'); print('Error: $e');
ToastHelper.showWarningToast(context, 'Something went wrong'); ToastHelper.showWarningToast(context, 'Something went wrong');
// Show a Snackbar if there's an error while verifying OTP // Show a Snackbar if there's an error while verifying OTP
print('Failed to verify OTP. Please try again.'); print('Failed to verify OTP. Please try again.');
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
} }
} }
@ -339,13 +341,13 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
await SessionManager().initializeFromPostToken(post['data']); await SessionManager().initializeFromPostToken(post['data']);
session = await SessionManager(); session = await SessionManager();
if (session.client_id != null && session.client_id!.isNotEmpty) { // if (session.client_id != null && session.client_id!.isNotEmpty) {
await dataManager.loadSelfEmployeeProfile( // await dataManager.loadSelfEmployeeProfile(
clientId: session.client_id!, // clientId: session.client_id!,
empCode: session.empCodeString!, // empCode: session.empCodeString!,
clientBranchId: session.empClientBranchId!, // clientBranchId: session.empClientBranchId!,
); // );
} // }
// // Decode the JWT token received from the API response // // Decode the JWT token received from the API response
// Map<String, dynamic>? decodedToken = Jwt.parseJwt(post['data']); // Map<String, dynamic>? decodedToken = Jwt.parseJwt(post['data']);
@ -417,7 +419,7 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
// prefs.setString('enrollmentClient_id', enrollmentClient_id); // prefs.setString('enrollmentClient_id', enrollmentClient_id);
// enrollmentEmp_status = decodedToken['emp_status']; // enrollmentEmp_status = decodedToken['emp_status'];
// prefs.setString('enrollmentEmp_status', enrollmentEmp_status); // prefs.setString('enrollmentEmp_status', enrollmentEmp_status);
getClientLogoAndDetails(); // getClientLogoAndDetails();
} }
// //
// if(kIsWeb) { // if(kIsWeb) {
@ -505,7 +507,7 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
// prefs.setString('enrollmentClient_id', enrollmentClient_id); // prefs.setString('enrollmentClient_id', enrollmentClient_id);
// enrollmentEmp_status = decodedToken['emp_status']; // enrollmentEmp_status = decodedToken['emp_status'];
// prefs.setString('enrollmentEmp_status', enrollmentEmp_status); // prefs.setString('enrollmentEmp_status', enrollmentEmp_status);
getClientLogoAndDetails(); // getClientLogoAndDetails();
print('Successfully Login'); print('Successfully Login');
@ -513,7 +515,7 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
// final enrollToken = prefs.getString('enrollToken'); // final enrollToken = prefs.getString('enrollToken');
// int skipStatus = prefs.getInt('skipStatus') ?? 1; // int skipStatus = prefs.getInt('skipStatus') ?? 1;
// final mpinText = prefs.getString('mpinText'); // final mpinText = prefs.getString('mpinText');
print(isMobilePlatform()); // print(isMobilePlatform());
if (isMobilePlatform()) { if (isMobilePlatform()) {
// if (prefs.containsKey('mpin') && mpinText == 'Mpin - exist') { // if (prefs.containsKey('mpin') && mpinText == 'Mpin - exist') {
if (_preToken != null && _preToken.isNotEmpty) { if (_preToken != null && _preToken.isNotEmpty) {
@ -546,6 +548,7 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
_otpController.text = ''; _otpController.text = '';
_secondsRemaining = 60; _secondsRemaining = 60;
_isTimerRunning = true; _isTimerRunning = true;
_isLoading = false;
}); });
startTimer(); startTimer();
verifyMobileAndEmailNumber(); verifyMobileAndEmailNumber();
@ -1063,6 +1066,15 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
showCursor: true, showCursor: true,
controller: _otpController, controller: _otpController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'OTP is required';
}
if (value.length < 6) {
return 'Please enter a valid 6-digit OTP';
}
return null;
},
), ),
), ),
SizedBox(height: 10), SizedBox(height: 10),
@ -1118,20 +1130,28 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
BorderRadius.circular(10), BorderRadius.circular(10),
), ),
), ),
onPressed: () { onPressed: (_isLoading || _isOtpVerified)
if (_formKey.currentState! ? null
.validate()) { : () {
_formKey.currentState! if (_formKey.currentState!.validate()) {
.save(); // Save form fields before calling verifyOTP verifyOTP(_otpController.text.trim());
verifyOTP( }
_otpController.text); },
} child: _isLoading
}, ? CircularProgressIndicator(
child: Text( valueColor:
"Submit", AlwaysStoppedAnimation<
style: GoogleFonts.poppins( Color>(
color: Color(0xFFFFFFFF)), Color(0xFF00989E),
), ),
)
: Text( "Submit",
style: GoogleFonts
.poppins(
color: Color(
0xFFFFFFFF),
),
)
), ),
), ),
), ),

View File

@ -4590,40 +4590,38 @@ class _addOnsDetailsState extends State<addOnsDetails> {
? CustomBottomNavigationBar( ? CustomBottomNavigationBar(
onTabChanged: (index) { onTabChanged: (index) {
// Add your navigation logic here // Add your navigation logic here
// For example: // repositionBotman();
if (index == 0) { if (index == 0) {
context.go('/home'); context.push('/home');
// Navigator.pushNamed(context, 'home');
} else if (index == 1) { } else if (index == 1) {
context.go('/claims'); context.push('/claims');
// Navigator.pushNamed(context, 'claims');
} else if (index == 2) { } else if (index == 2) {
context.go('/profile'); context.push('/faqs');
// Navigator.pushNamed(context, 'profile');
} else if (index == 3) { } else if (index == 3) {
context.go('/help'); context.push('/profile');
// Navigator.pushNamed(context, 'help');
} else if (index == 4) { } else if (index == 4) {
context.go('/wellness'); context.push('/help');
// Navigator.pushNamed(context, 'wellness');
} }
// 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: [
Icons.home_outlined, Icons.home_outlined,
Icons.sticky_note_2_outlined, Icons.sticky_note_2_outlined,
Icons.question_answer_outlined,
Icons.person_outline_outlined, Icons.person_outline_outlined,
Icons.headset_mic_outlined, Icons.headset_mic_outlined,
Icons.health_and_safety_outlined,
], ],
labels: [ labels: ["Home", "Claims", "FAQs", "Profile","Help"],
"Home", initialIndex: 0, // Initial index of the bottom navigation bar
"Claims",
"Profile",
"Help",
"wellness",
],
initialIndex:
0, // Initial index of the bottom navigation bar
) : null, ) : null,
) ); ) );
} }

View File

@ -1044,42 +1044,41 @@ class _empDetailsState extends State<empDetails> {
? null ? null
: isTokenAvailable : isTokenAvailable
? CustomBottomNavigationBar( ? CustomBottomNavigationBar(
onTabChanged: (index) { onTabChanged: (index) {
// For example: // Add your navigation logic here
if (index == 0) { // repositionBotman();
context.go('/home'); if (index == 0) {
// Navigator.pushNamed(context, 'home'); context.push('/home');
} else if (index == 1) { } else if (index == 1) {
context.go('/claims'); context.push('/claims');
// Navigator.pushNamed(context, 'claims'); } else if (index == 2) {
} else if (index == 2) { context.push('/faqs');
context.go('/profile'); } else if (index == 3) {
// Navigator.pushNamed(context, 'profile'); context.push('/profile');
} else if (index == 3) { } else if (index == 4) {
context.go('/help'); context.push('/help');
// Navigator.pushNamed(context, 'help'); }
} else if (index == 4) { // else if (index == 4) {
context.go('/wellness'); // // context.push('/wellness');
// Navigator.pushNamed(context, 'wellness'); // // Wellness tab clicked show popup
} // if(!isRetailLoggedIn)
}, // PopupHelper.showRedirectPopup(
icons: [ // context: context,
Icons.home_outlined, // apiService: apiService,
Icons.sticky_note_2_outlined, // empPrimaryId: session.empPrimaryId,
Icons.person_outline_outlined, // );
Icons.headset_mic_outlined, // }
Icons.health_and_safety_outlined, },
], icons: [
labels: [ Icons.home_outlined,
"Home", Icons.sticky_note_2_outlined,
"Claims", Icons.question_answer_outlined,
"Profile", Icons.person_outline_outlined,
"Help", Icons.headset_mic_outlined,
"Wellness", ],
], labels: ["Home", "Claims", "FAQs", "Profile","Help"],
initialIndex: initialIndex: 0, // Initial index of the bottom navigation bar
0, // Initial index of the bottom navigation bar )
)
: null, : null,
)); ));
} }

View File

@ -586,6 +586,7 @@ class _empReviewDetailsState extends State<empReviewDetails> {
// setState(() { // setState(() {
topUpClientPolicyId = topUpClientPolicyId =
topUpSiPolicies['gmc_si_topup']['client_policy_id']; topUpSiPolicies['gmc_si_topup']['client_policy_id'];
print('topUpClientPolicyId12345 $topUpClientPolicyId');
topUpSumInsured = topUpSiPolicies['gmc_si_topup'] topUpSumInsured = topUpSiPolicies['gmc_si_topup']
['family_floaters_of_only_si_value']; ['family_floaters_of_only_si_value'];
@ -3309,43 +3310,41 @@ setState(() {
? null ? null
: isTokenAvailable : isTokenAvailable
? CustomBottomNavigationBar( ? CustomBottomNavigationBar(
onTabChanged: (index) { onTabChanged: (index) {
// Add your navigation logic here // Add your navigation logic here
// For example: // repositionBotman();
if (index == 0) { if (index == 0) {
context.go('/home'); context.push('/home');
// Navigator.pushNamed(context, 'home'); } else if (index == 1) {
} else if (index == 1) { context.push('/claims');
context.go('/claims'); } else if (index == 2) {
// Navigator.pushNamed(context, 'claims'); context.push('/faqs');
} else if (index == 2) { } else if (index == 3) {
context.go('/profile'); context.push('/profile');
// Navigator.pushNamed(context, 'profile'); } else if (index == 4) {
} else if (index == 3) { context.push('/help');
context.go('/help'); }
// Navigator.pushNamed(context, 'help'); // else if (index == 4) {
} else if (index == 4) { // // context.push('/wellness');
context.go('/wellness'); // // Wellness tab clicked show popup
// Navigator.pushNamed(context, 'wellness'); // if(!isRetailLoggedIn)
} // PopupHelper.showRedirectPopup(
}, // context: context,
icons: [ // apiService: apiService,
Icons.home_outlined, // empPrimaryId: session.empPrimaryId,
Icons.sticky_note_2_outlined, // );
Icons.person_outline_outlined, // }
Icons.headset_mic_outlined, },
Icons.health_and_safety_outlined, icons: [
], Icons.home_outlined,
labels: [ Icons.sticky_note_2_outlined,
"Home", Icons.question_answer_outlined,
"Claims", Icons.person_outline_outlined,
"Profile", Icons.headset_mic_outlined,
"Help", ],
"wellness", labels: ["Home", "Claims", "FAQs", "Profile","Help"],
], initialIndex: 0, // Initial index of the bottom navigation bar
initialIndex: )
0, // Initial index of the bottom navigation bar
)
: null, : null,
)); ));
} }

View File

@ -508,6 +508,11 @@ class ApiService {
await _clearLocalStorageAndRedirect(); await _clearLocalStorageAndRedirect();
} }
return {}; return {};
} else if (response.statusCode == 429) {
final body = jsonDecode(response.body);
final message = body['message'];
ToastHelper.showWarningToast(context, message);
return {};
} else { } else {
throw Exception('Failed to load data'); throw Exception('Failed to load data');
} }

View File

@ -280,7 +280,14 @@ class _loginState extends State<login> {
ToastHelper.showErrorToast(context, message); ToastHelper.showErrorToast(context, message);
print('Invalid mobile number'); print('Invalid mobile number');
} }
} else { } else if (response.statusCode == 429) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
final message = data['message'];
ToastHelper.showErrorToast(context, message);
} else {
setState(() { setState(() {
_isLoading = false; _isLoading = false;
}); });

View File

@ -129,8 +129,6 @@ class _ClaimHistoryPopupState extends State<ClaimHistoryPopup>
}); });
} }
// ------------------------- // -------------------------
// Remove assignment // Remove assignment
// ------------------------- // -------------------------

View File

@ -29,6 +29,7 @@ class _generalExclusionsDeductiblesState
late ApiService apiService; late ApiService apiService;
int _currentIndex = 0; int _currentIndex = 0;
bool isActive = true; bool isActive = true;
bool isLoading = false;
dynamic _token; dynamic _token;
dynamic empCodeString; dynamic empCodeString;
dynamic empPrimaryId; dynamic empPrimaryId;
@ -40,30 +41,19 @@ class _generalExclusionsDeductiblesState
late Map<String, String> generalContent; late Map<String, String> generalContent;
late Map<String, String> generalNotes; late Map<String, String> generalNotes;
dynamic type3; // Headings
dynamic type3SectionName; String? type3SectionName, type3Heading;
dynamic type3Heading; String? type4SectionName, type4Heading;
late Map<String, String> type3Content; String? type5Heading;
String? type6Heading;
String? type7Heading;
dynamic type4; // Content lists
dynamic type4SectionName; List<String> type3Content = [];
dynamic type4Heading; List<String> type4Content = [];
late Map<String, String> type4Content; List<String> type5Content = [];
List<String> type6Content = [];
dynamic type5; List<String> type7Content = [];
dynamic type5SectionName;
dynamic type5Heading;
late Map<String, String> type5Content;
dynamic type6;
dynamic type6SectionName;
dynamic type6Heading;
late Map<String, String> type6Content;
dynamic type7;
dynamic type7SectionName;
dynamic type7Heading;
late Map<String, String> type7Content;
final session = SessionManager(); final session = SessionManager();
@ -95,68 +85,81 @@ class _generalExclusionsDeductiblesState
} }
} }
/// 🔥 Extract <li> text from HTML
List<String> extractListItems(String html) {
final regex = RegExp(r'<li>(.*?)<\/li>', dotAll: true);
return regex
.allMatches(html)
.map((m) => m.group(1)!.replaceAll(RegExp(r'<[^>]*>'), '').trim())
.toList();
}
Future<void> getCashlessAndReimbursement() async { Future<void> getCashlessAndReimbursement() async {
final response = await apiService.getCashlessAndReimbursementToApi(); setState(() => isLoading = true);
print('check 1');
if (response['status'] == 'success') { try {
print(response['data']); final response = await apiService.getCashlessAndReimbursementToApi();
if (response['status'] != 'success') {
setState(() => isLoading = false);
return;
}
final List data = response['data'];
final filtered =
data.where((e) => e['content_section'] != 'Video').toList();
Map<String, dynamic>? findType(String type) {
try {
return filtered.firstWhere((e) => e['type'] == type);
} catch (_) {
return null;
}
}
final t3 = findType('3');
final t4 = findType('4');
final t5 = findType('5');
final t6 = findType('6');
final t7 = findType('7');
setState(() { setState(() {
generalExclusionsDetails = response['data'][3]; if (t3 != null) {
type3 = response['data'][2]; type3SectionName = t3['content_section'];
print(type3); type3Heading = t3['heading'];
type3SectionName = type3['content_section']; type3Content = extractListItems(t3['content']);
type3Heading = type3['heading']; }
Map<String, dynamic> type3ContentjsonData =
jsonDecode(type3['content']);
type3Content = Map<String, String>.from(type3ContentjsonData);
print('type3Content');
print(type3Content);
type4 = response['data'][3]; if (t4 != null) {
print(type4); type4Heading = t4['heading'];
type4SectionName = type4['content_section']; type4Content = extractListItems(t4['content']);
type4Heading = type4['heading']; }
Map<String, dynamic> type4ContentjsonData =
jsonDecode(type4['content']);
type4Content = Map<String, String>.from(type4ContentjsonData);
print('type4Content');
print(type4Content);
type5 = response['data'][4]; if (t5 != null) {
print(type5); type5Heading = t5['heading'];
type5SectionName = type5['content_section']; type5Content = extractListItems(t5['content']);
type5Heading = type5['heading']; }
Map<String, dynamic> type5ContentjsonData =
jsonDecode(type5['content']);
type5Content = Map<String, String>.from(type5ContentjsonData);
print('type5Content');
print(type5Content);
type6 = response['data'][5]; if (t6 != null) {
print(type6); type6Heading = t6['heading'];
type6SectionName = type6['content_section']; type6Content = extractListItems(t6['content']);
type6Heading = type6['heading']; }
Map<String, dynamic> type6ContentjsonData =
jsonDecode(type6['content']);
type6Content = Map<String, String>.from(type6ContentjsonData);
print('type6Content');
print(type6Content);
type7 = response['data'][6]; if (t7 != null) {
print(type7); type7Heading = t7['heading'];
type7SectionName = type7['content_section']; type7Content = extractListItems(t7['content']);
type7Heading = type7['heading']; }
Map<String, dynamic> type7ContentjsonData =
jsonDecode(type7['content']); isLoading = false;
type7Content = Map<String, String>.from(type7ContentjsonData);
print('type7Content');
print(type7Content);
}); });
} else { } catch (e) {
print('API request failed with status: ${response['status']}'); debugPrint('API ERROR: $e');
setState(() => isLoading = false);
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopScope( return PopScope(
@ -166,682 +169,140 @@ class _generalExclusionsDeductiblesState
context.pop(); context.pop();
}, },
child: Scaffold( child: Scaffold(
backgroundColor: Colors.white,
appBar: CustomAppBar(), appBar: CustomAppBar(),
body: Stack( backgroundColor: Colors.white,
children: [ body: isLoading
SingleChildScrollView( ? Container(
child: Container( color: Color(0x98FFFCE5), // Semi-transparent background
padding: Responsive.isDesktop(context) child: Center(
? EdgeInsets.symmetric( child: // Your GIF loader widget
horizontal: MediaQuery.of(context).size.width * 0.2, Image.asset(
vertical: MediaQuery.of(context).size.height * 0.03, height: 60,
) width: 60,
: EdgeInsets.all(10), 'assets/nhance-loader.gif'), // Adjust path to your GIF loader
color: Colors.white, ),
)
: SingleChildScrollView(
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.2,
vertical: MediaQuery.of(context).size.height * 0.03,
)
: EdgeInsets.all(10),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( Text(
padding: Responsive.isDesktop(context) 'General Exclusions & Deductibles',
? EdgeInsets.symmetric(vertical: 15, horizontal: 25) style: GoogleFonts.poppins(
: EdgeInsets.all(0), fontSize: 18, fontWeight: FontWeight.w600),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 12,
child: InkWell(
onTap: () {
context.pop();
},
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
// if (!Responsive.isDesktop(context))
Icon(
Icons.chevron_left,
color: Color(0xFF000000),
size: 30,
),
SizedBox(
width: Responsive.isDesktop(context)
? 0
: 5),
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'General Exclusions & Deductibles',
textAlign: TextAlign.start,
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xFF000000),
),
),
],
),
],
),
),
),
],
),
],
),
), ),
SizedBox(height: 15), const SizedBox(height: 20),
Container( if (type3Content.isNotEmpty) ...[
decoration: BoxDecoration( Text(type3SectionName ?? '',
borderRadius: BorderRadius.circular(5), style: GoogleFonts.poppins(
), fontSize: 18, fontWeight: FontWeight.w500)),
padding: Responsive.isDesktop(context) const SizedBox(height: 10),
? EdgeInsets.symmetric(vertical: 15, horizontal: 25) buildBulletList(type3Content),
: EdgeInsets.all(10), ],
child: Column( if (type4Content.isNotEmpty) ...[
crossAxisAlignment: CrossAxisAlignment.start, const SizedBox(height: 20),
children: [ Text(type4Heading ?? '',
Padding( style: GoogleFonts.poppins(
padding: EdgeInsets.only(bottom: 20), fontSize: 18, fontWeight: FontWeight.w500)),
child: Column( buildBulletList(type4Content),
crossAxisAlignment: CrossAxisAlignment.start, ],
children: [ if (type5Content.isNotEmpty) ...[
Text( const SizedBox(height: 20),
type3SectionName ?? '', Text(type5Heading ?? '',
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context) fontSize: 18, fontWeight: FontWeight.w500)),
? 18 buildBulletList(type5Content),
: 16, ],
fontWeight: FontWeight.w500, if (type6Content.isNotEmpty) ...[
color: Color(0xFF000000), const SizedBox(height: 20),
), Text(type6Heading ?? '',
), style: GoogleFonts.poppins(
], fontSize: 18, fontWeight: FontWeight.w500)),
), buildBulletList(type6Content),
), ],
if (generalExclusionsDetails != null) if (type7Content.isNotEmpty) ...[
Padding( const SizedBox(height: 20),
padding: Text(type7Heading ?? '',
EdgeInsets.only(bottom: 20, left: 15), style: GoogleFonts.poppins(
child: Column( fontSize: 18, fontWeight: FontWeight.w500)),
crossAxisAlignment: buildBulletList(type7Content),
CrossAxisAlignment.start, ],
children: [
SizedBox(height: 10),
LayoutBuilder(
builder: (context, constraints) {
double itemHeight =
50; // Adjust item height based on content
double listViewHeight =
type3Content.length * itemHeight;
double maxHeight =
constraints.maxHeight;
if (listViewHeight > maxHeight) {
listViewHeight = maxHeight;
}
return Container(
height: listViewHeight,
child: ListView.builder(
itemCount: type3Content.length,
itemBuilder: (context, index) {
String key = type3Content.keys
.elementAt(index);
String value =
type3Content[key]!;
return Padding(
padding: const EdgeInsets
.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets
.only(
left: 20.0),
child: Text(
"",
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFFE26728),
),
),
),
Expanded(
child: Text(
value,
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFF000000),
),
),
),
],
),
);
},
),
);
},
),
],
),
),
]),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
type4SectionName ?? '',
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context)
? 18
: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
),
),
],
),
),
if (generalExclusionsDetails != null)
Padding(
padding:
EdgeInsets.only(bottom: 20, left: 15),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
type4Heading ?? '',
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context)
? 18
: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
),
),
SizedBox(height: 10),
LayoutBuilder(
builder: (context, constraints) {
double itemHeight =
40; // Adjust item height based on content
double listViewHeight =
type4Content.length * itemHeight;
double maxHeight =
constraints.maxHeight;
if (listViewHeight > maxHeight) {
listViewHeight = maxHeight;
}
return Container(
height: listViewHeight,
child: ListView.builder(
itemCount: type4Content.length,
itemBuilder: (context, index) {
String key = type4Content.keys
.elementAt(index);
String value =
type4Content[key]!;
return Padding(
padding: const EdgeInsets
.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets
.only(
left: 20.0),
child: Text(
"",
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFFE26728),
),
),
),
Expanded(
child: Text(
value,
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFF000000),
),
),
),
],
),
);
},
),
);
},
),
],
),
),
]),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (generalExclusionsDetails != null)
Padding(
padding:
EdgeInsets.only(bottom: 20, left: 15),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
type5Heading ?? '',
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context)
? 18
: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
),
),
SizedBox(height: 10),
LayoutBuilder(
builder: (context, constraints) {
double itemHeight =
40; // Adjust item height based on content
double listViewHeight =
type5Content.length * itemHeight;
double maxHeight =
constraints.maxHeight;
if (listViewHeight > maxHeight) {
listViewHeight = maxHeight;
}
return Container(
height: listViewHeight,
child: ListView.builder(
itemCount: type5Content.length,
itemBuilder: (context, index) {
String key = type5Content.keys
.elementAt(index);
String value =
type5Content[key]!;
return Padding(
padding: const EdgeInsets
.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets
.only(
left: 20.0),
child: Text(
"",
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFFE26728),
),
),
),
Expanded(
child: Text(
value,
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFF000000),
),
),
),
],
),
);
},
),
);
},
),
],
),
),
]),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (generalExclusionsDetails != null)
Padding(
padding:
EdgeInsets.only(bottom: 20, left: 15),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
type6Heading ?? '',
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context)
? 18
: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
),
),
SizedBox(height: 10),
LayoutBuilder(
builder: (context, constraints) {
double itemHeight =
40; // Adjust item height based on content
double listViewHeight =
type6Content.length * itemHeight;
double maxHeight =
constraints.maxHeight;
if (listViewHeight > maxHeight) {
listViewHeight = maxHeight;
}
return Container(
height: listViewHeight,
child: ListView.builder(
itemCount: type6Content.length,
itemBuilder: (context, index) {
String key = type6Content.keys
.elementAt(index);
String value =
type6Content[key]!;
return Padding(
padding: const EdgeInsets
.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets
.only(
left: 20.0),
child: Text(
"",
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFFE26728),
),
),
),
Expanded(
child: Text(
value,
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFF000000),
),
),
),
],
),
);
},
),
);
},
),
],
),
),
]),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (generalExclusionsDetails != null)
Padding(
padding:
EdgeInsets.only(bottom: 20, left: 15),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
type7Heading ?? '',
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context)
? 18
: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
),
),
SizedBox(height: 10),
LayoutBuilder(
builder: (context, constraints) {
double itemHeight =
40; // Adjust item height based on content
double listViewHeight =
type7Content.length * itemHeight;
double maxHeight =
constraints.maxHeight;
if (listViewHeight > maxHeight) {
listViewHeight = maxHeight;
}
return Container(
height: listViewHeight,
child: ListView.builder(
itemCount: type7Content.length,
itemBuilder: (context, index) {
String key = type7Content.keys
.elementAt(index);
String value =
type7Content[key]!;
return Padding(
padding: const EdgeInsets
.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets
.only(
left: 20.0),
child: Text(
"",
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFFE26728),
),
),
),
Expanded(
child: Text(
value,
style: GoogleFonts
.poppins(
fontSize: 16,
fontWeight:
FontWeight.w400,
color: Color(
0xFF000000),
),
),
),
],
),
);
},
),
);
},
),
],
),
),
]),
),
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
], ],
), ),
), ),
),
if (Responsive.isDesktop(context))
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
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) bottomNavigationBar: Responsive.isDesktop(context)
? null ? SizedBox(
: CustomBottomNavigationBar( height: 40, // 👈 FIXED HEIGHT (adjust if needed)
onTabChanged: (index) { width: double.infinity,
// Add your navigation logic here child: CustomFooter(),
// repositionBotman(); )
if (index == 0) { : CustomBottomNavigationBar(
context.push('/home'); initialIndex: 0,
} else if (index == 1) { labels: const ["Home", "Claims", "FAQs", "Profile", "Help"],
context.push('/claims'); icons: const [
} else if (index == 2) { Icons.home_outlined,
context.push('/faqs'); Icons.sticky_note_2_outlined,
} else if (index == 3) { Icons.question_answer_outlined,
context.push('/profile'); Icons.person_outline_outlined,
} else if (index == 4) { Icons.headset_mic_outlined,
context.push('/help'); ],
} onTabChanged: (index) {
// else if (index == 4) { if (index == 0) context.push('/home');
// // context.push('/wellness'); if (index == 1) context.push('/claims');
// // Wellness tab clicked show popup if (index == 2) context.push('/faqs');
// if(!isRetailLoggedIn) if (index == 3) context.push('/profile');
// PopupHelper.showRedirectPopup( if (index == 4) context.push('/help');
// 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: 0, // Initial index of the bottom navigation bar
),
)); ));
} }
Widget buildBulletList(List<String> items) {
if (items.isEmpty) return const SizedBox.shrink();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: items.map((text) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.only(top: 2),
child: Text(
"",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xFFE26728),
),
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
text,
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
),
),
),
],
),
);
}).toList(),
);
}
} }

View File

@ -506,82 +506,82 @@ class _helpState extends State<help> {
]), ]),
), ),
Container( // Container(
width: Responsive.isDesktop(context) ? 500 : double.infinity, // width: Responsive.isDesktop(context) ? 500 : double.infinity,
height: 75, // height: 75,
// padding: Responsive.isDesktop(context) // // padding: Responsive.isDesktop(context)
// ? EdgeInsets.only(top: 20, bottom: 20, left: 30, right: 30) // // ? EdgeInsets.only(top: 20, bottom: 20, left: 30, right: 30)
// : EdgeInsets.only(top: 5, bottom: 5,left: 10,right: 10), // // : EdgeInsets.only(top: 5, bottom: 5,left: 10,right: 10),
padding: Responsive.isDesktop(context) // padding: Responsive.isDesktop(context)
? EdgeInsets.only( // ? EdgeInsets.only(
top: 20, bottom: 20, left: 30, right: 30) // top: 20, bottom: 20, left: 30, right: 30)
: EdgeInsets.symmetric(vertical: 5, horizontal: 10), // : EdgeInsets.symmetric(vertical: 5, horizontal: 10),
child: Row( // child: Row(
children: [ // children: [
// Expanded( // // Expanded(
// flex: 6, // // flex: 6,
// child: ElevatedButton( // // child: ElevatedButton(
// onPressed: () { // // onPressed: () {
// var details = { // // var details = {
// 'claimsDetails': '', // // 'claimsDetails': '',
// 'fromClaimPage': 1, // // 'fromClaimPage': 1,
// }; // // };
// Navigator.pushNamed(context, 'planclaimsform', // // Navigator.pushNamed(context, 'planclaimsform',
// arguments: details); // // arguments: details);
// }, // // },
// style: ElevatedButton.styleFrom( // // style: ElevatedButton.styleFrom(
// backgroundColor: Color(0xFFE26728), // // backgroundColor: Color(0xFFE26728),
// shape: RoundedRectangleBorder( // // shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(5), // // borderRadius: BorderRadius.circular(5),
// ), // // ),
// ), // // ),
// child: Text( // // child: Text(
// 'Raise Claims', // // 'Raise Claims',
// style: GoogleFonts.poppins(color: Colors.white), // // style: GoogleFonts.poppins(color: Colors.white),
// ), // // ),
// ), // // ),
// ), // // ),
// SizedBox(width: 10), // // SizedBox(width: 10),
Expanded( // Expanded(
flex: 4, // flex: 4,
child: ElevatedButton( // child: ElevatedButton(
onPressed: () { // onPressed: () {
context.go('/tickets'); // context.go('/tickets');
}, // },
style: ElevatedButton.styleFrom( // style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFE26728), // backgroundColor: Color(0xFFE26728),
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5), // borderRadius: BorderRadius.circular(5),
), // ),
), // ),
child: Text( // child: Text(
'Raise a Query', // 'Raise a Query',
style: GoogleFonts.poppins(color: Colors.white), // style: GoogleFonts.poppins(color: Colors.white),
), // ),
), // ),
), // ),
SizedBox(width: 10), // SizedBox(width: 10),
Expanded( // Expanded(
flex: 4, // flex: 4,
child: ElevatedButton( // child: ElevatedButton(
onPressed: () { // onPressed: () {
context.go('/raisedTicketHistory'); // context.go('/raisedTicketHistory');
}, // },
style: ElevatedButton.styleFrom( // style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFE26728), // backgroundColor: Color(0xFFE26728),
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5), // borderRadius: BorderRadius.circular(5),
), // ),
), // ),
child: Text( // child: Text(
'Track Queries', // 'Track Queries',
style: GoogleFonts.poppins(color: Colors.white), // style: GoogleFonts.poppins(color: Colors.white),
), // ),
), // ),
), // ),
], // ],
), // ),
), // ),
SizedBox(height: 5), SizedBox(height: 5),

View File

@ -1800,7 +1800,7 @@ class _HomeState extends State<Home> {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
context.go('/policies', extra: item); context.push('/policies', extra: item);
}, },
child: MouseRegion( child: MouseRegion(
cursor: SystemMouseCursors.click, cursor: SystemMouseCursors.click,

View File

@ -78,6 +78,7 @@ class _planclaimsformState extends State<planclaimsform> {
// List<html.File> uploadedFiles = []; // List<html.File> uploadedFiles = [];
List<PlatformFile> uploadedFiles = []; List<PlatformFile> uploadedFiles = [];
final fileService = FileUploadService(); final fileService = FileUploadService();
bool isSubmitting = false;
// Declare subjectController and bodyController as instance variables // Declare subjectController and bodyController as instance variables
@ -177,7 +178,10 @@ class _planclaimsformState extends State<planclaimsform> {
sumInsuredController.dispose(); sumInsuredController.dispose();
admitDateController.dispose(); admitDateController.dispose();
dischargeDateController.dispose(); dischargeDateController.dispose();
serviceId = null;
departmentList.clear();
super.dispose(); super.dispose();
fileService.clearAll();
} }
// void repositionBotman() { // void repositionBotman() {
@ -537,6 +541,7 @@ class _planclaimsformState extends State<planclaimsform> {
} }
Future<void> sendFormDataToApi() async { Future<void> sendFormDataToApi() async {
setState(() => isSubmitting = true); // 🔥 start loader
setState(() { setState(() {
isServiceValid = serviceId != null; isServiceValid = serviceId != null;
isPolicyValid = policyNumberId != null; isPolicyValid = policyNumberId != null;
@ -653,7 +658,7 @@ class _planclaimsformState extends State<planclaimsform> {
_token = await TokenService.getPostToken(); _token = await TokenService.getPostToken();
final request = http.MultipartRequest('POST', Uri.parse('${Environment.apiUrl}/initiateClaim')); final request = http.MultipartRequest('POST', Uri.parse('${Environment.apiUrl}initiateClaim'));
request.headers['Authorization'] = 'Bearer $_token'; request.headers['Authorization'] = 'Bearer $_token';
request.headers['APP-SIGNATURE'] = 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y'; request.headers['APP-SIGNATURE'] = 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y';
final stringFields = fields.map((key, value) => MapEntry(key, value?.toString() ?? '')); final stringFields = fields.map((key, value) => MapEntry(key, value?.toString() ?? ''));
@ -780,6 +785,8 @@ class _planclaimsformState extends State<planclaimsform> {
isLoading = false; isLoading = false;
}); });
print('Error submitting form data: $e'); print('Error submitting form data: $e');
} finally {
setState(() => isSubmitting = false); // 🔥 stop loader
} }
} }
@ -1412,7 +1419,16 @@ SizedBox(height: 15),
onPressed: () { onPressed: () {
sendFormDataToApi(); sendFormDataToApi();
}, },
child: Text( child: isSubmitting
? SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: Text(
'Send', 'Send',
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
color: Colors.white), color: Colors.white),

View File

@ -291,7 +291,8 @@ class _policiesState extends State<policies> {
canPop: false, canPop: false,
onPopInvokedWithResult: (didPop, result) { onPopInvokedWithResult: (didPop, result) {
if (didPop) return; if (didPop) return;
context.go('/home'); // context.go('/home');
context.pop();
}, },
child: Scaffold( child: Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
@ -330,7 +331,8 @@ class _policiesState extends State<policies> {
flex: 1, flex: 1,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
context.go('/home'); // context.go('/home');
context.pop();
}, },
child: Icon( child: Icon(
Icons Icons

View File

@ -69,6 +69,7 @@ class _profileState extends State<profile> {
final session = SessionManager(); final session = SessionManager();
String installedVersion = ""; String installedVersion = "";
String? storeVersion = ""; String? storeVersion = "";
bool showSetMpin = false;
void _onTabChanged(int index) { void _onTabChanged(int index) {
setState(() { setState(() {
@ -81,7 +82,9 @@ class _profileState extends State<profile> {
super.initState(); super.initState();
apiService = ApiService(context); // Initialize ApiService here apiService = ApiService(context); // Initialize ApiService here
_loadToken(); _loadToken();
// _checkMpinStatus();
if(!kIsWeb){ if(!kIsWeb){
_checkMpinStatus();
loadVersionInfo(); loadVersionInfo();
} }
} }
@ -91,6 +94,22 @@ class _profileState extends State<profile> {
super.dispose(); super.dispose();
} }
Future<void> _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<void> loadVersionInfo() async { Future<void> loadVersionInfo() async {
print('App version:}'); print('App version:}');
installedVersion = await AppVersionService.getInstalledVersion(); installedVersion = await AppVersionService.getInstalledVersion();
@ -762,15 +781,20 @@ class _profileState extends State<profile> {
alignment: Alignment.center, alignment: Alignment.center,
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
print('changePin'); if (showSetMpin) {
context.go('/changePin'); print('pinSettingPage');
context.go('/pinSettingPage'); // Set MPIN page
} else {
print('changePin');
context.go('/changePin'); // Change PIN page
}
}, },
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
// Adjust space between icon and text // Adjust space between icon and text
Text( Text(
'Change Pin', showSetMpin ? 'Set MPIN' : 'Change PIN',
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
color: Color(0xFFE26728)), color: Color(0xFFE26728)),
), ),

View File

@ -42,6 +42,10 @@ class ApiService {
Future<Map<String, dynamic>> getClaimsHistoryToApi( Future<Map<String, dynamic>> getClaimsHistoryToApi(
String ticket_type_id) async { String ticket_type_id) async {
print("getCashDepositDetailsToApi1"); print("getCashDepositDetailsToApi1");
print(_postToken);
if (_postToken == null) {
await _initializeToken();
}
final url = final url =
Uri.parse('${Environment.apiUrl}claimView?ticket_id=$ticket_type_id'); Uri.parse('${Environment.apiUrl}claimView?ticket_id=$ticket_type_id');
@ -112,7 +116,7 @@ class ApiService {
await _initializeToken(); await _initializeToken();
} }
final url = Uri.parse( final url = Uri.parse(
'${Environment.apiUrl}/get_ticket_data?emp_id=$empPrimaryId&mobile_number=$mobileNo&email_id=$emailID'); '${Environment.apiUrl}get_ticket_data?emp_id=$empPrimaryId&mobile_number=$mobileNo&email_id=$emailID');
final headers = { final headers = {
'Authorization': 'Bearer $_postToken' ?? '', 'Authorization': 'Bearer $_postToken' ?? '',
}; };
@ -242,7 +246,7 @@ class ApiService {
if (_postToken == null) { if (_postToken == null) {
await _initializeToken(); await _initializeToken();
} }
final url = Uri.parse('${Environment.apiUrl}/get_ticket_type?client_id=$clientId&emp_code=$empCode'); final url = Uri.parse('${Environment.apiUrl}get_ticket_type?client_id=$clientId&emp_code=$empCode');
final headers = { final headers = {
'Authorization': 'Bearer $_postToken' ?? '', 'Authorization': 'Bearer $_postToken' ?? '',
}; };
@ -255,7 +259,7 @@ class ApiService {
if (_postToken == null) { if (_postToken == null) {
await _initializeToken(); await _initializeToken();
} }
final url = Uri.parse('${Environment.apiUrl}/getClaimTypeMaster'); final url = Uri.parse('${Environment.apiUrl}getClaimTypeMaster');
final headers = { final headers = {
'Authorization': 'Bearer $_postToken' ?? '', 'Authorization': 'Bearer $_postToken' ?? '',
}; };
@ -286,7 +290,7 @@ class ApiService {
if (_postToken == null) { if (_postToken == null) {
await _initializeToken(); await _initializeToken();
} }
final url = Uri.parse('${Environment.apiUrl}/initiateClaim'); final url = Uri.parse('${Environment.apiUrl}initiateClaim');
// Convert formData to Map<String, String> // Convert formData to Map<String, String>
Map<String, String> stringFormData = Map<String, String> stringFormData =
formData.map((key, value) => MapEntry(key, value.toString())); formData.map((key, value) => MapEntry(key, value.toString()));
@ -299,6 +303,10 @@ class ApiService {
Future<Map<String, dynamic>> sendClaimsMessageToApi( Future<Map<String, dynamic>> sendClaimsMessageToApi(
Map<String, dynamic> formData) async { Map<String, dynamic> formData) async {
print(_postToken);
if (_postToken == null) {
await _initializeToken();
}
print("sendClaimsMessageToApi"); print("sendClaimsMessageToApi");
final url = Uri.parse('${Environment.apiUrl}ticketConversationSave'); final url = Uri.parse('${Environment.apiUrl}ticketConversationSave');
// final url = Uri.parse('${Environment.apiUrlTicket}/messages/create'); // final url = Uri.parse('${Environment.apiUrlTicket}/messages/create');
@ -398,6 +406,11 @@ class ApiService {
} else if (response.statusCode == 401) { } else if (response.statusCode == 401) {
await _clearLocalStorageAndRedirect(); await _clearLocalStorageAndRedirect();
return {}; return {};
} else if (response.statusCode == 429) {
final body = jsonDecode(response.body);
final message = body['message'];
ToastHelper.showWarningToast(context, message);
return {};
} else { } else {
throw Exception('Failed to load data'); throw Exception('Failed to load data');
} }

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,9 @@ class _changePinState extends State<changePin> {
dynamic empEmailid; dynamic empEmailid;
dynamic _token; dynamic _token;
dynamic emp_status; dynamic emp_status;
bool _isSaving = false;
bool _isPinChanged = false; // hard success lock
@override @override
void initState(){ void initState(){
@ -53,6 +56,14 @@ class _changePinState extends State<changePin> {
} }
Future<void> setChangePin() async { Future<void> setChangePin() async {
if (_isSaving || _isPinChanged) return;
if (!_formKey.currentState!.validate()) return;
setState(() {
_isSaving = true;
});
try { try {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
@ -87,6 +98,9 @@ class _changePinState extends State<changePin> {
bool pinVerification = data['data']['mpin_verification']; bool pinVerification = data['data']['mpin_verification'];
String message = data['data']['message']; String message = data['data']['message'];
if (pinVerification) { if (pinVerification) {
setState(() {
_isPinChanged = true;
});
ToastHelper.showSuccessToast(context, message); ToastHelper.showSuccessToast(context, message);
context.go('/profile'); context.go('/profile');
} else { } else {
@ -103,7 +117,14 @@ class _changePinState extends State<changePin> {
} catch (e) { } catch (e) {
ToastHelper.showErrorToast(context, 'Something went wrong'); ToastHelper.showErrorToast(context, 'Something went wrong');
print('Error: $e'); print('Error: $e');
} finally {
if (mounted) {
setState(() {
_isSaving = false;
});
}
} }
} }
String? _validatePin(String? value) { String? _validatePin(String? value) {
@ -343,6 +364,7 @@ class _changePinState extends State<changePin> {
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 0), horizontal: 0),
child: Pinput( child: Pinput(
enabled: !_isSaving && !_isPinChanged,
length: 4, length: 4,
defaultPinTheme: defaultPinTheme:
defaultPinTheme, defaultPinTheme,
@ -445,6 +467,7 @@ class _changePinState extends State<changePin> {
: EdgeInsets.symmetric( : EdgeInsets.symmetric(
horizontal: 0), horizontal: 0),
child: Pinput( child: Pinput(
enabled: !_isSaving && !_isPinChanged,
length: 4, length: 4,
defaultPinTheme: defaultPinTheme:
defaultPinTheme, defaultPinTheme,
@ -533,15 +556,23 @@ class _changePinState extends State<changePin> {
.circular(10), .circular(10),
), ),
), ),
onPressed: () async { onPressed: (_isSaving || _isPinChanged)
? null
: () {
setChangePin(); setChangePin();
}, },
child: Text( child: _isSaving
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: Text(
"Save", "Save",
style: style: GoogleFonts.poppins(color: Colors.white),
GoogleFonts.poppins(
color: Color(
0xFFFFFFFF)),
), ),
), ),
), ),

View File

@ -35,6 +35,8 @@ class _pinSettingPageState extends State<pinSettingPage> {
dynamic _postToken; dynamic _postToken;
dynamic emp_status; dynamic emp_status;
final session = SessionManager(); final session = SessionManager();
bool _isSavingPin = false;
bool _isPinSaved = false; // hard success lock
@override @override
void initState() { void initState() {
@ -49,6 +51,11 @@ class _pinSettingPageState extends State<pinSettingPage> {
} }
Future<void> setLoginPin(skipOrNot) async { Future<void> setLoginPin(skipOrNot) async {
if (_isSavingPin || _isPinSaved) return;
setState(() {
_isSavingPin = true;
});
try { try {
print('setLoginPin'); print('setLoginPin');
// Only validate if not skipping // Only validate if not skipping
@ -63,7 +70,7 @@ class _pinSettingPageState extends State<pinSettingPage> {
print('setLoginPin112233 $skipOrNot'); print('setLoginPin112233 $skipOrNot');
prefs.setString('is_mpin_skipped', skipOrNot.toString()); prefs.setString('is_mpin_skipped', skipOrNot.toString());
print('setLoginPin112233'); print('setLoginPin112233');
emp_status = session.emp_status; // emp_status = session.emp_status;
enrollToken = await TokenService.getPreToken(); enrollToken = await TokenService.getPreToken();
_postToken = await TokenService.getPostToken(); _postToken = await TokenService.getPostToken();
String pin = _pinController.text; String pin = _pinController.text;
@ -126,6 +133,10 @@ class _pinSettingPageState extends State<pinSettingPage> {
bool userVerification = data['data']['user_verification']; bool userVerification = data['data']['user_verification'];
String message = data['data']['message']; String message = data['data']['message'];
if (userVerification) { if (userVerification) {
setState(() {
_isPinSaved = true; // 🔒 HARD LOCK
});
if (_enableBiometric == true) { if (_enableBiometric == true) {
await _authService.saveBiometricEnableKey(_enableBiometric); await _authService.saveBiometricEnableKey(_enableBiometric);
bool biometricEnabled = bool biometricEnabled =
@ -163,7 +174,15 @@ class _pinSettingPageState extends State<pinSettingPage> {
} catch (e) { } catch (e) {
ToastHelper.showErrorToast(context, 'Something went wrong'); ToastHelper.showErrorToast(context, 'Something went wrong');
print('Error: $e'); print('Error: $e');
} finally {
if (mounted) {
setState(() {
_isSavingPin = false;
});
}
} }
} }
String? _validatePin(String? value) { String? _validatePin(String? value) {
@ -424,6 +443,7 @@ class _pinSettingPageState extends State<pinSettingPage> {
EdgeInsets.symmetric( EdgeInsets.symmetric(
horizontal: 0), horizontal: 0),
child: Pinput( child: Pinput(
enabled: !_isSavingPin && !_isPinSaved,
length: 4, length: 4,
defaultPinTheme: defaultPinTheme:
defaultPinTheme, defaultPinTheme,
@ -539,6 +559,7 @@ class _pinSettingPageState extends State<pinSettingPage> {
: EdgeInsets.symmetric( : EdgeInsets.symmetric(
horizontal: 0), horizontal: 0),
child: Pinput( child: Pinput(
enabled: !_isSavingPin && !_isPinSaved,
length: 4, length: 4,
defaultPinTheme: defaultPinTheme:
defaultPinTheme, defaultPinTheme,
@ -687,15 +708,23 @@ class _pinSettingPageState extends State<pinSettingPage> {
10), 10),
), ),
), ),
onPressed: () async { onPressed: (_isSavingPin || _isPinSaved)
? null
: () {
setLoginPin(0); setLoginPin(0);
}, },
child: Text( child: _isSavingPin
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: Text(
"Save", "Save",
style: GoogleFonts style: GoogleFonts.poppins(color: Colors.white),
.poppins(
color: Color(
0xFFFFFFFF)),
), ),
), ),
), ),
@ -708,20 +737,18 @@ class _pinSettingPageState extends State<pinSettingPage> {
.center, .center,
children: [ children: [
GestureDetector( GestureDetector(
onTap: () { onTap: (_isSavingPin || _isPinSaved)
// setSkipStatus(); ? null
: () {
setLoginPin(1); setLoginPin(1);
}, },
child: Text( child: Text(
'Skip ?', 'Skip ?',
style: GoogleFonts style: GoogleFonts.poppins(
.poppins(
fontSize: 12, fontSize: 12,
color: Color( color: (_isSavingPin || _isPinSaved)
0xFF929292), ? Colors.grey
fontWeight: : const Color(0xFF929292),
FontWeight
.w400,
), ),
), ),
), ),

View File

@ -17,8 +17,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
#version: 1.0.32+32 #version: 1.0.32+32
version: 1.0.28+33 version: 1.0.29+34
#version: 2.0.15+53 #version: 2.0.16+54
environment: environment:
sdk: '>=3.3.3 <4.0.0' sdk: '>=3.3.3 <4.0.0'