diff --git a/lib/common/settings.dart b/lib/common/settings.dart index 5729e6f..482a55e 100644 --- a/lib/common/settings.dart +++ b/lib/common/settings.dart @@ -80,6 +80,10 @@ class AppSettings{ static String host = 'http://armintaaqua.com:3000/api/'; static String loginUrl = host + 'supplierlogin'; + static String forgotPasswordUrl = host + 'forgotpassword'; + static String resetTokenUrl = host + 'reset_token'; + static String verifyPhnUrl = host + 'phone'; + // Shared preferences save,get and clear data static saveData(String _key, _value, type) async { @@ -136,6 +140,19 @@ class AppSettings{ return false; } + static Future> buildRequestHeaders() async { + Map _headers = new Map(); + _headers[HttpHeaders.contentTypeHeader] = 'application/json'; + _headers['Authorization'] = accessToken; + return _headers; + } + + static Future> + buildPutRequestHeadersForResetToken() async { + Map _headers = new Map(); + return _headers; + } + /*Apis Starts here*/ static Future login(payload) async { @@ -163,6 +180,86 @@ class AppSettings{ return false; } } + + static Future resetToken() async { + var uri = Uri.parse(resetTokenUrl + '/' + customerId); + + try { + // var response = await http.get(uri, headers: await buildPutRequestHeaders()); + var response = await http.get(uri, + headers: await buildPutRequestHeadersForResetToken()); + if (response.statusCode == 200) { + print(response.body); + var res = jsonDecode(response.body); + print(res); + + accessToken = res['access_token']; + return true; + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } + + static Future getOtp(payload) async { + var uri = Uri.parse(forgotPasswordUrl); + var response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + + if (response.statusCode == 200) { + try { + var _response = json.decode(response.body); + print(_response); + return true; + } catch (e) { + // display error toast + return false; + } + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + + static Future verifyPhn(payload) async { + var response = await http.post(Uri.parse(verifyPhnUrl), + body: json.encode(payload), + headers: {'Content-type': 'application/json'}); + + if (response.statusCode == 200) { + try { + var _response = json.decode(response.body); + print(_response); + if (_response['armintatankdata']['error'] == false) { + return true; + } else { + return false; + } + } catch (e) { + // display error toast + return false; + } + } else { + return false; + } + } + + /*Apis ends here*/ //save data local diff --git a/lib/login/login.dart b/lib/login/login.dart index 4c0a0e9..1cdc85c 100644 --- a/lib/login/login.dart +++ b/lib/login/login.dart @@ -61,7 +61,6 @@ class _LoginState extends State { CircleAvatar(radius: 80, backgroundColor: Color(0XFFF3F1FB)), SizedBox(height: MediaQuery.of(context).size.height * .05), - SizedBox(height:MediaQuery.of(context).size.height * .04,), SizedBox(height:MediaQuery.of(context).size.height * .024,), Container( child: TextFormField( diff --git a/lib/login/login_signup_screen.dart b/lib/login/login_signup_screen.dart index 8c1cb77..850f3c0 100644 --- a/lib/login/login_signup_screen.dart +++ b/lib/login/login_signup_screen.dart @@ -3,6 +3,8 @@ import 'package:supplier_new/common/settings.dart'; import 'package:supplier_new/login/login.dart'; import 'package:supplier_new/signup/signup.dart'; +import '../signup/signup_mobilenumber_screen.dart'; + class LoginSignUpScreen extends StatefulWidget { const LoginSignUpScreen({super.key}); @@ -39,8 +41,7 @@ class _LoginSignUpScreenState extends State { style: fontTextStyle(12, Color(0XFF7E7F80), FontWeight.w400), textAlign: TextAlign.center, // Keeps text centered in multiple lines ), - ) - , + ), SizedBox(height: MediaQuery.of(context).size.height * .04), Container( width:double.infinity, @@ -82,7 +83,7 @@ class _LoginSignUpScreenState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => SignUp()), + builder: (context) => SignUpMobileNumberScreen()), ); }, child: Text( diff --git a/lib/signup/otp_screen.dart b/lib/signup/otp_screen.dart new file mode 100644 index 0000000..3f6f7c7 --- /dev/null +++ b/lib/signup/otp_screen.dart @@ -0,0 +1,180 @@ +import 'package:flutter/material.dart'; +import 'package:supplier_new/signup/password_textbox_screen.dart'; + +import '../common/settings.dart'; + +class Otpscreen extends StatefulWidget { + var mobileNumber; + Otpscreen({ + this.mobileNumber + }); + + @override + State createState() => _OtpscreenState(); +} + +class _OtpscreenState extends State { + final List _controllers = List.generate(6, (index) => TextEditingController()); + final FocusNode _focusNode = FocusNode(); + + @override + void dispose() { + _controllers.forEach((controller) => controller.dispose()); + _focusNode.dispose(); + super.dispose(); + } + + void _submitOtp() { + final otp = _controllers.map((controller) => controller.text).join(); + print("Entered OTP: $otp"); + // Add OTP validation or submission logic here + } + + + String maskMobileNumber(String number) { + if (number.length < 3) return number; // Handle invalid numbers + final stars = '*' * (number.length - 3); + final lastThree = number.substring(number.length - 3); + return '$stars$lastThree'; + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack(children: [ + /*Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage("images/backgroundimage.png"), + fit: BoxFit.cover, + ), + ), + ),*/ + GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(new FocusNode()); + }, + child: SafeArea( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.fromLTRB(24, 0, 24, 0), + child: Column(children: [ + SizedBox(height:MediaQuery.of(context).size.height * .2,), + + Container( + + child: Text( + 'Enter confirmation code', + style: fontTextStyle(16,Color(0XFF101214),FontWeight.w800), + ), + ), + SizedBox(height:MediaQuery.of(context).size.height * .02,), + Container( + + child: Text( + 'A 6-digit code was sent to +91${maskMobileNumber(widget.mobileNumber)}', + style: fontTextStyle(12,Color(0XFF7E7F80),FontWeight.w400), + ), + ), + SizedBox(height:MediaQuery.of(context).size.height * .040,), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate(6, (index) { + return SizedBox( + width: 50, + child: TextFormField( + cursorColor:Color(0XFF1D7AFC), + controller: _controllers[index], + focusNode: index == 0 ? _focusNode : null, + maxLength: 1, + textAlign: TextAlign.center, + style: fontTextStyle(14,Color(0XFF101214),FontWeight.w400), + keyboardType: TextInputType.number, + decoration: textFormFieldDecoration(Icons.ice_skating, ''), + onChanged: (value) { + if (value.isNotEmpty && index < 5) { + FocusScope.of(context).nextFocus(); + } else if (value.isEmpty && index > 0) { + FocusScope.of(context).previousFocus(); + } + }, + ), + ); + }), + ), + + SizedBox(height:MediaQuery.of(context).size.height * .08,), + GestureDetector( + onTap: (){ + + }, + child: Text('Resend code',style:fontTextStyle(12,Color(0XFF1D7AFC),FontWeight.w600),), + ), + SizedBox(height:MediaQuery.of(context).size.height * .024,), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * .06, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: primaryColor, + ), + onPressed: () async{ + AppSettings.preLoaderDialog(context); + + bool isOnline = await AppSettings.internetConnectivity(); + if(isOnline){ + final otp = _controllers.map((controller) => controller.text).join(); + + if(otp.length==6){ + var phoneVerifyPayload = new Map(); + + phoneVerifyPayload["phoneVerificationCode"] = otp.toString(); + phoneVerifyPayload["phone"] = widget.mobileNumber.toString(); + + bool verifyPhnStatus = await AppSettings.verifyPhn(phoneVerifyPayload); + if (verifyPhnStatus) { + Navigator.of(context, rootNavigator: true).pop(); + //AppSettings.longSuccessToast("User SignUp Successfully"); + Navigator.push( + context, + new MaterialPageRoute( + builder: (__) => new PasswordTextBoxesScreen())); + /* await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const Login()), + );*/ + + } else { + Navigator.of(context, rootNavigator: true).pop(); + AppSettings.longFailedToast("Phone verification failed"); + } + } + else{ + Navigator.of(context, rootNavigator: true).pop(); + AppSettings.longFailedToast("Please enter 6 digit otp code"); + } + + + } + else{ + Navigator.of(context,rootNavigator: true).pop(); + AppSettings.longFailedToast("Please Check internet"); + } + + + + + + + }, + child: Text('Continue',style:fontTextStyle(12,Color(0XFFFFFFFF),FontWeight.w600),), + )), + + ]), + )))), + ])); + } +} diff --git a/lib/signup/password_textbox_screen.dart b/lib/signup/password_textbox_screen.dart new file mode 100644 index 0000000..ab7120a --- /dev/null +++ b/lib/signup/password_textbox_screen.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class PasswordTextBoxesScreen extends StatefulWidget { + const PasswordTextBoxesScreen({super.key}); + + @override + State createState() => _PasswordTextBoxesScreenState(); +} + +class _PasswordTextBoxesScreenState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/lib/signup/signup_mobilenumber_screen.dart b/lib/signup/signup_mobilenumber_screen.dart index e69de29..661c7b0 100644 --- a/lib/signup/signup_mobilenumber_screen.dart +++ b/lib/signup/signup_mobilenumber_screen.dart @@ -0,0 +1,150 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:supplier_new/common/settings.dart'; +import 'package:supplier_new/login/login_signup_screen.dart'; + +import 'otp_screen.dart'; + +class SignUpMobileNumberScreen extends StatefulWidget { + const SignUpMobileNumberScreen({super.key}); + + @override + State createState() => _SignUpMobileNumberScreenState(); +} + +class _SignUpMobileNumberScreenState extends State { + TextEditingController mobileNumberController = TextEditingController(); + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: Colors.white, + body: Padding( + padding: EdgeInsets.all(24), + child: Column( + children: [ + SizedBox(height: MediaQuery.of(context).size.height * .2), + Center( + child: Text("AQUICK SUPPLIER", + style: fontTextStyle(20, Color(0XFF515253), FontWeight.w800)), + ), + SizedBox(height: MediaQuery.of(context).size.height * .05), + CircleAvatar(radius: 80, backgroundColor: Color(0XFFF3F1FB)), + SizedBox(height: MediaQuery.of(context).size.height * .05), + Center( + child: Text( + "Welcome to Aquick Supplier", + style: fontTextStyle(20, Color(0XFF343637), FontWeight.w700), + ), + ), + SizedBox(height: MediaQuery.of(context).size.height * .004), + Center( + child: Text( + "Sign up to be listed as a supplier, start deliveries and track orders", + style: fontTextStyle(12, Color(0XFF7E7F80), FontWeight.w400), + textAlign: TextAlign.center, // Keeps text centered in multiple lines + ), + ), + SizedBox(height:MediaQuery.of(context).size.height * .016,), + Container( + child: TextFormField( + controller: mobileNumberController, + keyboardType: TextInputType.number, + textCapitalization: TextCapitalization.sentences, + maxLength: 10, + decoration: textFormFieldDecoration(Icons.phone,'Mobile Number'), + style:fontTextStyle(14,Color(0XFF2A2A2A),FontWeight.w400), + cursorColor: Color(0XFF8270DB), + + //TextStyle(color: Colors.black,fontWeight: FontWeight.bold), + ), + ), + + SizedBox(height: MediaQuery.of(context).size.height * .04), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * .06, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: primaryColor, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(24.0), // Customize the radius + ), + ), + onPressed: () async{ + if(mobileNumberController.text.length>=10){ + + AppSettings.preLoaderDialog(context); + + bool isOnline = await AppSettings.internetConnectivity(); + if(isOnline){ + + var payload = new Map(); + payload["phone"] = mobileNumberController.text.toString(); + + bool forgotPwd = await AppSettings.getOtp(payload); + + if(forgotPwd){ + Navigator.of(context,rootNavigator: true).pop(); + Navigator.push( + context, + new MaterialPageRoute( + builder: (__) => new Otpscreen(mobileNumber:mobileNumberController.text.toString()))); + + } + else{ + AppSettings.longFailedToast('Please enter valid registered mobile number'); + } + } + else{ + Navigator.of(context,rootNavigator: true).pop(); + AppSettings.longFailedToast("Please Check internet"); + } + + + + } + else{ + AppSettings.longFailedToast('Please enter 10 digits of mobile number'); + } + + }, + child: Text( + 'Continue', + style: fontTextStyle(14, Color(0XFFFFFFFF), FontWeight.w600), + ), + )), + SizedBox(height: MediaQuery.of(context).size.height * .012), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * .06, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Color(0XFF757575), + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(24.0), // Customize the radius + side: BorderSide( + color: Color(0XFF757575), // Border color + width: 1, // Border width + ), + ), + ), + onPressed: () async { + // Your onPressed logic + }, + child: Text( + 'Back', + style: fontTextStyle(14, Color(0XFF646566), FontWeight.w500), + ), + ), + ) + ], + ), + )); + } +}