bayu/dev #2
| @@ -76,7 +76,7 @@ class ButtonView extends StatelessWidget { | |||||||
|               side: isOutlined |               side: isOutlined | ||||||
|                   ? BorderSide( |                   ? BorderSide( | ||||||
|                       color: disabled |                       color: disabled | ||||||
|                           ? color.surface |                           ? ColorPalette.greyBorder | ||||||
|                           : isSecondaryColor |                           : isSecondaryColor | ||||||
|                               ? ColorPalette.greyBorder |                               ? ColorPalette.greyBorder | ||||||
|                               : ColorPalette.primary, |                               : ColorPalette.primary, | ||||||
|   | |||||||
							
								
								
									
										123
									
								
								lib/application/component/otp/otp_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								lib/application/component/otp/otp_view.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -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<OtpViewModel>(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, | ||||||
|  |                           ), | ||||||
|  |                         )) | ||||||
|  |                   ], | ||||||
|  |                 ); | ||||||
|  |               }), | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         }); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								lib/application/component/otp/otp_viewmodel.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/application/component/otp/otp_viewmodel.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | class OtpViewModel extends ChangeNotifier { | ||||||
|  |   var formKey = GlobalKey<FormState>(); | ||||||
|  |   var focusNode = FocusNode(); | ||||||
|  |   bool buttonIsActive = false; | ||||||
|  |  | ||||||
|  |   TextEditingController ctrlPin = TextEditingController(); | ||||||
|  |  | ||||||
|  |   Future<bool> validateOtp(String pin) async { | ||||||
|  |     final pinLength = pin.length; | ||||||
|  |     if (pinLength == 4) { | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -38,7 +38,7 @@ class TextCaption extends StatelessWidget { | |||||||
|                     style: const TextStyle( |                     style: const TextStyle( | ||||||
|                       fontSize: 16, |                       fontSize: 16, | ||||||
|                       fontWeight: FontWeight.w500, |                       fontWeight: FontWeight.w500, | ||||||
|                       color: ColorPalette.slate800, |                       color: ColorPalette.slate500, | ||||||
|                     ), |                     ), | ||||||
|                   ), |                   ), | ||||||
|                 ) |                 ) | ||||||
|   | |||||||
| @@ -73,5 +73,6 @@ class ColorPalette { | |||||||
|   static const Color chathamsBlue = Color(0xFF285BB9); |   static const Color chathamsBlue = Color(0xFF285BB9); | ||||||
|   static const Color background = Color(0xFFDADADA); |   static const Color background = Color(0xFFDADADA); | ||||||
|   static const Color backgroundBlueLight = Color(0xFFEBF3FD); |   static const Color backgroundBlueLight = Color(0xFFEBF3FD); | ||||||
|  |   static const Color slate500 = Color(0xFF64748B); | ||||||
|   static const Color slate800 = Color(0xFF1E293B); |   static const Color slate800 = Color(0xFF1E293B); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| import 'package:cims_apps/application/component/button/button_view.dart'; | 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_caption/text_caption.dart'; | ||||||
| import 'package:cims_apps/application/component/text_form/text_form_view.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/gestures.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
| @@ -12,6 +11,30 @@ class RegistrationView extends StatelessWidget { | |||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   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( |     return Scaffold( | ||||||
|       appBar: AppBar( |       appBar: AppBar( | ||||||
|         title: const Text('Sign Up'), |         title: const Text('Sign Up'), | ||||||
| @@ -29,7 +52,9 @@ class RegistrationView extends StatelessWidget { | |||||||
|             ButtonView( |             ButtonView( | ||||||
|               name: 'Next', |               name: 'Next', | ||||||
|               onPressed: () { |               onPressed: () { | ||||||
|                 routePush(context, page: const RegistrationPasswordView()); |                 _showOtpWidget(); | ||||||
|  |  | ||||||
|  |                 // routePush(context, page: const RegistrationPasswordView()); | ||||||
|               }, |               }, | ||||||
|             ), |             ), | ||||||
|             Align( |             Align( | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -163,6 +163,11 @@ packages: | |||||||
|     description: flutter |     description: flutter | ||||||
|     source: sdk |     source: sdk | ||||||
|     version: "0.0.0" |     version: "0.0.0" | ||||||
|  |   flutter_web_plugins: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: flutter | ||||||
|  |     source: sdk | ||||||
|  |     version: "0.0.0" | ||||||
|   http: |   http: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -323,6 +328,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.0.2" |     version: "6.0.2" | ||||||
|  |   pinput: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: pinput | ||||||
|  |       sha256: "543da5bfdefd9e06914a12100f8c9156f84cef3efc14bca507c49e966c5b813b" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "2.3.0" | ||||||
|   platform: |   platform: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -376,6 +389,14 @@ packages: | |||||||
|     description: flutter |     description: flutter | ||||||
|     source: sdk |     source: sdk | ||||||
|     version: "0.0.99" |     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: |   source_span: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -464,6 +485,14 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.3.2" |     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: |   uuid: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|   | |||||||
| @@ -40,6 +40,8 @@ dependencies: | |||||||
|   cached_network_image: ^3.2.3 |   cached_network_image: ^3.2.3 | ||||||
|   remove_emoji_input_formatter: ^0.0.1+1 |   remove_emoji_input_formatter: ^0.0.1+1 | ||||||
|   provider: ^6.1.1 |   provider: ^6.1.1 | ||||||
|  |   pinput: ^2.2.21 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user