import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; import 'package:nhance_app_pwa/pages/verify.dart'; import 'dart:convert'; import 'dart:io'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:google_fonts/google_fonts.dart'; import '../customAppBar/responsive.dart'; import '../customAppBar/toastHelper.dart'; import '../models/environment.dart'; import '../models/platform_helper_mobile.dart' if (dart.library.html) '../models/platform_helper_other.dart'; class login extends StatefulWidget { const login({Key? key}); @override State createState() => _loginState(); } class _loginState extends State { TextEditingController countryController = TextEditingController(); TextEditingController mobileController = TextEditingController(); final _formKey = GlobalKey(); bool _isCheckingToken = false; dynamic empMobileNo; final FirebaseAuth _auth = FirebaseAuth.instance; late String _verificationId; int? _resendToken; bool _isLoading = false; @override void initState() { countryController.text = "+91"; super.initState(); checkLoginPinOnMobile(); } void checkLoginPinOnMobile() { if (isMobilePlatform()) { checkLoginPin(context); } } Future checkLoginPin(BuildContext context) async { print('checkLoginPin'); try { final SharedPreferences prefs = await SharedPreferences.getInstance(); empMobileNo = prefs.getString('empMobileNo'); // _token = prefs.getString('token'); final response = await http.post( Uri.parse(Environment.apiUrl + 'checkMpin'), body: json.encode({'mobile_number': empMobileNo}), headers: { HttpHeaders.contentTypeHeader: 'application/json', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { print('data'); prefs.setString('mpinText', data['data']); prefs.setString('mpin', data['Mpin']); Navigator.pushReplacementNamed(context, 'pinPage'); } } else { ToastHelper.showErrorToast(context, 'Something went wrong'); throw Exception('Failed to verify pin number'); } } catch (e) { ToastHelper.showErrorToast(context, 'Something went wrong'); print('Error: $e'); } } Future verifyMobileNumber() async { try { if (_formKey.currentState!.validate()) { setState(() { _isLoading = true; }); var enteredMobileNumber = mobileController.text; final response = await http.post( Uri.parse(Environment.apiUrl + 'verifyEmployeeNumber'), body: json.encode({'mobile_number': enteredMobileNumber}), headers: { HttpHeaders.contentTypeHeader: 'application/json', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); bool userVerification = data['data']['user_verification']; String message = data['data']['message']; if (userVerification) { final SharedPreferences prefs = await SharedPreferences.getInstance(); var enteredMobileNumber = mobileController.text; prefs.setString('empMobileNo', enteredMobileNumber); _verifyPhoneNumber(); // ToastHelper.showSuccessToast(context, message); } else { setState(() { _isLoading = false; }); ToastHelper.showErrorToast(context, message); print('Invalid mobile number'); } } else { setState(() { _isLoading = false; }); ToastHelper.showErrorToast(context, 'Something went wrong'); throw Exception('Failed to verify mobile number'); } } } catch (e) { setState(() { _isLoading = false; }); ToastHelper.showErrorToast(context, 'Something went wrong'); print('Error: $e'); } } Future _verifyPhoneNumber() async { var enteredMobileNumber = mobileController.text; var countryCode = countryController.text; print('${countryCode + enteredMobileNumber}'); await _auth.verifyPhoneNumber( phoneNumber: '${countryCode + enteredMobileNumber}', timeout: const Duration(seconds: 60), verificationCompleted: (PhoneAuthCredential credential) async { await _auth.signInWithCredential(credential); // ToastHelper.showSuccessToast(context, 'Verified Successfully!'); // setState(() { // _isLoading = false; // }); }, verificationFailed: (FirebaseAuthException e) { ToastHelper.showSuccessToast(context, 'Verification Failed!'); if (e.code == 'invalid-phone-number') { print('The provided phone number is not valid.'); } setState(() { _isLoading = false; }); }, codeSent: (String verificationId, int? resendToken) { setState(() { _verificationId = verificationId; _resendToken = resendToken; }); ToastHelper.showSuccessToast( context, 'Verification code sent to ${enteredMobileNumber}'); Navigator.push( context, MaterialPageRoute( builder: (context) => MyVerify( verificationId: _verificationId, mobileNumber: enteredMobileNumber, resendToken: _resendToken, onResendCode: _resendCode, // Pass the phone number ), ), ); setState(() { _isLoading = false; }); }, codeAutoRetrievalTimeout: (String verificationId) { setState(() { _verificationId = verificationId; }); ToastHelper.showSuccessToast(context, 'Code auto-retrieval timed out.'); setState(() { _isLoading = false; }); }, ); } void _resendCode(String mobileNumber, int? resendToken) async { await _auth.verifyPhoneNumber( phoneNumber: '${countryController.text + mobileNumber}', timeout: const Duration(seconds: 60), forceResendingToken: resendToken, verificationCompleted: (PhoneAuthCredential credential) async { await _auth.signInWithCredential(credential); }, verificationFailed: (FirebaseAuthException e) { if (e.code == 'invalid-phone-number') { print('The provided phone number is not valid.'); } }, codeSent: (String verificationId, int? resendToken) { setState(() { _verificationId = verificationId; _resendToken = resendToken; }); ToastHelper.showSuccessToast( context, 'Verification code resent to ${mobileNumber}'); Navigator.push( context, MaterialPageRoute( builder: (context) => MyVerify( verificationId: _verificationId, mobileNumber: mobileNumber, resendToken: _resendToken, onResendCode: _resendCode, ), ), ); }, codeAutoRetrievalTimeout: (String verificationId) { setState(() { _verificationId = verificationId; }); }, ); } @override Widget build(BuildContext context) { Size _size = MediaQuery.of(context).size; EdgeInsets marginInsets = EdgeInsets.zero; if (Responsive.isDesktop(context)) { marginInsets = const EdgeInsets.only( left: 0, right: 0, bottom: 0, top: 0, ); } else if (Responsive.isMobile(context)) { marginInsets = const EdgeInsets.only( left: 25, // Example value for mobile right: 25, // Example value for mobile bottom: 0, // Example value for mobile top: 0, // Example value for mobile ); } else if (Responsive.isTablet(context)) { marginInsets = const EdgeInsets.only( left: 25, //// Example value for mobile right: 25, // Example value for mobile bottom: 0, // Example value for mobile top: 0, // Example value for mobile ); } return WillPopScope( onWillPop: () async { // Close the app on mobile back button press exit(0); // This will exit the app return false; // Return false to prevent any other actions }, child: Scaffold( body: SingleChildScrollView( keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, child: Container( height: _size.height, color: Colors.white, child: Stack( children: [ Visibility( visible: _size.width <= 1100, child: ClipRRect( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30), ), child: Container( height: _size.height / 3, width: double.infinity, color: Color(0xFFFFFCE5), child: Stack( children: [ Column( children: [ SizedBox( height: _size.height / 6.4), // Adjust the spacing between the rows Row( mainAxisAlignment: MainAxisAlignment .center, // Align to the center children: [ Expanded( flex: Responsive.isDesktop(context) ? 10 : 12, child: Align( alignment: Responsive.isDesktop(context) ? Alignment.centerLeft : Alignment.bottomCenter, child: Image.asset( 'assets/nhance_app_logo.png', width: 150, height: 150, )), ), if (!Responsive.isMobile(context) && !Responsive.isTablet(context)) Expanded( flex: 2, child: MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( onTap: () { // Add your navigation logic here // For example, you can use Navigator.push to navigate to another page Navigator.pushNamed( context, 'hrLogin'); }, child: Row( mainAxisAlignment: MainAxisAlignment .end, // Align to the end (right) children: [ Text( 'HR Login', style: TextStyle( color: Color( 0xFF000000), // Text color // Add other text styles as needed ), ), SizedBox(width: 5), Icon( Icons .east, // Icon for customer login color: Colors .black, // Adjust color as needed ), ], ), ), ), ), ], ), ], ), ], ), ), ), ), Container( margin: marginInsets, alignment: Alignment.bottomCenter, child: SingleChildScrollView( child: Form( key: _formKey, child: Column( children: [ Row( children: [ Expanded( flex: _size.width < 1100 ? 6 : 12, child: Container( margin: _size.width > 1100 ? EdgeInsets.only(left: 20, right: 20) : EdgeInsets.only(left: 0, right: 0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if (!Responsive.isMobile(context) && !Responsive.isTablet(context)) Row( children: [ Expanded( flex: 12, child: Align( alignment: Responsive .isDesktop(context) ? Alignment.centerLeft : Alignment .bottomCenter, // Align to the start child: _size.width <= 1100 ? Image.asset( 'assets/nhance_app_logo.png', width: 150, height: 150, ) : _size.width > 1100 ? Image.asset( 'assets/nhance_app_logo.png', width: 150, height: 150, ) : Image.asset( 'assets/nhance_app_logo.png', width: 150, height: 150, ), )), ], ), SizedBox(height: 10), Container( margin: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: 150) : EdgeInsets.symmetric( horizontal: 0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Welcome to Nhance", style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), ), SizedBox( height: 10, ), Container( margin: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: 150) : EdgeInsets.symmetric( horizontal: 0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Text( "Login with your mobile number and OTP to review and enroll for exciting health benefits for you and your family", style: GoogleFonts.poppins( fontSize: 12, color: Color(0xFF000000)), textAlign: TextAlign.center, ), ) ], ), ), SizedBox( height: 20, ), Container( height: 55, margin: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: 150) : EdgeInsets.symmetric( horizontal: 0), decoration: BoxDecoration( border: Border.all( width: 1, color: Colors.grey), borderRadius: BorderRadius.circular(10), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 10, ), SizedBox( width: 40, child: TextField( controller: countryController, keyboardType: TextInputType.number, decoration: InputDecoration( border: InputBorder.none, ), ), ), Text( "|", style: TextStyle( fontSize: 33, color: Colors.grey), ), SizedBox( width: 10, ), Expanded( child: TextFormField( controller: mobileController, keyboardType: TextInputType.phone, decoration: InputDecoration( border: InputBorder.none, hintText: "Enter your mobile number", ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your mobile number'; } if (value.length != 10) { return 'Mobile number must be 10 digits'; } return null; }, inputFormatters: [ FilteringTextInputFormatter .digitsOnly, LengthLimitingTextInputFormatter( 10), ], ), ), ], ), ), SizedBox( height: 20, ), Container( margin: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: 150) : EdgeInsets.symmetric( horizontal: 0), child: SizedBox( width: double.infinity, height: 45, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF00989E), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: _isLoading ? null : verifyMobileNumber, child: _isLoading ? CircularProgressIndicator( valueColor: AlwaysStoppedAnimation< Color>( Color( 0xFF00989E)), ) : Text( "Login With OTP", style: GoogleFonts.poppins( color: Color( 0xFFFFFFFF)), ), ), ), ), SizedBox( height: _size.width <= 1100 ? 0 : 0, ), _size.width > 1100 ? Container( margin: EdgeInsets.symmetric( horizontal: 150), child: Column( children: [ SizedBox(height: 30), Text( "Benefits of Login", style: GoogleFonts.poppins( fontSize: 20, fontWeight: FontWeight.bold, ), ), SizedBox(height: 15), ], )) : SizedBox(), _size.width > 1100 ? Container( margin: EdgeInsets.symmetric( horizontal: 150), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( flex: 6, child: Container( padding: EdgeInsets .symmetric( vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment .center, children: [ Expanded( child: Container( padding: EdgeInsets .symmetric( vertical: 12), decoration: BoxDecoration( border: Border( right: BorderSide( width: 1, color: Colors .black, ), ), ), child: Column( children: [ Icon( Icons .policy, color: Color( 0xFFE26728)), SizedBox( height: 10), Text( "View Policy"), ], ), ), ), Expanded( child: Container( padding: EdgeInsets .symmetric( vertical: 12), child: Column( children: [ Icon( Icons .edit, color: Color( 0xFFE26728)), SizedBox( height: 10), Text( "Manage Claims"), ], ), ), ), ], ), ), ), ], ), ) : SizedBox( height: Responsive.isDesktop( context) ? _size.height * 0.1 : _size.height * 0.2, ), SizedBox( height: _size.height * 0.1, ), Container( alignment: Alignment.bottomCenter, padding: EdgeInsets.symmetric(vertical: 8), child: RichText( textAlign: TextAlign.center, text: TextSpan( text: 'By continuing, you agree with our ', style: GoogleFonts.poppins( color: Colors.black, fontSize: 9, ), children: [ WidgetSpan( child: MouseRegion( cursor: SystemMouseCursors .click, child: GestureDetector( onTap: () { Navigator.pushNamed( context, 'privacypolicy'); }, child: Text( 'privacy policy ', style: GoogleFonts.poppins( color: Color(0xFF00989E), fontSize: 9, decoration: TextDecoration .underline, ), ), ), ), ), TextSpan( text: 'and ', style: GoogleFonts.poppins( color: Colors.black, fontSize: 9, ), ), WidgetSpan( child: MouseRegion( cursor: SystemMouseCursors .click, child: GestureDetector( onTap: () { Navigator.pushNamed( context, 'termsofuse'); }, child: Text( 'terms of use', style: GoogleFonts.poppins( color: Color(0xFF00989E), fontSize: 9, decoration: TextDecoration .underline, ), ), ), ), ), ], ), ), ), ], ), ), ), if (_size.width > 1100) Expanded( flex: _size.width < 1100 ? 6 : 12, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { if (constraints.maxWidth > 600) { return Image.asset( 'assets/login_web.jpg', height: _size.height, fit: BoxFit.cover, ); } else { return SizedBox(); } }, ), ), ], ), ], ), ), ), ), ], )), ))); } }