diff --git a/lib/application/component/button/button_view.dart b/lib/application/component/button/button_view.dart index 376dffa..8ea3823 100644 --- a/lib/application/component/button/button_view.dart +++ b/lib/application/component/button/button_view.dart @@ -76,7 +76,7 @@ class ButtonView extends StatelessWidget { side: isOutlined ? BorderSide( color: disabled - ? color.surface + ? ColorPalette.greyBorder : isSecondaryColor ? ColorPalette.greyBorder : ColorPalette.primary, diff --git a/lib/application/component/otp/otp_view.dart b/lib/application/component/otp/otp_view.dart new file mode 100644 index 0000000..d282b6b --- /dev/null +++ b/lib/application/component/otp/otp_view.dart @@ -0,0 +1,123 @@ +import 'package:cims_apps/application/component/button/button_view.dart'; +import 'package:cims_apps/application/component/otp/otp_viewmodel.dart'; +import 'package:cims_apps/application/component/text_caption/text_caption.dart'; +import 'package:cims_apps/application/theme/color_palette.dart'; +import 'package:cims_apps/core/route/route.dart'; +import 'package:cims_apps/core/utils/size_config.dart'; +import 'package:cims_apps/features/auth/registration/view/registration_password_view.dart'; +import 'package:flutter/material.dart'; +import 'package:pinput/pinput.dart'; +import 'package:provider/provider.dart'; + +class OtpView extends StatelessWidget { + final String title; + final String? contentTitle, contentSubtitle; + const OtpView({ + Key? key, + required this.title, + this.contentTitle, + this.contentSubtitle, + }) : super(key: key); + + Widget _otpContent(BuildContext context, OtpViewModel provider) { + return Form( + key: provider.formKey, + child: Column( + children: [ + Pinput( + length: 4, + controller: provider.ctrlPin, + focusNode: provider.focusNode, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + validator: (value) { + if (value!.isEmpty) { + return 'Pin must be complete'; + } + return null; + }, + defaultPinTheme: PinTheme( + textStyle: const TextStyle( + color: ColorPalette.slate800, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + width: SizeConfig.width * .19, + height: SizeConfig.height * .08, + decoration: BoxDecoration( + border: Border.all(color: const Color(0xFFE2E8F0)), + borderRadius: BorderRadius.circular(8), + ), + ), + errorPinTheme: PinTheme( + textStyle: const TextStyle( + color: ColorPalette.slate800, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + width: SizeConfig.width * .19, + height: SizeConfig.height * .08, + decoration: BoxDecoration( + border: Border.all(color: Colors.redAccent), + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ButtonView( + name: 'Verify', + // disabled: !provider.buttonIsActive, + // backgroundColor: ColorPalette.grey, + onPressed: () { + if (provider.formKey.currentState!.validate()) { + final pin = provider.ctrlPin.text; + provider.validateOtp(pin).then((value) { + if (value) { + routePush(context, + page: const RegistrationPasswordView(), + routeType: RouteType.pushReplace); + } else { + provider.ctrlPin.clear(); + } + }); + } + }, + ), + ], + )); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => OtpViewModel(), + builder: (context, child) { + return Scaffold( + appBar: AppBar( + title: Text(title), + ), + body: Container( + padding: const EdgeInsets.all(16.0), + child: + Consumer(builder: (context, provider, child) { + return Column( + children: [ + TextCaption( + title: contentTitle ?? '', + subtitle: contentSubtitle ?? '', + ), + _otpContent(context, provider), + TextButton( + onPressed: () {}, + child: const Text( + 'Resend Code', + style: TextStyle( + fontWeight: FontWeight.w700, + ), + )) + ], + ); + }), + ), + ); + }); + } +} diff --git a/lib/application/component/otp/otp_viewmodel.dart b/lib/application/component/otp/otp_viewmodel.dart new file mode 100644 index 0000000..851ec22 --- /dev/null +++ b/lib/application/component/otp/otp_viewmodel.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; + +class OtpViewModel extends ChangeNotifier { + var formKey = GlobalKey(); + var focusNode = FocusNode(); + bool buttonIsActive = false; + + TextEditingController ctrlPin = TextEditingController(); + + Future validateOtp(String pin) async { + final pinLength = pin.length; + if (pinLength == 4) { + return true; + } + return false; + } +} diff --git a/lib/application/component/text_caption/text_caption.dart b/lib/application/component/text_caption/text_caption.dart index 3b7e67e..00ab5b6 100644 --- a/lib/application/component/text_caption/text_caption.dart +++ b/lib/application/component/text_caption/text_caption.dart @@ -38,7 +38,7 @@ class TextCaption extends StatelessWidget { style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, - color: ColorPalette.slate800, + color: ColorPalette.slate500, ), ), ) diff --git a/lib/application/theme/color_palette.dart b/lib/application/theme/color_palette.dart index 724bd85..90ea85b 100644 --- a/lib/application/theme/color_palette.dart +++ b/lib/application/theme/color_palette.dart @@ -73,5 +73,6 @@ class ColorPalette { static const Color chathamsBlue = Color(0xFF285BB9); static const Color background = Color(0xFFDADADA); static const Color backgroundBlueLight = Color(0xFFEBF3FD); + static const Color slate500 = Color(0xFF64748B); static const Color slate800 = Color(0xFF1E293B); } diff --git a/lib/features/auth/registration/view/registration_view.dart b/lib/features/auth/registration/view/registration_view.dart index 59d5f60..0c60c17 100644 --- a/lib/features/auth/registration/view/registration_view.dart +++ b/lib/features/auth/registration/view/registration_view.dart @@ -1,8 +1,7 @@ import 'package:cims_apps/application/component/button/button_view.dart'; +import 'package:cims_apps/application/component/otp/otp_view.dart'; import 'package:cims_apps/application/component/text_caption/text_caption.dart'; import 'package:cims_apps/application/component/text_form/text_form_view.dart'; -import 'package:cims_apps/core/route/route.dart'; -import 'package:cims_apps/features/auth/registration/view/registration_password_view.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -12,6 +11,30 @@ class RegistrationView extends StatelessWidget { @override Widget build(BuildContext context) { + _showOtpWidget() { + Navigator.of(context).pop(); + showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: false, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + top: MediaQueryData.fromView( + WidgetsBinding.instance.window, + ).padding.top, + ), + child: const OtpView( + title: 'Sign Up', + contentTitle: 'Check your SMS', + contentSubtitle: + 'Enter 4 digit code We’ve sent to verify your phone number', + ), + ); + }, + ); + } + return Scaffold( appBar: AppBar( title: const Text('Sign Up'), @@ -29,7 +52,9 @@ class RegistrationView extends StatelessWidget { ButtonView( name: 'Next', onPressed: () { - routePush(context, page: const RegistrationPasswordView()); + _showOtpWidget(); + + // routePush(context, page: const RegistrationPasswordView()); }, ), Align( diff --git a/pubspec.lock b/pubspec.lock index ae75197..2ab6860 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -163,6 +163,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" http: dependency: transitive description: @@ -323,6 +328,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + pinput: + dependency: "direct main" + description: + name: pinput + sha256: "543da5bfdefd9e06914a12100f8c9156f84cef3efc14bca507c49e966c5b813b" + url: "https://pub.dev" + source: hosted + version: "2.3.0" platform: dependency: transitive description: @@ -376,6 +389,14 @@ packages: description: flutter source: sdk version: "0.0.99" + smart_auth: + dependency: transitive + description: + name: smart_auth + sha256: a25229b38c02f733d0a4e98d941b42bed91a976cb589e934895e60ccfa674cf6 + url: "https://pub.dev" + source: hosted + version: "1.1.1" source_span: dependency: transitive description: @@ -464,6 +485,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: d315be0f6641898b280ffa34e2ddb14f3d12b1a37882557869646e0cc363d0cc + url: "https://pub.dev" + source: hosted + version: "1.0.0+1" uuid: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 39356dc..2864079 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,8 @@ dependencies: cached_network_image: ^3.2.3 remove_emoji_input_formatter: ^0.0.1+1 provider: ^6.1.1 + pinput: ^2.2.21 +