From 41b84dd33972504b7d85c3e8a2fbdb0e97c07f94 Mon Sep 17 00:00:00 2001 From: treav Date: Wed, 20 Jan 2021 08:57:26 +0530 Subject: [PATCH 01/19] . --- pubspec.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 3ed6dc2..adca9e1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" + version: "2.5.0-nullsafety.3" bloc: dependency: "direct main" description: @@ -21,35 +21,35 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.5" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" + version: "1.15.0-nullsafety.5" cupertino_icons: dependency: "direct main" description: @@ -70,7 +70,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" flutter: dependency: "direct main" description: flutter @@ -94,14 +94,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10-nullsafety.3" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.6" nested: dependency: transitive description: @@ -115,7 +115,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" + version: "1.8.0-nullsafety.3" provider: dependency: transitive description: @@ -134,56 +134,56 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" + version: "1.8.0-nullsafety.4" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.6" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19-nullsafety.6" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.5" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.5" sdks: - dart: ">=2.10.0-110 <2.11.0" + dart: ">=2.12.0-0.0 <3.0.0" flutter: ">=1.16.0" From 8bf760ab9c9f4e3f59722e465b00caf543928d36 Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 4 Mar 2021 18:28:44 +0530 Subject: [PATCH 02/19] Staging Changes --- lib/core/res/strings.dart | 15 +++ .../forgot_password_repository.dart | 116 +++++++++++++++++- 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/lib/core/res/strings.dart b/lib/core/res/strings.dart index 45e74b4..b8b009e 100644 --- a/lib/core/res/strings.dart +++ b/lib/core/res/strings.dart @@ -10,6 +10,19 @@ class S { static const String getSponsorsUrl = baseUrl + "sponsors/sorted_list/$sponsorApiYear/"; static const String getSpeakerUrl = baseUrl + "speakers/full_list/"; static const String postFeedbackUrl = baseUrl + "feedback/post/"; + + ///Change password API is where the email, otp and password is posted and password is changed + /// Accepts [Email] [Otp] and [Password] in API. Last Stage + static const String postChangePasswordUrl = baseUrl + "users/change_password/"; + + ///Forgot Password API where the email is posted and OTP is sent to the user. + ///Accept [Email] only as a parameter to the API. First Stage + static const String postForgotPasswordUrl = baseUrl + "users/forgot_password/"; + + ///After change mail, send request to this API to verify new email id. + ///Accepts [Email] and [Otp]. Second Stage + static const String postCheckOtpUrl = baseUrl + "users/check_otp/"; + // shared preferences keys static const String tokenKeySharedPreferences = "token"; static const String nameKeySharedPreferences = "name"; @@ -21,6 +34,8 @@ class S { static const String firstnameKey = "first_name"; static const String lastnameKey = "last_name"; static const String phoneKey = "contact"; + static const String otpKey = "otp"; + //postfeedback static const String feedbackNameKey = "name"; static const String feedbackMessageKey = "message"; diff --git a/lib/screens/forgot_password/forgot_password_repository.dart b/lib/screens/forgot_password/forgot_password_repository.dart index 673078f..15cef81 100644 --- a/lib/screens/forgot_password/forgot_password_repository.dart +++ b/lib/screens/forgot_password/forgot_password_repository.dart @@ -1,5 +1,9 @@ +import 'dart:convert'; import 'dart:math'; - +import 'package:ecellapp/core/res/strings.dart'; +import 'package:ecellapp/core/utils/injection.dart'; +import 'package:ecellapp/core/utils/logger.dart'; +import 'package:http/http.dart' as http; import 'package:ecellapp/core/res/errors.dart'; abstract class ForgotPasswordRepository { @@ -56,3 +60,113 @@ class FakeForgotPasswordRepository extends ForgotPasswordRepository { } } } + +class APIForgotPasswordRepository extends ForgotPasswordRepository { + final String classTag = "APIForgotPasswordRepository"; + + ///Send [Email] [OTP] [Passoword] + @override + Future changePassword(String email, String otp, String password) async { + final String tag = classTag + "changePassword"; + http.Response response; + try { + response = await sl.get().post( + S.postChangePasswordUrl, + body: {S.emailKey: email, S.otpKey: otp, S.passwordKey: password}, + ); + } catch (e) { + Log.e(tag: tag, message: "NetworkError:" + e.toString()); + throw NetworkException(); + } + + if (response.statusCode == 202) { + try { + String changePasswordResponse = json.decode(response.body)["detail"]; + return; + } catch (e) { + Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); + throw UnknownException(); + } + } else if (response.statusCode == 400) { + throw ValidationException(response.body); + } else if (response.statusCode == 401 || response.statusCode == 404) { + throw ResponseException(jsonDecode(response.body)['detail']); + } else { + Log.e( + tag: tag, + message: "Unknown response code -> ${response.statusCode}, message ->" + response.body); + throw UnknownException(); + } + } + + ///Send [Email] [OTP] + @override + Future checkOTP(String otp, String email) async { + final String tag = classTag + "sendOTP"; + http.Response response; + try { + response = await sl.get().post( + S.postCheckOtpUrl, + body: {S.emailKey: email, S.otpKey: otp}, + ); + } catch (e) { + Log.e(tag: tag, message: "NetworkError:" + e.toString()); + throw NetworkException(); + } + + if (response.statusCode == 202) { + try { + String otpResponse = json.decode(response.body)["verified"]; + //TODO: Return type to bool + return otpResponse; + } catch (e) { + Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); + throw UnknownException(); + } + } else if (response.statusCode == 400) { + throw ValidationException(response.body); + } else if (response.statusCode == 401 || response.statusCode == 404) { + throw ResponseException(jsonDecode(response.body)['detail']); + } else { + Log.e( + tag: tag, + message: "Unknown response code -> ${response.statusCode}, message ->" + response.body); + throw UnknownException(); + } + } + + /// Send [Email] to server get [OTP] to phone + @override + Future sendOTP(String email) async { + final String tag = classTag + "sendOTP"; + http.Response response; + try { + response = await sl.get().post( + S.postForgotPasswordUrl, + body: {S.emailKey: email}, + ); + } catch (e) { + Log.e(tag: tag, message: "NetworkError:" + e.toString()); + throw NetworkException(); + } + + if (response.statusCode == 202) { + try { + //String otp = json.decode(response.body)["detail"]; + return; + } catch (e) { + Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); + throw UnknownException(); + } + } else if (response.statusCode == 400) { + throw ValidationException(response.body); + } else if (response.statusCode == 401 || response.statusCode == 404) { + throw ResponseException(jsonDecode(response.body)['detail']); + } else { + Log.e( + tag: tag, + message: "Unknown response code -> ${response.statusCode}, message ->" + response.body); + throw UnknownException(); + } + } +} From 03efa05b187cc5646279819b7ff8acf34d07230f Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 4 Mar 2021 18:31:33 +0530 Subject: [PATCH 03/19] pubspec.lock --- pubspec.lock | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 2c955d0..cdbbed2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -412,21 +412,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - version: "2.1.0-nullsafety.5" -sdks: - dart: ">=2.12.0-0.0 <3.0.0" - flutter: ">=1.16.0" -======= - version: "2.1.0-nullsafety.3" -======= - version: "2.1.0-nullsafety.5" ->>>>>>> 136b89a39df782d63a55f2fc5b127552381e16b4 -======= version: "2.1.0-nullsafety.3" ->>>>>>> 05b87f88beeca873b74ba23bbe5d091b1676c248 win32: dependency: transitive description: @@ -442,20 +428,5 @@ sdks: source: hosted version: "0.1.2" sdks: -<<<<<<< HEAD -<<<<<<< HEAD - dart: ">=2.10.0-110 <2.11.0" -<<<<<<< HEAD - flutter: ">=1.17.0 <2.0.0" ->>>>>>> 24cc943c75c8886ad1315291ca408d1b159130d6 -======= - flutter: ">=1.17.0 <2.0.0" ->>>>>>> 63a66ed70efb6c17625fca475468dc716766a8aa -======= - dart: ">=2.12.0-0.0 <3.0.0" - flutter: ">=1.22.0 <2.0.0" ->>>>>>> 136b89a39df782d63a55f2fc5b127552381e16b4 -======= dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.22.0 <2.0.0" ->>>>>>> 05b87f88beeca873b74ba23bbe5d091b1676c248 + flutter: ">=1.22.0 <2.0.0" \ No newline at end of file From 6bb18b703b4aa3bea2870ba539442566c46afd1a Mon Sep 17 00:00:00 2001 From: treav Date: Fri, 5 Mar 2021 05:54:10 +0530 Subject: [PATCH 04/19] Minor fix --- .../forgot_password/forgot_password_repository.dart | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/screens/forgot_password/forgot_password_repository.dart b/lib/screens/forgot_password/forgot_password_repository.dart index 15cef81..c463db8 100644 --- a/lib/screens/forgot_password/forgot_password_repository.dart +++ b/lib/screens/forgot_password/forgot_password_repository.dart @@ -64,7 +64,7 @@ class FakeForgotPasswordRepository extends ForgotPasswordRepository { class APIForgotPasswordRepository extends ForgotPasswordRepository { final String classTag = "APIForgotPasswordRepository"; - ///Send [Email] [OTP] [Passoword] + ///Send [Email] [OTP] [Passoword] Stage 3/3 @override Future changePassword(String email, String otp, String password) async { final String tag = classTag + "changePassword"; @@ -81,7 +81,6 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { if (response.statusCode == 202) { try { - String changePasswordResponse = json.decode(response.body)["detail"]; return; } catch (e) { Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); @@ -99,7 +98,7 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { } } - ///Send [Email] [OTP] + ///Send [Email] [OTP] Stage 2/3 @override Future checkOTP(String otp, String email) async { final String tag = classTag + "sendOTP"; @@ -116,9 +115,7 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { if (response.statusCode == 202) { try { - String otpResponse = json.decode(response.body)["verified"]; - //TODO: Return type to bool - return otpResponse; + return; } catch (e) { Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); throw UnknownException(); @@ -135,7 +132,7 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { } } - /// Send [Email] to server get [OTP] to phone + /// Send [Email] to server get [OTP to phone] Stage 1/3 @override Future sendOTP(String email) async { final String tag = classTag + "sendOTP"; @@ -152,7 +149,6 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { if (response.statusCode == 202) { try { - //String otp = json.decode(response.body)["detail"]; return; } catch (e) { Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); From bfdc0249ab1ad1c4fb77e2d14dfbccc588505894 Mon Sep 17 00:00:00 2001 From: treav Date: Fri, 5 Mar 2021 06:49:07 +0530 Subject: [PATCH 05/19] ForgotPassword UI staged --- lib/core/res/colors.dart | 6 + lib/core/res/strings.dart | 1 + lib/main.dart | 9 +- .../forgot_password/forgot_password.dart | 549 ++++++++++++++++-- .../widgets/confirm_password.dart | 53 ++ .../forgot_password/widgets/otp_field.dart | 31 - 6 files changed, 583 insertions(+), 66 deletions(-) create mode 100644 lib/screens/forgot_password/widgets/confirm_password.dart delete mode 100644 lib/screens/forgot_password/widgets/otp_field.dart diff --git a/lib/core/res/colors.dart b/lib/core/res/colors.dart index 1adc541..f116bd9 100644 --- a/lib/core/res/colors.dart +++ b/lib/core/res/colors.dart @@ -53,6 +53,12 @@ class C { //Speaker Card fonts static final Color cardFontColor = HexColor("#A3A3A3"); + + ///Otp ring colors + static final Color firstRing = HexColor("#2DEBFF"); + static final Color secondRing = HexColor("#FB28E6"); + static final Color thirdRing = HexColor("#EFEA79"); + static final Color fourthRing = HexColor("#AE82FF"); } class HexColor extends Color { diff --git a/lib/core/res/strings.dart b/lib/core/res/strings.dart index 45e74b4..21b4ba8 100644 --- a/lib/core/res/strings.dart +++ b/lib/core/res/strings.dart @@ -114,4 +114,5 @@ class S { static const routeEvents = "/events"; static const routeSponsors = "/sponsors"; static const routeEsummit = "/esummit"; + static const routeForgotPassword = "/forgotPassword"; } diff --git a/lib/main.dart b/lib/main.dart index 6dd9110..95f48f1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,6 @@ +import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; +import 'package:ecellapp/screens/forgot_password/forgot_password.dart'; +import 'package:ecellapp/screens/forgot_password/forgot_password_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -58,7 +61,11 @@ class ECellApp extends StatelessWidget { create: (_) => EventsCubit(FakeEventsRepository()), child: EventsScreen()), S.routeSponsors: (_) => BlocProvider( create: (_) => SponsorsCubit(APISponsorsRepository()), child: SponsorsScreen()), - S.routeEsummit: (_) => ESummitScreen() + S.routeEsummit: (_) => ESummitScreen(), + S.routeForgotPassword: (_) => BlocProvider( + create: (_) => ForgotPasswordCubit(FakeForgotPasswordRepository()), + child: ForgotPasswordScreen(), + ) }, initialRoute: S.routeSplash, title: "ECellApp", diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 2c63f4d..5e95e8b 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -1,21 +1,30 @@ +import 'package:ecellapp/core/res/colors.dart'; +import 'package:ecellapp/core/res/dimens.dart'; +import 'package:ecellapp/core/res/strings.dart'; import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; -import 'package:ecellapp/screens/forgot_password/widgets/otp_field.dart'; import 'package:ecellapp/widgets/ecell_animation.dart'; import 'package:ecellapp/widgets/email_field.dart'; import 'package:ecellapp/widgets/password_field.dart'; +import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import 'widgets/confirm_password.dart'; class ForgotPasswordScreen extends StatelessWidget { + String otp1 = "1", otp2 = "2", otp3 = "3", otp4 = "4", otpEntered = "1234"; final TextEditingController emailController = TextEditingController(); final TextEditingController otpController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmPasswordController = TextEditingController(); - + final ScrollController _scrollController = ScrollController(); + final _formKey = GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Colors.transparent, body: BlocConsumer( listener: (context, state) { if (state is ForgotPasswordError) { @@ -27,6 +36,7 @@ class ForgotPasswordScreen extends StatelessWidget { builder: (context, state) { return Stack( children: [ + ScreenBackground(elementId: 0), if (state is ForgotEmailInitial) _initialForgotPassword(context, state) else if (state is ForgotLoading) @@ -62,18 +72,160 @@ class ForgotPasswordScreen extends StatelessWidget { } } + ///Initial Forgot Password Widget _initialForgotPassword(BuildContext context, ForgotPasswordState state) { - return Padding( - padding: const EdgeInsets.all(40.0), - child: Column( + double width = MediaQuery.of(context).size.width; + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (_scrollController.hasClients) { + if (bottom > height * 0.25) { + _scrollController.animateTo( + bottom - height * 0.25, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( children: [ - Text("Enter email"), - EmailField(emailController), - FlatButton( - onPressed: () { - _sendOTP(context, state); - }, - child: Text("Press me")), + ScreenBackground(elementId: 1), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: _scrollController, + child: Container( + height: height * 1.25, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + flex: 5, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Text( + "Step 1/3", + style: + TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + )), + Flexible( + flex: 7, + child: Column( + children: [ + // Logo + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding + 1), + child: Image.asset( + S.assetEcellLogoWhite, + width: width * 0.25 * heightFactor, + ), + ), + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding, top: 20), + child: Text( + "Welcome", + style: + TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + //Text Greeting + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding, top: 5), + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: "Forgot your ", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + TextSpan( + text: "Password ", + style: TextStyle(color: C.primaryHighlightedColor), + ), + TextSpan( + text: "? \n", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + TextSpan( + text: + "We got you covered.\nJust enter your registered email address.", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + ], + style: TextStyle(fontSize: 25 * heightFactor), + ), + ), + ), + SizedBox(height: 23 * heightFactor), + Form( + key: _formKey, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), + child: Column( + children: [ + EmailField(emailController), + SizedBox(height: 20 * heightFactor), + SizedBox(height: 10 * heightFactor), + ], + ), + )), + ], + ), + ), + //LoginButton + Expanded( + child: Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => _sendOTP(context, state), + child: Container( + height: 60, + width: 120, + alignment: Alignment.center, + child: Text( + "Submit", + style: TextStyle( + color: C.primaryUnHighlightedColor, fontSize: 20 * heightFactor), + ), + ), + ), + ), + ), + ), + //To flex background + Expanded(flex: 9, child: Container()), + ], + ), + ), + ), ], ), ); @@ -85,17 +237,202 @@ class ForgotPasswordScreen extends StatelessWidget { } Widget _enterOTP(BuildContext context, ForgotPasswordState state) { - return Padding( - padding: const EdgeInsets.all(40.0), - child: Column( + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (_scrollController.hasClients) { + if (bottom > height * 0.25) { + _scrollController.animateTo( + bottom - height * 0.25, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( children: [ - Text("Enter otp"), - OTPField(otpController), - FlatButton( - onPressed: () { - _verifyOtp(context, state); - }, - child: Text("Press me")), + //background + ScreenBackground(elementId: 0), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: _scrollController, + child: Container( + height: height * 1.00, + child: Column( + children: [ + // The text part od the screen + Flexible( + flex: 4, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Column( + children: [ + Text( + "Step 2/3", + style: + TextStyle(fontSize: 40 * heightFactor, fontWeight: FontWeight.w600), + ), + SizedBox(height: 30 * heightFactor), + Container( + alignment: Alignment.center, + child: Text( + "Enter OTP", + style: TextStyle( + fontWeight: FontWeight.w300, + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), + ), + ), + SizedBox(height: 30 * heightFactor), + Container( + padding: + EdgeInsets.fromLTRB(heightFactor * 10, 0, heightFactor * 10, 0), + alignment: Alignment.center, + child: Text( + "An otp has been sent to your email address.", + //textAlign: TextAlign.center, + style: TextStyle( + fontSize: heightFactor * 20, + ), + ), + ), + ], + ), + ), + ), + Flexible( + flex: 3, + child: Container( + child: Column( + children: [ + //OTP number fields + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp1, + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.firstRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp2, + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.secondRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp3, + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.thirdRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp4, + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.fourthRing, + width: 2.5, + ), + ), + ), + ], + ), + SizedBox(height: 30 * heightFactor), + //Verify button + Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => _verifyOtp(context, state), + child: Container( + height: 60, + width: 120, + alignment: Alignment.center, + child: Text( + "Verify", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + ), + ], + ), + ), + ), + Flexible( + flex: 7, + child: Container( + //TODO: Keyboard Here + color: Colors.teal, + ), + ), + ], + ), + ), + ), ], ), ); @@ -109,17 +446,130 @@ class ForgotPasswordScreen extends StatelessWidget { } Widget _resetPassword(BuildContext context, ForgotPasswordState state) { - return Padding( - padding: const EdgeInsets.all(40.0), - child: Column( + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (_scrollController.hasClients) { + if (bottom > height * 0.5) { + _scrollController.animateTo( + bottom - height * 0.5, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( children: [ - PasswordField(passwordController), - PasswordField(confirmPasswordController), - FlatButton( - onPressed: () { - _changePassword(context, state); - }, - child: Text("change password")), + //background + ScreenBackground(elementId: 0), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: _scrollController, + child: Container( + height: height * 1.25, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + //3/3 text + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Column( + children: [ + Text( + "Step 3/3", + style: + TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + SizedBox(height: 23 * heightFactor), + Container( + alignment: Alignment.center, + child: Text( + "Reset Password", + style: TextStyle( + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), + ), + ), + SizedBox(height: 23 * heightFactor), + Container( + alignment: Alignment.center, + child: Text( + "Please enter new password", + style: TextStyle( + fontSize: heightFactor * 25, + ), + ), + ), + ], + ), + ), + ), + // password and confirm password fields + Expanded( + flex: 3, + child: Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: PasswordField(passwordController), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: ConfirmPasswordField(confirmPasswordController), + ), + SizedBox(height: 20 * heightFactor), + Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => _changePassword(context, state), + child: Container( + height: 60, + width: 150, + alignment: Alignment.center, + child: Text( + "Reset Password", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), ], ), ); @@ -132,12 +582,43 @@ class ForgotPasswordScreen extends StatelessWidget { void _verifyOtp(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); - cubit.checkOTP(otpController.text, state, emailController.text); + cubit.checkOTP(otpEntered.substring(0, 4), state, emailController.text); } void _changePassword(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); - cubit.changePassword(emailController.text, otpController.text, passwordController.text, + cubit.changePassword(emailController.text, otpEntered.substring(0, 4), passwordController.text, confirmPasswordController.text, state); } + + void updateOTPBlocks() { + int length = otpEntered.length; + if (length == 0) { + otp1 = ""; + otp2 = ""; + otp3 = ""; + otp4 = ""; + } else if (length == 1) { + otp1 = otpEntered[0]; + otp2 = ""; + otp3 = ""; + otp4 = ""; + } else if (length == 2) { + otp1 = otpEntered[0]; + otp2 = otpEntered[1]; + otp3 = ""; + otp4 = ""; + } else if (length == 3) { + otp1 = otpEntered[0]; + otp2 = otpEntered[1]; + otp3 = otpEntered[2]; + otp4 = ""; + } else { + otp1 = otpEntered[0]; + otp2 = otpEntered[1]; + otp3 = otpEntered[2]; + otp4 = otpEntered[3]; + otpEntered = otpEntered.substring(0, 4); + } + } } diff --git a/lib/screens/forgot_password/widgets/confirm_password.dart b/lib/screens/forgot_password/widgets/confirm_password.dart new file mode 100644 index 0000000..001a6c0 --- /dev/null +++ b/lib/screens/forgot_password/widgets/confirm_password.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:ecellapp/core/res/colors.dart'; +import 'package:ecellapp/core/res/dimens.dart'; + +class ConfirmPasswordField extends StatefulWidget { + const ConfirmPasswordField(this.controller); + + final TextEditingController controller; + + @override + _ConfirmPasswordFieldState createState() => _ConfirmPasswordFieldState(); +} + +class _ConfirmPasswordFieldState extends State { + bool _passwordVisible = false; + + @override + Widget build(BuildContext context) { + double height = MediaQuery.of(context).size.height; + double heightFactor = height >= 1000 ? 1 : height / 1000; + return TextFormField( + controller: widget.controller, + validator: _validator, + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: D.inputFieldFontSize * heightFactor, + ), + textInputAction: TextInputAction.next, + onEditingComplete: () => FocusScope.of(context)..nextFocus()..nextFocus(), + obscureText: !_passwordVisible, + decoration: InputDecoration( + errorStyle: TextStyle(fontSize: 0.1), + prefixIcon: Icon( + Icons.lock_outline, + size: D.iconSize * heightFactor, + color: C.primaryHighlightedColor, + ), + suffixIcon: IconButton( + icon: IconTheme( + child: _passwordVisible ? Icon(Icons.visibility) : Icon(Icons.visibility_off), + data: IconThemeData(color: C.primaryHighlightedColor, size: D.iconSize * heightFactor), + ), + onPressed: _togglePasswordVisibility, + ), + labelText: "Confirm Password", + ), + ); + } + + String _validator(String password) => password.isEmpty ? "" : null; + + void _togglePasswordVisibility() => setState(() => _passwordVisible = !_passwordVisible); +} diff --git a/lib/screens/forgot_password/widgets/otp_field.dart b/lib/screens/forgot_password/widgets/otp_field.dart deleted file mode 100644 index d6ddbb8..0000000 --- a/lib/screens/forgot_password/widgets/otp_field.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -class OTPField extends StatelessWidget { - const OTPField(this.controller); - - final TextEditingController controller; - - @override - Widget build(BuildContext context) { - return TextFormField( - controller: controller, - keyboardType: TextInputType.phone, - validator: _validateOTP, - decoration: InputDecoration( - suffixText: '*', - suffixStyle: TextStyle(color: Colors.red, fontSize: 20), - prefixIcon: Icon(Icons.error), - border: OutlineInputBorder(), - labelText: "OTP", - ), - ); - } - - String _validateOTP(String otp) { - if (otp.length != 4) { - return "Please enter 4 digit OTP"; - } else { - return null; - } - } -} From 9ff21c1309f999909754de63e036a47486407664 Mon Sep 17 00:00:00 2001 From: treav Date: Fri, 5 Mar 2021 18:47:40 +0530 Subject: [PATCH 06/19] Resolved --- .../forgot_password_repository.dart | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/screens/forgot_password/forgot_password_repository.dart b/lib/screens/forgot_password/forgot_password_repository.dart index c463db8..ee6ea9a 100644 --- a/lib/screens/forgot_password/forgot_password_repository.dart +++ b/lib/screens/forgot_password/forgot_password_repository.dart @@ -80,12 +80,8 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { } if (response.statusCode == 202) { - try { - return; - } catch (e) { - Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); - throw UnknownException(); - } + // Since 202 denotes Accepted Response + return; } else if (response.statusCode == 400) { throw ValidationException(response.body); } else if (response.statusCode == 401 || response.statusCode == 404) { @@ -114,12 +110,8 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { } if (response.statusCode == 202) { - try { - return; - } catch (e) { - Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); - throw UnknownException(); - } + // 202 Implies sucess + return; } else if (response.statusCode == 400) { throw ValidationException(response.body); } else if (response.statusCode == 401 || response.statusCode == 404) { @@ -148,12 +140,8 @@ class APIForgotPasswordRepository extends ForgotPasswordRepository { } if (response.statusCode == 202) { - try { - return; - } catch (e) { - Log.e(tag: tag, message: "Error while decoding response json to get token: $e"); - throw UnknownException(); - } + // 202 Implies sucess + return; } else if (response.statusCode == 400) { throw ValidationException(response.body); } else if (response.statusCode == 401 || response.statusCode == 404) { From 53feaf138cfb306ab46f6f597a2acab212e105e8 Mon Sep 17 00:00:00 2001 From: treav Date: Sat, 6 Mar 2021 08:20:31 +0530 Subject: [PATCH 07/19] final commit --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index af11f90..7e1d851 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -69,7 +69,7 @@ class ECellApp extends StatelessWidget { S.routeForgotPassword: (_) => BlocProvider( create: (_) => ForgotPasswordCubit(FakeForgotPasswordRepository()), child: ForgotPasswordScreen(), - ) + ), S.routeBQuiz: (_) => BQuiz(), S.routeAboutUs: (_) => BlocProvider(create: (_) => TeamCubit(FakeTeamRepository()), child: AboutUsScreen()), From 1f40f508c1486c7dcd2d151d5a28ae1987e110fa Mon Sep 17 00:00:00 2001 From: treav Date: Sun, 7 Mar 2021 10:50:41 +0530 Subject: [PATCH 08/19] Minor fix --- lib/screens/forgot_password/forgot_password.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 5e95e8b..3d0a322 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -14,13 +14,15 @@ import 'package:google_fonts/google_fonts.dart'; import 'widgets/confirm_password.dart'; class ForgotPasswordScreen extends StatelessWidget { - String otp1 = "1", otp2 = "2", otp3 = "3", otp4 = "4", otpEntered = "1234"; final TextEditingController emailController = TextEditingController(); final TextEditingController otpController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmPasswordController = TextEditingController(); final ScrollController _scrollController = ScrollController(); final _formKey = GlobalKey(); + + String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; + @override Widget build(BuildContext context) { return Scaffold( From 3a828a176a0a1ca3553eab3c31dac085d841cacf Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 12:34:03 +0530 Subject: [PATCH 09/19] UI build stage1 --- lib/main.dart | 2 +- .../forgot_password/forgot_password.dart | 163 +++++++++++++----- .../forgot_password/widgets/keyboard.dart | 133 ++++++++++++++ 3 files changed, 257 insertions(+), 41 deletions(-) create mode 100644 lib/screens/forgot_password/widgets/keyboard.dart diff --git a/lib/main.dart b/lib/main.dart index 7e1d851..911dba1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,7 @@ class ECellApp extends StatelessWidget { S.routeAboutUs: (_) => BlocProvider(create: (_) => TeamCubit(FakeTeamRepository()), child: AboutUsScreen()), }, - initialRoute: S.routeSplash, + initialRoute: S.routeForgotPassword, title: "ECellApp", theme: AppTheme.themeData(context), ), diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 3d0a322..d798607 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -2,6 +2,7 @@ import 'package:ecellapp/core/res/colors.dart'; import 'package:ecellapp/core/res/dimens.dart'; import 'package:ecellapp/core/res/strings.dart'; import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; +import 'package:ecellapp/screens/forgot_password/widgets/keyboard.dart'; import 'package:ecellapp/widgets/ecell_animation.dart'; import 'package:ecellapp/widgets/email_field.dart'; import 'package:ecellapp/widgets/password_field.dart'; @@ -20,7 +21,7 @@ class ForgotPasswordScreen extends StatelessWidget { final TextEditingController confirmPasswordController = TextEditingController(); final ScrollController _scrollController = ScrollController(); final _formKey = GlobalKey(); - + String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; @override @@ -274,34 +275,54 @@ class ForgotPasswordScreen extends StatelessWidget { alignment: Alignment.center, child: Column( children: [ - Text( - "Step 2/3", - style: - TextStyle(fontSize: 40 * heightFactor, fontWeight: FontWeight.w600), - ), - SizedBox(height: 30 * heightFactor), - Container( - alignment: Alignment.center, + Expanded( + flex: 1, child: Text( - "Enter OTP", + "Step 2/3", style: TextStyle( - fontWeight: FontWeight.w300, - color: C.primaryHighlightedColor, - fontSize: heightFactor * 30, + fontSize: 40 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + Expanded( + flex: 1, + child: Icon(Icons.verified_user, + color: Colors.white, size: 65 * heightFactor), + ), + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Verify OTP", + style: TextStyle( + fontWeight: FontWeight.w300, + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), ), ), ), - SizedBox(height: 30 * heightFactor), Container( padding: EdgeInsets.fromLTRB(heightFactor * 10, 0, heightFactor * 10, 0), alignment: Alignment.center, - child: Text( - "An otp has been sent to your email address.", - //textAlign: TextAlign.center, - style: TextStyle( - fontSize: heightFactor * 20, - ), + child: Column( + children: [ + Text( + "An otp has been sent to the registered user", + style: TextStyle( + fontSize: heightFactor * 20, + ), + ), + Padding( + padding: EdgeInsets.only(top: 10 * heightFactor), + child: Text( + "email", + style: TextStyle( + fontSize: heightFactor * 20, + ), + )), + ], ), ), ], @@ -310,11 +331,12 @@ class ForgotPasswordScreen extends StatelessWidget { ), Flexible( flex: 3, - child: Container( - child: Column( - children: [ - //OTP number fields - Row( + child: Column( + children: [ + //!OTP number fields + Padding( + padding: const EdgeInsets.only(top: 20), + child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( @@ -383,12 +405,72 @@ class ForgotPasswordScreen extends StatelessWidget { ), ], ), - SizedBox(height: 30 * heightFactor), - //Verify button - Container( - padding: EdgeInsets.only(right: D.horizontalPadding), - alignment: Alignment.topRight, - child: Container( + ), + Center( + child: RichText( + text: TextSpan( + text: "You can request another OTP in ", + children: [ + TextSpan( + text: "[Time]", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w600, + )), + TextSpan( + text: "s", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w600, + )), + ], + style: TextStyle( + fontSize: 15 * heightFactor, fontWeight: FontWeight.w300), + ), + ), + ), + + SizedBox(height: 30 * heightFactor), + //!Verify button + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C, + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => _verifyOtp(context, state), + child: Container( + height: 60, + width: 120, + alignment: Alignment.center, + child: Text( + "Resend", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + SizedBox( + width: 20 * heightFactor, + ), + Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(30)), boxShadow: [ @@ -411,7 +493,7 @@ class ForgotPasswordScreen extends StatelessWidget { width: 120, alignment: Alignment.center, child: Text( - "Verify", + "Submit", style: TextStyle( color: C.primaryUnHighlightedColor, fontSize: 20 * heightFactor), @@ -419,17 +501,14 @@ class ForgotPasswordScreen extends StatelessWidget { ), ), ), - ), - ], - ), + ], + ), + ], ), ), Flexible( - flex: 7, - child: Container( - //TODO: Keyboard Here - color: Colors.teal, - ), + flex: 3, + child: NumericPad(onNumberSelected: _onNumSelected), ), ], ), @@ -623,4 +702,8 @@ class ForgotPasswordScreen extends StatelessWidget { otpEntered = otpEntered.substring(0, 4); } } + + _onNumSelected(int p1) { + print("$p1"); + } } diff --git a/lib/screens/forgot_password/widgets/keyboard.dart b/lib/screens/forgot_password/widgets/keyboard.dart new file mode 100644 index 0000000..b54e933 --- /dev/null +++ b/lib/screens/forgot_password/widgets/keyboard.dart @@ -0,0 +1,133 @@ +import 'package:flutter/material.dart'; + +class NumericPad extends StatelessWidget { + final Function(int) onNumberSelected; + + NumericPad({@required this.onNumberSelected}); + + @override + Widget build(BuildContext context) { + return Container( + color: Color(0xFFF5F4F9), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.11, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(1), + buildNumber(2), + buildNumber(3), + ], + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.11, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(4), + buildNumber(5), + buildNumber(6), + ], + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.11, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(7), + buildNumber(8), + buildNumber(9), + ], + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.11, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildEmptySpace(), + buildNumber(0), + buildBackspace(), + ], + ), + ), + ], + ), + ); + } + + Widget buildNumber(int number) { + return Expanded( + child: GestureDetector( + onTap: () { + onNumberSelected(number); + }, + child: Padding( + padding: EdgeInsets.all(10), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + child: Center( + child: Text( + number.toString(), + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Color(0xFF1F1F1F), + ), + ), + ), + ), + ), + ), + ); + } + + Widget buildBackspace() { + return Expanded( + child: GestureDetector( + onTap: () { + onNumberSelected(-1); + }, + child: Padding( + padding: EdgeInsets.all(10), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + child: Center( + child: Icon( + Icons.backspace, + size: 28, + color: Color(0xFF1F1F1F), + ), + ), + ), + ), + ), + ); + } + + Widget buildEmptySpace() { + return Expanded( + child: Container(), + ); + } +} From 915a550b3fac528b79045f9f5426aabdced6449a Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:06:54 +0530 Subject: [PATCH 10/19] UI Done --- lib/core/res/colors.dart | 1 + .../forgot_password/forgot_password.dart | 201 +++++++++++------- .../forgot_password/widgets/keyboard.dart | 133 ------------ .../forgot_password/widgets/numeric_pad.dart | 135 ++++++++++++ 4 files changed, 262 insertions(+), 208 deletions(-) delete mode 100644 lib/screens/forgot_password/widgets/keyboard.dart create mode 100644 lib/screens/forgot_password/widgets/numeric_pad.dart diff --git a/lib/core/res/colors.dart b/lib/core/res/colors.dart index 2bf4f36..ec59a69 100644 --- a/lib/core/res/colors.dart +++ b/lib/core/res/colors.dart @@ -6,6 +6,7 @@ class C { /// background color gradient static final Color backgroundTop = HexColor("#4F3FA0"); static final Color backgroundBottom = HexColor("#180C58"); + /// animated rings colors (1->4 increasingsize) static final Color ring1 = HexColor("#2DFFF9"); diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index d798607..09b8661 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -2,7 +2,7 @@ import 'package:ecellapp/core/res/colors.dart'; import 'package:ecellapp/core/res/dimens.dart'; import 'package:ecellapp/core/res/strings.dart'; import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; -import 'package:ecellapp/screens/forgot_password/widgets/keyboard.dart'; +import 'package:ecellapp/screens/forgot_password/widgets/numeric_pad.dart'; import 'package:ecellapp/widgets/ecell_animation.dart'; import 'package:ecellapp/widgets/email_field.dart'; import 'package:ecellapp/widgets/password_field.dart'; @@ -22,11 +22,23 @@ class ForgotPasswordScreen extends StatelessWidget { final ScrollController _scrollController = ScrollController(); final _formKey = GlobalKey(); - String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; + String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = "1234"; @override Widget build(BuildContext context) { return Scaffold( + extendBodyBehindAppBar: true, + appBar: AppBar( + elevation: 0, + backgroundColor: Colors.transparent, + leading: Container( + padding: EdgeInsets.only(left: D.horizontalPadding - 10, top: 10), + child: IconButton( + icon: Icon(Icons.arrow_back_ios, color: Colors.white, size: 30), + onPressed: () => Navigator.of(context).pop(), + ), + ), + ), backgroundColor: Colors.transparent, body: BlocConsumer( listener: (context, state) { @@ -239,6 +251,7 @@ class ForgotPasswordScreen extends StatelessWidget { return Center(child: ECellLogoAnimation(size: width / 2)); } + /// Screen for EnterOTP Widget _enterOTP(BuildContext context, ForgotPasswordState state) { double height = MediaQuery.of(context).size.height; double bottom = MediaQuery.of(context).viewInsets.bottom; @@ -438,13 +451,17 @@ class ForgotPasswordScreen extends StatelessWidget { children: [ Container( decoration: BoxDecoration( + border: Border.all( + color: Colors.white, + width: 2.0, + ), borderRadius: BorderRadius.all(Radius.circular(30)), boxShadow: [ BoxShadow( - color: C, - blurRadius: 10, - spreadRadius: 3, - offset: Offset(0, 12), + color: C.backgroundTop, + // blurRadius: 10, + //spreadRadius: 3, + //offset: Offset(0, 12), ) ], ), @@ -452,10 +469,10 @@ class ForgotPasswordScreen extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(30)), ), - color: C.authButtonColor, + color: Colors.transparent, onPressed: () => _verifyOtp(context, state), child: Container( - height: 60, + height: 50, width: 120, alignment: Alignment.center, child: Text( @@ -489,8 +506,8 @@ class ForgotPasswordScreen extends StatelessWidget { color: C.authButtonColor, onPressed: () => _verifyOtp(context, state), child: Container( - height: 60, - width: 120, + height: 54, + width: 124, alignment: Alignment.center, child: Text( "Submit", @@ -507,9 +524,10 @@ class ForgotPasswordScreen extends StatelessWidget { ), ), Flexible( - flex: 3, + flex: 4, child: NumericPad(onNumberSelected: _onNumSelected), ), + SizedBox(height: heightFactor * 40) ], ), ), @@ -520,9 +538,33 @@ class ForgotPasswordScreen extends StatelessWidget { } Widget _passwordResetSuccess() { - return Padding( - padding: const EdgeInsets.all(40.0), - child: Text("success"), + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + S.assetEcellLogoWhite, + height: 170, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 120), + child: Row( + children: [ + Text( + "Sucess", + style: TextStyle( + fontSize: 40, fontWeight: FontWeight.w600, color: C.primaryHighlightedColor), + ), + Icon( + Icons.check_circle, + color: C.primaryUnHighlightedColor, + size: 40, + ) + ], + ), + ) + ], + ), ); } @@ -553,7 +595,6 @@ class ForgotPasswordScreen extends StatelessWidget { child: Container( height: height * 1.25, child: Column( - mainAxisSize: MainAxisSize.min, children: [ //3/3 text Expanded( @@ -563,29 +604,36 @@ class ForgotPasswordScreen extends StatelessWidget { alignment: Alignment.center, child: Column( children: [ - Text( - "Step 3/3", - style: - TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), - ), - SizedBox(height: 23 * heightFactor), - Container( - alignment: Alignment.center, + Expanded( + flex: 1, child: Text( - "Reset Password", + "Step 3/3", style: TextStyle( - color: C.primaryHighlightedColor, - fontSize: heightFactor * 30, + fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Reset Password", + style: TextStyle( + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), ), ), ), - SizedBox(height: 23 * heightFactor), - Container( - alignment: Alignment.center, - child: Text( - "Please enter new password", - style: TextStyle( - fontSize: heightFactor * 25, + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Please enter your new password", + style: TextStyle( + fontSize: heightFactor * 25, + ), ), ), ), @@ -594,57 +642,60 @@ class ForgotPasswordScreen extends StatelessWidget { ), ), // password and confirm password fields + SizedBox( + height: 50, + ), Expanded( flex: 3, - child: Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: PasswordField(passwordController), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: ConfirmPasswordField(confirmPasswordController), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 40), + child: Column( + children: [ + PasswordField(passwordController), + SizedBox(height: 20 * heightFactor), + ConfirmPasswordField(confirmPasswordController), + ], ), - SizedBox(height: 20 * heightFactor), - Container( - padding: EdgeInsets.only(right: D.horizontalPadding), - alignment: Alignment.topRight, - child: Container( - decoration: BoxDecoration( + ), + SizedBox(height: 20 * heightFactor), + Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(30)), - boxShadow: [ - BoxShadow( - color: C.authButtonColor.withOpacity(0.2), - blurRadius: 10, - spreadRadius: 3, - offset: Offset(0, 12), - ) - ], ), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - ), - color: C.authButtonColor, - onPressed: () => _changePassword(context, state), - child: Container( - height: 60, - width: 150, - alignment: Alignment.center, - child: Text( - "Reset Password", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontSize: 20 * heightFactor), - ), + color: C.authButtonColor, + onPressed: () => _changePassword(context, state), + child: Container( + height: 60, + width: 100, + alignment: Alignment.center, + child: Text( + "Reset", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), ), ), ), ), - ], - ), + ), + ], ), ), ], diff --git a/lib/screens/forgot_password/widgets/keyboard.dart b/lib/screens/forgot_password/widgets/keyboard.dart deleted file mode 100644 index b54e933..0000000 --- a/lib/screens/forgot_password/widgets/keyboard.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:flutter/material.dart'; - -class NumericPad extends StatelessWidget { - final Function(int) onNumberSelected; - - NumericPad({@required this.onNumberSelected}); - - @override - Widget build(BuildContext context) { - return Container( - color: Color(0xFFF5F4F9), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.11, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildNumber(1), - buildNumber(2), - buildNumber(3), - ], - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.11, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildNumber(4), - buildNumber(5), - buildNumber(6), - ], - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.11, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildNumber(7), - buildNumber(8), - buildNumber(9), - ], - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.11, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildEmptySpace(), - buildNumber(0), - buildBackspace(), - ], - ), - ), - ], - ), - ); - } - - Widget buildNumber(int number) { - return Expanded( - child: GestureDetector( - onTap: () { - onNumberSelected(number); - }, - child: Padding( - padding: EdgeInsets.all(10), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(15), - ), - ), - child: Center( - child: Text( - number.toString(), - style: TextStyle( - fontSize: 28, - fontWeight: FontWeight.bold, - color: Color(0xFF1F1F1F), - ), - ), - ), - ), - ), - ), - ); - } - - Widget buildBackspace() { - return Expanded( - child: GestureDetector( - onTap: () { - onNumberSelected(-1); - }, - child: Padding( - padding: EdgeInsets.all(10), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(15), - ), - ), - child: Center( - child: Icon( - Icons.backspace, - size: 28, - color: Color(0xFF1F1F1F), - ), - ), - ), - ), - ), - ); - } - - Widget buildEmptySpace() { - return Expanded( - child: Container(), - ); - } -} diff --git a/lib/screens/forgot_password/widgets/numeric_pad.dart b/lib/screens/forgot_password/widgets/numeric_pad.dart new file mode 100644 index 0000000..360f874 --- /dev/null +++ b/lib/screens/forgot_password/widgets/numeric_pad.dart @@ -0,0 +1,135 @@ +import 'package:ecellapp/core/res/colors.dart'; +import 'package:flutter/material.dart'; + +class NumericPad extends StatelessWidget { + final Function(int) onNumberSelected; + + NumericPad({@required this.onNumberSelected}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 80), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(1), + buildNumber(2), + buildNumber(3), + ], + ), + ), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(4), + buildNumber(5), + buildNumber(6), + ], + ), + ), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildNumber(7), + buildNumber(8), + buildNumber(9), + ], + ), + ), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildEmptySpace(), + buildNumber(0), + buildBackspace(), + ], + ), + ), + ], + ), + ), + ); + } + + Widget buildNumber(int number) { + return Expanded( + child: GestureDetector( + onTap: () { + onNumberSelected(number); + }, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12.75), + child: Container( + height: 40, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.35), + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + child: Center( + child: Text( + number.toString(), + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: C.primaryUnHighlightedColor, + ), + ), + ), + ), + ), + ), + ); + } + + Widget buildBackspace() { + return Expanded( + child: GestureDetector( + onTap: () { + onNumberSelected(-1); + }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.75), + child: Container( + height: 40, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.25), + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + child: Center( + child: Icon( + Icons.backspace_outlined, + size: 20, + color: Colors.white.withOpacity(0.75), + ), + ), + ), + ), + ), + ); + } + + Widget buildEmptySpace() { + return Expanded( + child: Container(), + ); + } +} From 7df95f3b928e250fa537742a653f329b2c174b1e Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:09:26 +0530 Subject: [PATCH 11/19] check fix --- lib/core/res/colors.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/core/res/colors.dart b/lib/core/res/colors.dart index ec59a69..2bf4f36 100644 --- a/lib/core/res/colors.dart +++ b/lib/core/res/colors.dart @@ -6,7 +6,6 @@ class C { /// background color gradient static final Color backgroundTop = HexColor("#4F3FA0"); static final Color backgroundBottom = HexColor("#180C58"); - /// animated rings colors (1->4 increasingsize) static final Color ring1 = HexColor("#2DFFF9"); From 926a104e48ef211c7212d2e51ef215b195f8536e Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:25:48 +0530 Subject: [PATCH 12/19] Minor fix --- lib/screens/forgot_password/forgot_password.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 09b8661..5a7d9d8 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -22,7 +22,7 @@ class ForgotPasswordScreen extends StatelessWidget { final ScrollController _scrollController = ScrollController(); final _formKey = GlobalKey(); - String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = "1234"; + String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; @override Widget build(BuildContext context) { @@ -755,6 +755,13 @@ class ForgotPasswordScreen extends StatelessWidget { } _onNumSelected(int p1) { + if (p1 == -1 && otpEntered.length > 0) { + otpEntered = otpEntered.substring(0, otpEntered.length - 1); + } else { + otpEntered = otpEntered + p1.toString(); + } + updateOTPBlocks(); print("$p1"); + print("O: $otpEntered"); } } From b53d3f2bb3c104d1d7057a4d2ba5a0d4444cd9e2 Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:28:59 +0530 Subject: [PATCH 13/19] Check fix --- .../forgot_password/forgot_password.dart | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 5a7d9d8..20b4e27 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -14,12 +14,22 @@ import 'package:google_fonts/google_fonts.dart'; import 'widgets/confirm_password.dart'; -class ForgotPasswordScreen extends StatelessWidget { +class ForgotPasswordScreen extends StatefulWidget { + @override + _ForgotPasswordScreenState createState() => _ForgotPasswordScreenState(); +} + +class _ForgotPasswordScreenState extends State { final TextEditingController emailController = TextEditingController(); + final TextEditingController otpController = TextEditingController(); + final TextEditingController passwordController = TextEditingController(); + final TextEditingController confirmPasswordController = TextEditingController(); + final ScrollController _scrollController = ScrollController(); + final _formKey = GlobalKey(); String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; @@ -755,13 +765,15 @@ class ForgotPasswordScreen extends StatelessWidget { } _onNumSelected(int p1) { - if (p1 == -1 && otpEntered.length > 0) { - otpEntered = otpEntered.substring(0, otpEntered.length - 1); - } else { - otpEntered = otpEntered + p1.toString(); - } - updateOTPBlocks(); - print("$p1"); - print("O: $otpEntered"); + setState(() { + if (p1 == -1) { + if (otpEntered.length > 0) { + otpEntered = otpEntered.substring(0, otpEntered.length - 1); + } + } else { + otpEntered = otpEntered + p1.toString(); + } + updateOTPBlocks(); + }); } } From 5e4a03ecf8618a50446ee076872c1d45ad6f48ae Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:29:21 +0530 Subject: [PATCH 14/19] minor fix --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 911dba1..7e1d851 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,7 @@ class ECellApp extends StatelessWidget { S.routeAboutUs: (_) => BlocProvider(create: (_) => TeamCubit(FakeTeamRepository()), child: AboutUsScreen()), }, - initialRoute: S.routeForgotPassword, + initialRoute: S.routeSplash, title: "ECellApp", theme: AppTheme.themeData(context), ), From 91bfd00ee339bc8493c1db7301958071c87b4af4 Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 14:40:16 +0530 Subject: [PATCH 15/19] Routes added --- lib/screens/home/tabs/profile.dart | 4 +++- lib/screens/login/login.dart | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/screens/home/tabs/profile.dart b/lib/screens/home/tabs/profile.dart index a34671b..3fb8d9c 100644 --- a/lib/screens/home/tabs/profile.dart +++ b/lib/screens/home/tabs/profile.dart @@ -64,7 +64,9 @@ class _ProfileScreenState extends State { Container( alignment: Alignment.topRight, child: GestureDetector( - onTap: () {}, //TODO + onTap: () { + Navigator.pushReplacementNamed(context, S.routeForgotPassword); + }, child: Text( "Change Password?", style: TextStyle( diff --git a/lib/screens/login/login.dart b/lib/screens/login/login.dart index a46381a..fccdcb4 100644 --- a/lib/screens/login/login.dart +++ b/lib/screens/login/login.dart @@ -141,7 +141,7 @@ class LoginScreen extends StatelessWidget { TextStyle(fontSize: 20 * heightFactor, color: C.secondaryColor), ), onTap: () { - //TODO: Forgot Password Route + Navigator.pushReplacementNamed(context, S.routeForgotPassword); }, ), ) From f2efeaa0d39d012386144c52d519810047a1e2e2 Mon Sep 17 00:00:00 2001 From: treav Date: Thu, 11 Mar 2021 17:31:55 +0530 Subject: [PATCH 16/19] Code Defragmentation --- lib/screens/forgot_password/ask_email.dart | 178 +++++ lib/screens/forgot_password/enter_otp.dart | 297 ++++++++ .../forgot_password/forgot_password.dart | 692 ++---------------- .../forgot_password/reset_password.dart | 162 ++++ 4 files changed, 686 insertions(+), 643 deletions(-) create mode 100644 lib/screens/forgot_password/ask_email.dart create mode 100644 lib/screens/forgot_password/enter_otp.dart create mode 100644 lib/screens/forgot_password/reset_password.dart diff --git a/lib/screens/forgot_password/ask_email.dart b/lib/screens/forgot_password/ask_email.dart new file mode 100644 index 0000000..74f7048 --- /dev/null +++ b/lib/screens/forgot_password/ask_email.dart @@ -0,0 +1,178 @@ +import 'package:ecellapp/core/res/colors.dart'; +import 'package:ecellapp/core/res/dimens.dart'; +import 'package:ecellapp/core/res/strings.dart'; +import 'package:ecellapp/widgets/email_field.dart'; +import 'package:ecellapp/widgets/screen_background.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import 'cubit/forgot_password_cubit.dart'; + +class AskEmailScreen extends StatelessWidget { + const AskEmailScreen({Key key, this.onSubmit, this.emailController}) : super(key: key); + + final Function(BuildContext context, ForgotPasswordState state) onSubmit; + final TextEditingController emailController; + + @override + Widget build(BuildContext context) { + final ScrollController scrollController = ScrollController(); + final formKey = GlobalKey(); + + double width = MediaQuery.of(context).size.width; + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (scrollController.hasClients) { + if (bottom > height * 0.25) { + scrollController.animateTo( + bottom - height * 0.25, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( + children: [ + ScreenBackground(elementId: 1), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: scrollController, + child: Container( + height: height * 1.25, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + flex: 5, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Text( + "Step 1/3", + style: + TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + )), + Flexible( + flex: 7, + child: Column( + children: [ + // Logo + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding + 1), + child: Image.asset( + S.assetEcellLogoWhite, + width: width * 0.25 * heightFactor, + ), + ), + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding, top: 20), + child: Text( + "Welcome", + style: + TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + //Text Greeting + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(left: D.horizontalPadding, top: 5), + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: "Forgot your ", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + TextSpan( + text: "Password ", + style: TextStyle(color: C.primaryHighlightedColor), + ), + TextSpan( + text: "? \n", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + TextSpan( + text: + "We got you covered.\nJust enter your registered email address.", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w300)), + ], + style: TextStyle(fontSize: 25 * heightFactor), + ), + ), + ), + SizedBox(height: 23 * heightFactor), + Form( + key: formKey, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), + child: Column( + children: [ + EmailField(emailController), + SizedBox(height: 20 * heightFactor), + SizedBox(height: 10 * heightFactor), + ], + ), + )), + ], + ), + ), + //LoginButton + Expanded( + child: Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => onSubmit, + child: Container( + height: 60, + width: 120, + alignment: Alignment.center, + child: Text( + "Submit", + style: TextStyle( + color: C.primaryUnHighlightedColor, fontSize: 20 * heightFactor), + ), + ), + ), + ), + ), + ), + //To flex background + Expanded(flex: 9, child: Container()), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/forgot_password/enter_otp.dart b/lib/screens/forgot_password/enter_otp.dart new file mode 100644 index 0000000..e8c9964 --- /dev/null +++ b/lib/screens/forgot_password/enter_otp.dart @@ -0,0 +1,297 @@ +import 'package:ecellapp/core/res/colors.dart'; +import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; +import 'package:ecellapp/widgets/screen_background.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import 'widgets/numeric_pad.dart'; + +class EnterOTPScreen extends StatelessWidget { + const EnterOTPScreen({Key key, this.otp, this.toVerify, this.numSelected}) : super(key: key); + + final Function(BuildContext context, ForgotPasswordState state) toVerify; + final Function(int) numSelected; + final String otp; + + @override + Widget build(BuildContext context) { + final ScrollController scrollController = ScrollController(); + + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (scrollController.hasClients) { + if (bottom > height * 0.25) { + scrollController.animateTo( + bottom - height * 0.25, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( + children: [ + //background + ScreenBackground(elementId: 0), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: scrollController, + child: Container( + height: height * 1.00, + child: Column( + children: [ + // The text part od the screen + Flexible( + flex: 4, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Column( + children: [ + Expanded( + flex: 1, + child: Text( + "Step 2/3", + style: TextStyle( + fontSize: 40 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + Expanded( + flex: 1, + child: Icon(Icons.verified_user, + color: Colors.white, size: 65 * heightFactor), + ), + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Verify OTP", + style: TextStyle( + fontWeight: FontWeight.w300, + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), + ), + ), + ), + Container( + padding: + EdgeInsets.fromLTRB(heightFactor * 10, 0, heightFactor * 10, 0), + alignment: Alignment.center, + child: Column( + children: [ + Text( + "An otp has been sent to the registered user", + style: TextStyle( + fontSize: heightFactor * 20, + ), + ), + Padding( + padding: EdgeInsets.only(top: 10 * heightFactor), + child: Text( + "email", + style: TextStyle( + fontSize: heightFactor * 20, + ), + )), + ], + ), + ), + ], + ), + ), + ), + Flexible( + flex: 3, + child: Column( + children: [ + //!OTP number fields + Padding( + padding: const EdgeInsets.only(top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp[0] ?? "", + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.firstRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp[1] ?? "", + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.secondRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp[2] ?? "", + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.thirdRing, + width: 2.5, + ), + ), + ), + Container( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + otp[3] ?? "", + style: TextStyle(fontSize: 23), + ), + ), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: C.fourthRing, + width: 2.5, + ), + ), + ), + ], + ), + ), + Center( + child: RichText( + text: TextSpan( + text: "You can request another OTP in ", + children: [ + TextSpan( + text: "[Time]s", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontWeight: FontWeight.w600, + )), + ], + style: TextStyle( + fontSize: 15 * heightFactor, fontWeight: FontWeight.w300), + ), + ), + ), + + SizedBox(height: 30 * heightFactor), + //!Verify button + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.white, + width: 2.0, + ), + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.backgroundTop, + // blurRadius: 10, + //spreadRadius: 3, + //offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: Colors.transparent, + onPressed: () => toVerify, + child: Container( + height: 50, + width: 120, + alignment: Alignment.center, + child: Text( + "Resend", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + SizedBox( + width: 20 * heightFactor, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => toVerify, + child: Container( + height: 54, + width: 124, + alignment: Alignment.center, + child: Text( + "Submit", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + ], + ), + ], + ), + ), + Flexible( + flex: 4, + child: NumericPad(onNumberSelected: numSelected), + ), + SizedBox(height: heightFactor * 40) + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 20b4e27..2f53d46 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -1,18 +1,16 @@ import 'package:ecellapp/core/res/colors.dart'; import 'package:ecellapp/core/res/dimens.dart'; import 'package:ecellapp/core/res/strings.dart'; +import 'package:ecellapp/screens/forgot_password/ask_email.dart'; import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; -import 'package:ecellapp/screens/forgot_password/widgets/numeric_pad.dart'; +import 'package:ecellapp/screens/forgot_password/enter_otp.dart'; import 'package:ecellapp/widgets/ecell_animation.dart'; -import 'package:ecellapp/widgets/email_field.dart'; -import 'package:ecellapp/widgets/password_field.dart'; import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'widgets/confirm_password.dart'; +import 'reset_password.dart'; class ForgotPasswordScreen extends StatefulWidget { @override @@ -20,19 +18,12 @@ class ForgotPasswordScreen extends StatefulWidget { } class _ForgotPasswordScreenState extends State { - final TextEditingController emailController = TextEditingController(); - - final TextEditingController otpController = TextEditingController(); - final TextEditingController passwordController = TextEditingController(); - final TextEditingController confirmPasswordController = TextEditingController(); + final TextEditingController emailController = TextEditingController(); + final TextEditingController otpController = TextEditingController(); - final ScrollController _scrollController = ScrollController(); - - final _formKey = GlobalKey(); - - String otp1 = "", otp2 = "", otp3 = "", otp4 = "", otpEntered = ""; + String otpEntered = ""; @override Widget build(BuildContext context) { @@ -63,19 +54,32 @@ class _ForgotPasswordScreenState extends State { children: [ ScreenBackground(elementId: 0), if (state is ForgotEmailInitial) - _initialForgotPassword(context, state) + AskEmailScreen( + emailController: emailController, + onSubmit: _sendOTP(context, state), + ) else if (state is ForgotLoading) _buildLoading(context) else if (state is ForgotOTPInitial) - _enterOTP(context, state) + EnterOTPScreen( + numSelected: _onNumSelected, + otp: otpEntered, + toVerify: _verifyOtp(context, state), + ) else if (state is ForgotPasswordError) _uiUpdateForNetworkError(context, state.state) else if (state is ForgotResetInitial) - _resetPassword(context, state) + ResetPassword( + onConfirm: _changePassword(context, state), + confirmPasswordController: confirmPasswordController, + passwordController: passwordController) else if (state is ForgotResetSuccess) _passwordResetSuccess() else - _initialForgotPassword(context, state) + AskEmailScreen( + emailController: emailController, + onSubmit: _sendOTP(context, state), + ) ], ); }, @@ -85,468 +89,40 @@ class _ForgotPasswordScreenState extends State { Widget _uiUpdateForNetworkError(BuildContext context, ForgotPasswordState state) { if (state is ForgotEmailInitial) { - return _initialForgotPassword(context, state); + return AskEmailScreen( + emailController: emailController, + onSubmit: _sendOTP(context, state), + ); } else if (state is ForgotOTPInitial) { - return _enterOTP(context, state); + return EnterOTPScreen( + numSelected: _onNumSelected, + otp: otpEntered, + toVerify: _verifyOtp(context, state), + ); } else if (state is ForgotPasswordError) { - return _enterOTP(context, state); + return EnterOTPScreen( + numSelected: _onNumSelected, + otp: otpEntered, + toVerify: _verifyOtp(context, state), + ); } else if (state is ForgotResetInitial) { - return _resetPassword(context, state); + return ResetPassword( + onConfirm: _changePassword(context, state), + confirmPasswordController: confirmPasswordController, + passwordController: passwordController); } else { - return _initialForgotPassword(context, state); + return AskEmailScreen( + emailController: emailController, + onSubmit: _sendOTP(context, state), + ); } } - ///Initial Forgot Password - Widget _initialForgotPassword(BuildContext context, ForgotPasswordState state) { - double width = MediaQuery.of(context).size.width; - double height = MediaQuery.of(context).size.height; - double bottom = MediaQuery.of(context).viewInsets.bottom; - double heightFactor = height / 1000; - if (_scrollController.hasClients) { - if (bottom > height * 0.25) { - _scrollController.animateTo( - bottom - height * 0.25, - duration: Duration(milliseconds: 300), - curve: Curves.ease, - ); - } else { - _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); - } - } - return DefaultTextStyle( - style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), - child: Stack( - children: [ - ScreenBackground(elementId: 1), - SingleChildScrollView( - physics: NeverScrollableScrollPhysics(), - controller: _scrollController, - child: Container( - height: height * 1.25, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - flex: 5, - child: Container( - padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), - alignment: Alignment.center, - child: Text( - "Step 1/3", - style: - TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), - ), - )), - Flexible( - flex: 7, - child: Column( - children: [ - // Logo - Container( - alignment: Alignment.centerLeft, - padding: EdgeInsets.only(left: D.horizontalPadding + 1), - child: Image.asset( - S.assetEcellLogoWhite, - width: width * 0.25 * heightFactor, - ), - ), - Container( - alignment: Alignment.centerLeft, - padding: EdgeInsets.only(left: D.horizontalPadding, top: 20), - child: Text( - "Welcome", - style: - TextStyle(fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), - ), - ), - //Text Greeting - Container( - alignment: Alignment.centerLeft, - padding: EdgeInsets.only(left: D.horizontalPadding, top: 5), - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: "Forgot your ", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontWeight: FontWeight.w300)), - TextSpan( - text: "Password ", - style: TextStyle(color: C.primaryHighlightedColor), - ), - TextSpan( - text: "? \n", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontWeight: FontWeight.w300)), - TextSpan( - text: - "We got you covered.\nJust enter your registered email address.", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontWeight: FontWeight.w300)), - ], - style: TextStyle(fontSize: 25 * heightFactor), - ), - ), - ), - SizedBox(height: 23 * heightFactor), - Form( - key: _formKey, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), - child: Column( - children: [ - EmailField(emailController), - SizedBox(height: 20 * heightFactor), - SizedBox(height: 10 * heightFactor), - ], - ), - )), - ], - ), - ), - //LoginButton - Expanded( - child: Container( - padding: EdgeInsets.only(right: D.horizontalPadding), - alignment: Alignment.topRight, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(30)), - boxShadow: [ - BoxShadow( - color: C.authButtonColor.withOpacity(0.2), - blurRadius: 10, - spreadRadius: 3, - offset: Offset(0, 12), - ) - ], - ), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - ), - color: C.authButtonColor, - onPressed: () => _sendOTP(context, state), - child: Container( - height: 60, - width: 120, - alignment: Alignment.center, - child: Text( - "Submit", - style: TextStyle( - color: C.primaryUnHighlightedColor, fontSize: 20 * heightFactor), - ), - ), - ), - ), - ), - ), - //To flex background - Expanded(flex: 9, child: Container()), - ], - ), - ), - ), - ], - ), - ); - } - Widget _buildLoading(BuildContext context) { double width = MediaQuery.of(context).size.width; return Center(child: ECellLogoAnimation(size: width / 2)); } - /// Screen for EnterOTP - Widget _enterOTP(BuildContext context, ForgotPasswordState state) { - double height = MediaQuery.of(context).size.height; - double bottom = MediaQuery.of(context).viewInsets.bottom; - double heightFactor = height / 1000; - if (_scrollController.hasClients) { - if (bottom > height * 0.25) { - _scrollController.animateTo( - bottom - height * 0.25, - duration: Duration(milliseconds: 300), - curve: Curves.ease, - ); - } else { - _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); - } - } - return DefaultTextStyle( - style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), - child: Stack( - children: [ - //background - ScreenBackground(elementId: 0), - SingleChildScrollView( - physics: NeverScrollableScrollPhysics(), - controller: _scrollController, - child: Container( - height: height * 1.00, - child: Column( - children: [ - // The text part od the screen - Flexible( - flex: 4, - child: Container( - padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), - alignment: Alignment.center, - child: Column( - children: [ - Expanded( - flex: 1, - child: Text( - "Step 2/3", - style: TextStyle( - fontSize: 40 * heightFactor, fontWeight: FontWeight.w600), - ), - ), - Expanded( - flex: 1, - child: Icon(Icons.verified_user, - color: Colors.white, size: 65 * heightFactor), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment.center, - child: Text( - "Verify OTP", - style: TextStyle( - fontWeight: FontWeight.w300, - color: C.primaryHighlightedColor, - fontSize: heightFactor * 30, - ), - ), - ), - ), - Container( - padding: - EdgeInsets.fromLTRB(heightFactor * 10, 0, heightFactor * 10, 0), - alignment: Alignment.center, - child: Column( - children: [ - Text( - "An otp has been sent to the registered user", - style: TextStyle( - fontSize: heightFactor * 20, - ), - ), - Padding( - padding: EdgeInsets.only(top: 10 * heightFactor), - child: Text( - "email", - style: TextStyle( - fontSize: heightFactor * 20, - ), - )), - ], - ), - ), - ], - ), - ), - ), - Flexible( - flex: 3, - child: Column( - children: [ - //!OTP number fields - Padding( - padding: const EdgeInsets.only(top: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - otp1, - style: TextStyle(fontSize: 23), - ), - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: C.firstRing, - width: 2.5, - ), - ), - ), - Container( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - otp2, - style: TextStyle(fontSize: 23), - ), - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: C.secondRing, - width: 2.5, - ), - ), - ), - Container( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - otp3, - style: TextStyle(fontSize: 23), - ), - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: C.thirdRing, - width: 2.5, - ), - ), - ), - Container( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - otp4, - style: TextStyle(fontSize: 23), - ), - ), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: C.fourthRing, - width: 2.5, - ), - ), - ), - ], - ), - ), - Center( - child: RichText( - text: TextSpan( - text: "You can request another OTP in ", - children: [ - TextSpan( - text: "[Time]", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontWeight: FontWeight.w600, - )), - TextSpan( - text: "s", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontWeight: FontWeight.w600, - )), - ], - style: TextStyle( - fontSize: 15 * heightFactor, fontWeight: FontWeight.w300), - ), - ), - ), - - SizedBox(height: 30 * heightFactor), - //!Verify button - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - decoration: BoxDecoration( - border: Border.all( - color: Colors.white, - width: 2.0, - ), - borderRadius: BorderRadius.all(Radius.circular(30)), - boxShadow: [ - BoxShadow( - color: C.backgroundTop, - // blurRadius: 10, - //spreadRadius: 3, - //offset: Offset(0, 12), - ) - ], - ), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - ), - color: Colors.transparent, - onPressed: () => _verifyOtp(context, state), - child: Container( - height: 50, - width: 120, - alignment: Alignment.center, - child: Text( - "Resend", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontSize: 20 * heightFactor), - ), - ), - ), - ), - SizedBox( - width: 20 * heightFactor, - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(30)), - boxShadow: [ - BoxShadow( - color: C.authButtonColor.withOpacity(0.2), - blurRadius: 10, - spreadRadius: 3, - offset: Offset(0, 12), - ) - ], - ), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - ), - color: C.authButtonColor, - onPressed: () => _verifyOtp(context, state), - child: Container( - height: 54, - width: 124, - alignment: Alignment.center, - child: Text( - "Submit", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontSize: 20 * heightFactor), - ), - ), - ), - ), - ], - ), - ], - ), - ), - Flexible( - flex: 4, - child: NumericPad(onNumberSelected: _onNumSelected), - ), - SizedBox(height: heightFactor * 40) - ], - ), - ), - ), - ], - ), - ); - } - Widget _passwordResetSuccess() { return Center( child: Column( @@ -578,194 +154,25 @@ class _ForgotPasswordScreenState extends State { ); } - Widget _resetPassword(BuildContext context, ForgotPasswordState state) { - double height = MediaQuery.of(context).size.height; - double bottom = MediaQuery.of(context).viewInsets.bottom; - double heightFactor = height / 1000; - if (_scrollController.hasClients) { - if (bottom > height * 0.5) { - _scrollController.animateTo( - bottom - height * 0.5, - duration: Duration(milliseconds: 300), - curve: Curves.ease, - ); - } else { - _scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); - } - } - return DefaultTextStyle( - style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), - child: Stack( - children: [ - //background - ScreenBackground(elementId: 0), - SingleChildScrollView( - physics: NeverScrollableScrollPhysics(), - controller: _scrollController, - child: Container( - height: height * 1.25, - child: Column( - children: [ - //3/3 text - Expanded( - flex: 1, - child: Container( - padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), - alignment: Alignment.center, - child: Column( - children: [ - Expanded( - flex: 1, - child: Text( - "Step 3/3", - style: TextStyle( - fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), - ), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment.center, - child: Text( - "Reset Password", - style: TextStyle( - color: C.primaryHighlightedColor, - fontSize: heightFactor * 30, - ), - ), - ), - ), - Expanded( - flex: 1, - child: Container( - alignment: Alignment.center, - child: Text( - "Please enter your new password", - style: TextStyle( - fontSize: heightFactor * 25, - ), - ), - ), - ), - ], - ), - ), - ), - // password and confirm password fields - SizedBox( - height: 50, - ), - Expanded( - flex: 3, - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 40), - child: Column( - children: [ - PasswordField(passwordController), - SizedBox(height: 20 * heightFactor), - ConfirmPasswordField(confirmPasswordController), - ], - ), - ), - SizedBox(height: 20 * heightFactor), - Container( - padding: EdgeInsets.only(right: D.horizontalPadding), - alignment: Alignment.topRight, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(30)), - boxShadow: [ - BoxShadow( - color: C.authButtonColor.withOpacity(0.2), - blurRadius: 10, - spreadRadius: 3, - offset: Offset(0, 12), - ) - ], - ), - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - ), - color: C.authButtonColor, - onPressed: () => _changePassword(context, state), - child: Container( - height: 60, - width: 100, - alignment: Alignment.center, - child: Text( - "Reset", - style: TextStyle( - color: C.primaryUnHighlightedColor, - fontSize: 20 * heightFactor), - ), - ), - ), - ), - ), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ); - } - - void _sendOTP(BuildContext context, ForgotPasswordState state) { + _sendOTP(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.sendOTP(emailController.text, state); } - void _verifyOtp(BuildContext context, ForgotPasswordState state) { + _verifyOtp(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.checkOTP(otpEntered.substring(0, 4), state, emailController.text); } - void _changePassword(BuildContext context, ForgotPasswordState state) { + _changePassword(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.changePassword(emailController.text, otpEntered.substring(0, 4), passwordController.text, confirmPasswordController.text, state); } - void updateOTPBlocks() { - int length = otpEntered.length; - if (length == 0) { - otp1 = ""; - otp2 = ""; - otp3 = ""; - otp4 = ""; - } else if (length == 1) { - otp1 = otpEntered[0]; - otp2 = ""; - otp3 = ""; - otp4 = ""; - } else if (length == 2) { - otp1 = otpEntered[0]; - otp2 = otpEntered[1]; - otp3 = ""; - otp4 = ""; - } else if (length == 3) { - otp1 = otpEntered[0]; - otp2 = otpEntered[1]; - otp3 = otpEntered[2]; - otp4 = ""; - } else { - otp1 = otpEntered[0]; - otp2 = otpEntered[1]; - otp3 = otpEntered[2]; - otp4 = otpEntered[3]; - otpEntered = otpEntered.substring(0, 4); - } - } - _onNumSelected(int p1) { setState(() { + otpEntered = otpEntered.substring(0, 4); if (p1 == -1) { if (otpEntered.length > 0) { otpEntered = otpEntered.substring(0, otpEntered.length - 1); @@ -773,7 +180,6 @@ class _ForgotPasswordScreenState extends State { } else { otpEntered = otpEntered + p1.toString(); } - updateOTPBlocks(); }); } } diff --git a/lib/screens/forgot_password/reset_password.dart b/lib/screens/forgot_password/reset_password.dart new file mode 100644 index 0000000..35ceb81 --- /dev/null +++ b/lib/screens/forgot_password/reset_password.dart @@ -0,0 +1,162 @@ +import 'package:ecellapp/core/res/colors.dart'; +import 'package:ecellapp/core/res/dimens.dart'; +import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; +import 'package:ecellapp/widgets/password_field.dart'; +import 'package:ecellapp/widgets/screen_background.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import 'widgets/confirm_password.dart'; + +class ResetPassword extends StatelessWidget { + const ResetPassword({ + Key key, + this.onConfirm, + this.passwordController, + this.confirmPasswordController, + }) : super(key: key); + final Function(BuildContext context, ForgotPasswordState state) onConfirm; + final TextEditingController passwordController; + final TextEditingController confirmPasswordController; + @override + Widget build(BuildContext context) { + final ScrollController scrollController = ScrollController(); + + double height = MediaQuery.of(context).size.height; + double bottom = MediaQuery.of(context).viewInsets.bottom; + double heightFactor = height / 1000; + if (scrollController.hasClients) { + if (bottom > height * 0.5) { + scrollController.animateTo( + bottom - height * 0.5, + duration: Duration(milliseconds: 300), + curve: Curves.ease, + ); + } else { + scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); + } + } + return DefaultTextStyle( + style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), + child: Stack( + children: [ + //background + ScreenBackground(elementId: 0), + SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + controller: scrollController, + child: Container( + height: height * 1.25, + child: Column( + children: [ + //3/3 text + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.fromLTRB(0, heightFactor * 100, 0, 0), + alignment: Alignment.center, + child: Column( + children: [ + Expanded( + flex: 1, + child: Text( + "Step 3/3", + style: TextStyle( + fontSize: 35 * heightFactor, fontWeight: FontWeight.w600), + ), + ), + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Reset Password", + style: TextStyle( + color: C.primaryHighlightedColor, + fontSize: heightFactor * 30, + ), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + alignment: Alignment.center, + child: Text( + "Please enter your new password", + style: TextStyle( + fontSize: heightFactor * 25, + ), + ), + ), + ), + ], + ), + ), + ), + // password and confirm password fields + SizedBox( + height: 50, + ), + Expanded( + flex: 3, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 40), + child: Column( + children: [ + PasswordField(passwordController), + SizedBox(height: 20 * heightFactor), + ConfirmPasswordField(confirmPasswordController), + ], + ), + ), + SizedBox(height: 20 * heightFactor), + Container( + padding: EdgeInsets.only(right: D.horizontalPadding), + alignment: Alignment.topRight, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(30)), + boxShadow: [ + BoxShadow( + color: C.authButtonColor.withOpacity(0.2), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(0, 12), + ) + ], + ), + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + color: C.authButtonColor, + onPressed: () => onConfirm, + child: Container( + height: 60, + width: 100, + alignment: Alignment.center, + child: Text( + "Reset", + style: TextStyle( + color: C.primaryUnHighlightedColor, + fontSize: 20 * heightFactor), + ), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} From 745d43368f445e3baa56abe5ab686a056cb5135a Mon Sep 17 00:00:00 2001 From: treav Date: Sat, 13 Mar 2021 20:06:32 +0530 Subject: [PATCH 17/19] UI Fix --- lib/screens/forgot_password/ask_email.dart | 33 ++--- lib/screens/forgot_password/enter_otp.dart | 16 +-- .../forgot_password/forgot_password.dart | 115 +++++++----------- .../forgot_password_repository.dart | 6 +- .../forgot_password/reset_password.dart | 4 +- lib/screens/login/login.dart | 2 +- 6 files changed, 74 insertions(+), 102 deletions(-) diff --git a/lib/screens/forgot_password/ask_email.dart b/lib/screens/forgot_password/ask_email.dart index 74f7048..f629f2b 100644 --- a/lib/screens/forgot_password/ask_email.dart +++ b/lib/screens/forgot_password/ask_email.dart @@ -6,19 +6,15 @@ import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'cubit/forgot_password_cubit.dart'; - class AskEmailScreen extends StatelessWidget { - const AskEmailScreen({Key key, this.onSubmit, this.emailController}) : super(key: key); + AskEmailScreen({Key key, this.onSubmit, this.emailController}) : super(key: key); - final Function(BuildContext context, ForgotPasswordState state) onSubmit; + final Function onSubmit; final TextEditingController emailController; + ScrollController scrollController = ScrollController(); @override Widget build(BuildContext context) { - final ScrollController scrollController = ScrollController(); - final formKey = GlobalKey(); - double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; double bottom = MediaQuery.of(context).viewInsets.bottom; @@ -113,18 +109,15 @@ class AskEmailScreen extends StatelessWidget { ), ), SizedBox(height: 23 * heightFactor), - Form( - key: formKey, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), - child: Column( - children: [ - EmailField(emailController), - SizedBox(height: 20 * heightFactor), - SizedBox(height: 10 * heightFactor), - ], - ), - )), + Padding( + padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), + child: Column( + children: [ + EmailField(emailController), + SizedBox(height: 30 * heightFactor), + ], + ), + ), ], ), ), @@ -150,7 +143,7 @@ class AskEmailScreen extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(30)), ), color: C.authButtonColor, - onPressed: () => onSubmit, + onPressed: () => onSubmit(), child: Container( height: 60, width: 120, diff --git a/lib/screens/forgot_password/enter_otp.dart b/lib/screens/forgot_password/enter_otp.dart index e8c9964..bb522e1 100644 --- a/lib/screens/forgot_password/enter_otp.dart +++ b/lib/screens/forgot_password/enter_otp.dart @@ -1,5 +1,4 @@ import 'package:ecellapp/core/res/colors.dart'; -import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -9,7 +8,7 @@ import 'widgets/numeric_pad.dart'; class EnterOTPScreen extends StatelessWidget { const EnterOTPScreen({Key key, this.otp, this.toVerify, this.numSelected}) : super(key: key); - final Function(BuildContext context, ForgotPasswordState state) toVerify; + final Function toVerify; final Function(int) numSelected; final String otp; @@ -31,6 +30,7 @@ class EnterOTPScreen extends StatelessWidget { scrollController.animateTo(0, duration: Duration(milliseconds: 300), curve: Curves.ease); } } + print("OTPSCREEN: $otp"); return DefaultTextStyle( style: GoogleFonts.roboto().copyWith(color: C.primaryUnHighlightedColor), child: Stack( @@ -120,7 +120,7 @@ class EnterOTPScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16.0), child: Text( - otp[0] ?? "", + otp[0], style: TextStyle(fontSize: 23), ), ), @@ -136,7 +136,7 @@ class EnterOTPScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16.0), child: Text( - otp[1] ?? "", + otp[1], style: TextStyle(fontSize: 23), ), ), @@ -152,7 +152,7 @@ class EnterOTPScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16.0), child: Text( - otp[2] ?? "", + otp[2], style: TextStyle(fontSize: 23), ), ), @@ -168,7 +168,7 @@ class EnterOTPScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16.0), child: Text( - otp[3] ?? "", + otp[3], style: TextStyle(fontSize: 23), ), ), @@ -228,7 +228,7 @@ class EnterOTPScreen extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(30)), ), color: Colors.transparent, - onPressed: () => toVerify, + onPressed: () => toVerify(), child: Container( height: 50, width: 120, @@ -262,7 +262,7 @@ class EnterOTPScreen extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(30)), ), color: C.authButtonColor, - onPressed: () => toVerify, + onPressed: () => toVerify(), child: Container( height: 54, width: 124, diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 2f53d46..55ccc06 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -23,7 +23,7 @@ class _ForgotPasswordScreenState extends State { final TextEditingController emailController = TextEditingController(); final TextEditingController otpController = TextEditingController(); - String otpEntered = ""; + String otpEntered = " " * 4, finalOTP = ""; @override Widget build(BuildContext context) { @@ -41,81 +41,56 @@ class _ForgotPasswordScreenState extends State { ), ), backgroundColor: Colors.transparent, - body: BlocConsumer( - listener: (context, state) { - if (state is ForgotPasswordError) { - Scaffold.of(context).showSnackBar( - SnackBar(content: Text(state.message)), - ); - } - }, - builder: (context, state) { - return Stack( - children: [ - ScreenBackground(elementId: 0), - if (state is ForgotEmailInitial) - AskEmailScreen( - emailController: emailController, - onSubmit: _sendOTP(context, state), - ) - else if (state is ForgotLoading) - _buildLoading(context) - else if (state is ForgotOTPInitial) - EnterOTPScreen( - numSelected: _onNumSelected, - otp: otpEntered, - toVerify: _verifyOtp(context, state), - ) + body: Stack( + children: [ + ScreenBackground(elementId: 0), + BlocConsumer( + listener: (context, state) { + if (state is ForgotPasswordError) { + Scaffold.of(context).showSnackBar( + SnackBar(content: Text(state.message)), + ); + } + }, + builder: (context, state) { + if (state is ForgotLoading) + return _buildLoading(context); else if (state is ForgotPasswordError) - _uiUpdateForNetworkError(context, state.state) - else if (state is ForgotResetInitial) - ResetPassword( - onConfirm: _changePassword(context, state), - confirmPasswordController: confirmPasswordController, - passwordController: passwordController) + return _stepScreen(context, state.state); else if (state is ForgotResetSuccess) - _passwordResetSuccess() + return _passwordResetSuccess(); else - AskEmailScreen( - emailController: emailController, - onSubmit: _sendOTP(context, state), - ) - ], - ); - }, + return _stepScreen(context, state); + }, + ), + ], ), ); } - Widget _uiUpdateForNetworkError(BuildContext context, ForgotPasswordState state) { - if (state is ForgotEmailInitial) { + Widget _stepScreen(BuildContext context, ForgotPasswordState state) { + if (state is ForgotEmailInitial) return AskEmailScreen( emailController: emailController, - onSubmit: _sendOTP(context, state), + onSubmit: () => _sendOTP(context, state), ); - } else if (state is ForgotOTPInitial) { + else if (state is ForgotOTPInitial) return EnterOTPScreen( numSelected: _onNumSelected, otp: otpEntered, - toVerify: _verifyOtp(context, state), + toVerify: () => _verifyOtp(context, state), ); - } else if (state is ForgotPasswordError) { - return EnterOTPScreen( - numSelected: _onNumSelected, - otp: otpEntered, - toVerify: _verifyOtp(context, state), - ); - } else if (state is ForgotResetInitial) { + else if (state is ForgotResetInitial) return ResetPassword( - onConfirm: _changePassword(context, state), - confirmPasswordController: confirmPasswordController, - passwordController: passwordController); - } else { + onConfirm: () => _changePassword(context, state), + confirmPasswordController: confirmPasswordController, + passwordController: passwordController, + ); + else return AskEmailScreen( emailController: emailController, - onSubmit: _sendOTP(context, state), + onSubmit: () => _sendOTP(context, state), ); - } } Widget _buildLoading(BuildContext context) { @@ -154,31 +129,35 @@ class _ForgotPasswordScreenState extends State { ); } - _sendOTP(BuildContext context, ForgotPasswordState state) { + void _sendOTP(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.sendOTP(emailController.text, state); } - _verifyOtp(BuildContext context, ForgotPasswordState state) { + void _verifyOtp(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.checkOTP(otpEntered.substring(0, 4), state, emailController.text); } - _changePassword(BuildContext context, ForgotPasswordState state) { + void _changePassword(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); cubit.changePassword(emailController.text, otpEntered.substring(0, 4), passwordController.text, confirmPasswordController.text, state); } - _onNumSelected(int p1) { + _onNumSelected(int numEntered) { + int length = otpEntered.length; setState(() { - otpEntered = otpEntered.substring(0, 4); - if (p1 == -1) { - if (otpEntered.length > 0) { - otpEntered = otpEntered.substring(0, otpEntered.length - 1); + if (numEntered == -1) { + if (length > 0) { + finalOTP = finalOTP.substring(0, finalOTP.length - 1); + otpEntered = finalOTP + " " * (4 - finalOTP.length); + } + } else if (length < 5) { + if (finalOTP.length < 4) { + finalOTP += numEntered.toString(); } - } else { - otpEntered = otpEntered + p1.toString(); + otpEntered = finalOTP + " " * (4 - finalOTP.length); } }); } diff --git a/lib/screens/forgot_password/forgot_password_repository.dart b/lib/screens/forgot_password/forgot_password_repository.dart index ee6ea9a..08bb54a 100644 --- a/lib/screens/forgot_password/forgot_password_repository.dart +++ b/lib/screens/forgot_password/forgot_password_repository.dart @@ -18,7 +18,7 @@ class FakeForgotPasswordRepository extends ForgotPasswordRepository { @override // this is to simulate a delay for getting otp Future sendOTP(String email) async { - await Future.delayed(Duration(seconds: 2)); + await Future.delayed(Duration(seconds: 1)); if (Random().nextBool()) { return; } else { @@ -33,7 +33,7 @@ class FakeForgotPasswordRepository extends ForgotPasswordRepository { // this to simulate the process of otp verification @override Future checkOTP(String otp, String email) async { - await Future.delayed(Duration(seconds: 2)); + await Future.delayed(Duration(seconds: 1)); if (Random().nextBool()) { if (otp == "1234") { return; @@ -48,7 +48,7 @@ class FakeForgotPasswordRepository extends ForgotPasswordRepository { // this is to simulate the process of change in email @override Future changePassword(String email, String otp, String password) async { - await Future.delayed(Duration(seconds: 2)); + await Future.delayed(Duration(seconds: 1)); if (Random().nextBool()) { return; } else { diff --git a/lib/screens/forgot_password/reset_password.dart b/lib/screens/forgot_password/reset_password.dart index 35ceb81..6cb9db1 100644 --- a/lib/screens/forgot_password/reset_password.dart +++ b/lib/screens/forgot_password/reset_password.dart @@ -15,7 +15,7 @@ class ResetPassword extends StatelessWidget { this.passwordController, this.confirmPasswordController, }) : super(key: key); - final Function(BuildContext context, ForgotPasswordState state) onConfirm; + final Function onConfirm; final TextEditingController passwordController; final TextEditingController confirmPasswordController; @override @@ -133,7 +133,7 @@ class ResetPassword extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(30)), ), color: C.authButtonColor, - onPressed: () => onConfirm, + onPressed: () => onConfirm(), child: Container( height: 60, width: 100, diff --git a/lib/screens/login/login.dart b/lib/screens/login/login.dart index fccdcb4..b7691cc 100644 --- a/lib/screens/login/login.dart +++ b/lib/screens/login/login.dart @@ -141,7 +141,7 @@ class LoginScreen extends StatelessWidget { TextStyle(fontSize: 20 * heightFactor, color: C.secondaryColor), ), onTap: () { - Navigator.pushReplacementNamed(context, S.routeForgotPassword); + Navigator.pushNamed(context, S.routeForgotPassword); }, ), ) From 97bbf9833d39868e1c0b68958023712cd6e41fac Mon Sep 17 00:00:00 2001 From: treav Date: Sat, 13 Mar 2021 20:38:50 +0530 Subject: [PATCH 18/19] Final fix --- lib/screens/forgot_password/ask_email.dart | 4 +++- lib/screens/forgot_password/forgot_password.dart | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/screens/forgot_password/ask_email.dart b/lib/screens/forgot_password/ask_email.dart index f629f2b..e2f8711 100644 --- a/lib/screens/forgot_password/ask_email.dart +++ b/lib/screens/forgot_password/ask_email.dart @@ -143,7 +143,9 @@ class AskEmailScreen extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(30)), ), color: C.authButtonColor, - onPressed: () => onSubmit(), + onPressed: () { + onSubmit(); + }, child: Container( height: 60, width: 120, diff --git a/lib/screens/forgot_password/forgot_password.dart b/lib/screens/forgot_password/forgot_password.dart index 55ccc06..7e46ad5 100644 --- a/lib/screens/forgot_password/forgot_password.dart +++ b/lib/screens/forgot_password/forgot_password.dart @@ -131,16 +131,22 @@ class _ForgotPasswordScreenState extends State { void _sendOTP(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); - cubit.sendOTP(emailController.text, state); + bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") + .hasMatch(emailController.text); + if (emailValid) { + cubit.sendOTP(emailController.text, state); + } } void _verifyOtp(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); + cubit.checkOTP(otpEntered.substring(0, 4), state, emailController.text); } void _changePassword(BuildContext context, ForgotPasswordState state) { final cubit = context.read(); + cubit.changePassword(emailController.text, otpEntered.substring(0, 4), passwordController.text, confirmPasswordController.text, state); } From 053516935ded284753cc88f0ba7bbefbcb3ec987 Mon Sep 17 00:00:00 2001 From: treav Date: Sat, 13 Mar 2021 22:49:52 +0530 Subject: [PATCH 19/19] Check fix --- lib/screens/forgot_password/ask_email.dart | 12 +++++++++--- lib/screens/forgot_password/reset_password.dart | 1 - 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/screens/forgot_password/ask_email.dart b/lib/screens/forgot_password/ask_email.dart index e2f8711..1edacc0 100644 --- a/lib/screens/forgot_password/ask_email.dart +++ b/lib/screens/forgot_password/ask_email.dart @@ -6,11 +6,17 @@ import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; -class AskEmailScreen extends StatelessWidget { +class AskEmailScreen extends StatefulWidget { AskEmailScreen({Key key, this.onSubmit, this.emailController}) : super(key: key); final Function onSubmit; final TextEditingController emailController; + + @override + _AskEmailScreenState createState() => _AskEmailScreenState(); +} + +class _AskEmailScreenState extends State { ScrollController scrollController = ScrollController(); @override @@ -113,7 +119,7 @@ class AskEmailScreen extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: D.horizontalPadding), child: Column( children: [ - EmailField(emailController), + EmailField(widget.emailController), SizedBox(height: 30 * heightFactor), ], ), @@ -144,7 +150,7 @@ class AskEmailScreen extends StatelessWidget { ), color: C.authButtonColor, onPressed: () { - onSubmit(); + widget.onSubmit(); }, child: Container( height: 60, diff --git a/lib/screens/forgot_password/reset_password.dart b/lib/screens/forgot_password/reset_password.dart index 6cb9db1..ad51975 100644 --- a/lib/screens/forgot_password/reset_password.dart +++ b/lib/screens/forgot_password/reset_password.dart @@ -1,6 +1,5 @@ import 'package:ecellapp/core/res/colors.dart'; import 'package:ecellapp/core/res/dimens.dart'; -import 'package:ecellapp/screens/forgot_password/cubit/forgot_password_cubit.dart'; import 'package:ecellapp/widgets/password_field.dart'; import 'package:ecellapp/widgets/screen_background.dart'; import 'package:flutter/material.dart';