diff --git a/assets/icons/success-white.svg b/assets/icons/success-white.svg new file mode 100644 index 0000000..ae7e99d --- /dev/null +++ b/assets/icons/success-white.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lib/features/auth/bloc/auth_cubit.dart b/lib/features/auth/bloc/auth_cubit.dart index 2b1ae24..c6d37e4 100644 --- a/lib/features/auth/bloc/auth_cubit.dart +++ b/lib/features/auth/bloc/auth_cubit.dart @@ -241,14 +241,16 @@ class AuthCubit extends Cubit { } } - reSendOtp() async { + Future reSendOtp() async { try { emit(AuthLoading()); await AuthenticationAPI.sendOtp( body: {'email': email, 'type': 'VERIFICATION'}); emit(ResendOtpSuccess()); + return true; } catch (_) { emit(AuthLoginError(message: 'Something went wrong')); + return false; } } diff --git a/lib/features/auth/view/otp_view.dart b/lib/features/auth/view/otp_view.dart index e8ca1da..f74f22e 100644 --- a/lib/features/auth/view/otp_view.dart +++ b/lib/features/auth/view/otp_view.dart @@ -8,6 +8,7 @@ import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/features/auth/view/create_new_password.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; +import 'package:syncrow_app/features/shared_widgets/success_dialog.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/navigation/routing_constants.dart'; @@ -40,13 +41,19 @@ class _OtpViewState extends State { _lifecycleEventHandler = LifecycleEventHandler( resumeCallBack: () async { SharedPreferencesHelper.saveBoolToSP('timeStampSaved', false); - String timeStampInBackground = await SharedPreferencesHelper.readStringFromSP('timeStamp'); - int savedCounter = await SharedPreferencesHelper.readIntFromSP('savedCounter'); + String timeStampInBackground = + await SharedPreferencesHelper.readStringFromSP('timeStamp'); + int savedCounter = + await SharedPreferencesHelper.readIntFromSP('savedCounter'); DateTime currentTime = DateTime.now(); int differenceInSeconds = timeStampInBackground.isNotEmpty - ? currentTime.difference(DateTime.parse(timeStampInBackground)).inSeconds + ? currentTime + .difference(DateTime.parse(timeStampInBackground)) + .inSeconds : 0; - remainingSec = differenceInSeconds > savedCounter ? 0 : savedCounter - differenceInSeconds; + remainingSec = differenceInSeconds > savedCounter + ? 0 + : savedCounter - differenceInSeconds; timerStarted = true; startTimer(remainingSec ?? 0); return; @@ -75,7 +82,8 @@ class _OtpViewState extends State { } handleTimerOnBackground() async { - bool timeStampSaved = await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false; + bool timeStampSaved = + await SharedPreferencesHelper.readBoolFromSP('timeStampSaved') ?? false; if (!timeStampSaved) { final dateInString = DateTime.now().toString(); SharedPreferencesHelper.saveIntToSP('savedCounter', remainingSec ?? 0); @@ -115,7 +123,8 @@ class _OtpViewState extends State { @override Widget build(BuildContext context) { - String maskedEmail = AuthCubit.get(context).maskEmail(AuthCubit.get(context).email); + String maskedEmail = + AuthCubit.get(context).maskEmail(AuthCubit.get(context).email); return BlocConsumer( listener: (context, state) { if (state is AuthOtpSuccess) { @@ -199,7 +208,10 @@ class _OtpViewState extends State { child: RichText( text: TextSpan( text: 'We have sent the verification code to', - style: Theme.of(context).textTheme.titleSmall!.copyWith( + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith( color: Colors.white, fontWeight: FontsManager.regular, fontSize: 14, @@ -207,7 +219,10 @@ class _OtpViewState extends State { children: [ TextSpan( text: ' $maskedEmail', - style: Theme.of(context).textTheme.titleSmall!.copyWith( + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith( color: Colors.black, fontWeight: FontsManager.bold, fontSize: 14, @@ -215,7 +230,10 @@ class _OtpViewState extends State { ), TextSpan( text: ' change email?', - style: Theme.of(context).textTheme.titleSmall!.copyWith( + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith( color: const Color(0xFF87C7FF), fontWeight: FontsManager.regular, fontSize: 14, @@ -239,7 +257,8 @@ class _OtpViewState extends State { keyboardType: TextInputType.number, autoFocus: true, backgroundColor: Colors.transparent, - animationDuration: const Duration(milliseconds: 30), + animationDuration: + const Duration(milliseconds: 30), beforeTextPaste: (text) { // Allow pasting only if all characters are numeric return int.tryParse(text!) != null; @@ -262,18 +281,27 @@ class _OtpViewState extends State { errorBorderWidth: 1, borderWidth: 1, errorBorderColor: Colors.red, - activeColor: state is AuthLoginError ? Colors.red : Colors.white, - inactiveColor: - state is AuthLoginError ? Colors.red : Colors.white, - activeFillColor: - state is AuthLoginError ? Colors.red : Colors.white, - inactiveFillColor: - state is AuthLoginError ? Colors.red : Colors.white, - selectedFillColor: - state is AuthLoginError ? Colors.red : Colors.white, + activeColor: state is AuthLoginError + ? Colors.red + : Colors.white, + inactiveColor: state is AuthLoginError + ? Colors.red + : Colors.white, + activeFillColor: state is AuthLoginError + ? Colors.red + : Colors.white, + inactiveFillColor: state is AuthLoginError + ? Colors.red + : Colors.white, + selectedFillColor: state is AuthLoginError + ? Colors.red + : Colors.white, disabledColor: Colors.white, fieldHeight: 56, - fieldWidth: MediaQuery.sizeOf(context).width > 340 ? 40 : 20, + fieldWidth: + MediaQuery.sizeOf(context).width > 340 + ? 40 + : 20, // fieldWidth: 40, selectedColor: Colors.white, shape: PinCodeFieldShape.box, @@ -295,10 +323,12 @@ class _OtpViewState extends State { isDone: state is AuthLoginSuccess, isLoading: state is AuthLoading, customButtonStyle: ButtonStyle( - backgroundColor: MaterialStateProperty.all( + backgroundColor: + MaterialStateProperty.all( Colors.black.withOpacity(.25), ), - foregroundColor: MaterialStateProperty.all( + foregroundColor: + MaterialStateProperty.all( Colors.white, ), ), @@ -307,7 +337,8 @@ class _OtpViewState extends State { ), onPressed: () { if ((state is! AuthLoading)) { - AuthCubit.get(context).verifyOtp(widget.isForgetPage); + AuthCubit.get(context) + .verifyOtp(widget.isForgetPage); FocusScope.of(context).unfocus(); } }, @@ -321,10 +352,12 @@ class _OtpViewState extends State { isDone: state is AuthLoginSuccess, isLoading: state is AuthLoading, customButtonStyle: ButtonStyle( - backgroundColor: MaterialStateProperty.all( + backgroundColor: + MaterialStateProperty.all( Colors.black.withOpacity(.25), ), - foregroundColor: MaterialStateProperty.all( + foregroundColor: + MaterialStateProperty.all( Colors.white, ), ), @@ -341,8 +374,20 @@ class _OtpViewState extends State { return; } if ((state is! AuthLoading)) { - await AuthCubit.get(context).reSendOtp(); + bool success = await AuthCubit.get(context) + .reSendOtp(); FocusScope.of(context).unfocus(); + if(success){ + showDialog( + context: context, + builder: (_) => SuccessDialog( + key: ValueKey('SuccessDialog'), + message: 'New OTP sent!',)); + } + Future.delayed(Duration(seconds: 2), + () { + Navigator.of(context).pop(); + }); } }, ), diff --git a/lib/features/shared_widgets/success_dialog.dart b/lib/features/shared_widgets/success_dialog.dart new file mode 100644 index 0000000..ca1112a --- /dev/null +++ b/lib/features/shared_widgets/success_dialog.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; + +class SuccessDialog extends StatelessWidget { + final double dialogWidth; + final String message; + + const SuccessDialog( + {super.key, this.dialogWidth = 160, required this.message}); + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.transparent, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + child: Container( + width: dialogWidth, + height: 120, + decoration: BoxDecoration( + color: ColorsManager.blackColor.withOpacity(0.7), + borderRadius: BorderRadius.circular(15), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.assetsSuccessWhite, + width: 50, + height: 50, + ), + const SizedBox(height: 20), + BodySmall( + text: message, + fontColor: ColorsManager.onPrimaryColor, + fontSize: FontSize.s16), + ], + ), + ), + ); + } +} diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 509443d..5370a48 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -733,6 +733,10 @@ class Assets { static const String playIcon = "assets/icons/play_ic.svg"; static const String gatewayIcon = "assets/icons/gateway_icon.svg"; + //assets/icons/success-white.svg + //assets for success white image + static const String assetsSuccessWhite ="assets/icons/success-white.svg"; + /// Assets for assetsImagesAutomation /// assets/images/automation.jpg static const String assetsImagesAutomation = "assets/images/automation.jpg";