diff --git a/assets/images/img-success-signup.png b/assets/images/img-success-signup.png new file mode 100644 index 0000000..a85648d Binary files /dev/null and b/assets/images/img-success-signup.png differ diff --git a/lib/application/assets/path_assets.dart b/lib/application/assets/path_assets.dart index 3bfdc02..39e8eb8 100644 --- a/lib/application/assets/path_assets.dart +++ b/lib/application/assets/path_assets.dart @@ -23,4 +23,5 @@ class PathAssets { static const String imgKtpCropped = 'assets/images/img-ktp-cropped.png'; static const String imgKtpClear = 'assets/images/img-ktp-clear.png'; static const String imgKtpBlur = 'assets/images/img-ktp-blur.png'; + static const String imgSuccessSignup = 'assets/images/img-success-signup.png'; } diff --git a/lib/application/component/button/button_view.dart b/lib/application/component/button/button_view.dart index 19799b6..376dffa 100644 --- a/lib/application/component/button/button_view.dart +++ b/lib/application/component/button/button_view.dart @@ -55,78 +55,80 @@ class ButtonView extends StatelessWidget { final widthPrefix = this.widthPrefix ?? (heightWrapContent ? width! / 4.7 : _widthBtn / 16); - return Container( - margin: EdgeInsets.symmetric(vertical: marginVertical ?? 32.0), - width: width ?? _widthBtn, - height: heightWrapContent ? null : height ?? _heightBtn, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - disabledBackgroundColor: isOutlined ? Colors.white : color.surface, - padding: contentPadding, - backgroundColor: backgroundColor ?? - (isOutlined - ? Colors.white - : isSecondaryColor - ? ColorPalette.grey - : ColorPalette.primary), - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(sizeBorderRadius ?? 48), - side: isOutlined - ? BorderSide( - color: disabled - ? color.surface - : isSecondaryColor - ? ColorPalette.greyBorder - : ColorPalette.primary, - ) - : BorderSide.none, + return Center( + child: Container( + margin: EdgeInsets.symmetric(vertical: marginVertical ?? 24.0), + width: width ?? _widthBtn, + height: heightWrapContent ? null : height ?? _heightBtn, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + disabledBackgroundColor: isOutlined ? Colors.white : color.surface, + padding: contentPadding, + backgroundColor: backgroundColor ?? + (isOutlined + ? Colors.white + : isSecondaryColor + ? ColorPalette.grey + : ColorPalette.primary), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(sizeBorderRadius ?? 48), + side: isOutlined + ? BorderSide( + color: disabled + ? color.surface + : isSecondaryColor + ? ColorPalette.greyBorder + : ColorPalette.primary, + ) + : BorderSide.none, + ), ), - ), - onPressed: disabled ? null : onPressed, - child: Row( - mainAxisAlignment: mainAxisAlignmentContent ?? - (prefixIcon != null - ? MainAxisAlignment.center - : suffixIcon != null - ? MainAxisAlignment.end - : MainAxisAlignment.center), - children: [ - if (prefixIcon != null) ...[ - prefixIcon!, - SizedBox(width: widthPrefix), - ] else - Container(), - Flexible( - child: Text( - name, - textAlign: TextAlign.center, - maxLines: maxLines, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: textSize ?? 16, - fontWeight: textWeight, - color: textColor ?? - (disabled && isOutlined - ? color.primary - : disabled - ? Colors.white - : isOutlined && isSecondaryColor - ? ColorPalette.blackFont - : isOutlined - ? color.primary - : isSecondaryColor - ? Colors.white - : Colors.white), + onPressed: disabled ? null : onPressed, + child: Row( + mainAxisAlignment: mainAxisAlignmentContent ?? + (prefixIcon != null + ? MainAxisAlignment.center + : suffixIcon != null + ? MainAxisAlignment.end + : MainAxisAlignment.center), + children: [ + if (prefixIcon != null) ...[ + prefixIcon!, + SizedBox(width: widthPrefix), + ] else + Container(), + Flexible( + child: Text( + name, + textAlign: TextAlign.center, + maxLines: maxLines, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: textSize ?? 16, + fontWeight: textWeight, + color: textColor ?? + (disabled && isOutlined + ? color.primary + : disabled + ? Colors.white + : isOutlined && isSecondaryColor + ? ColorPalette.blackFont + : isOutlined + ? color.primary + : isSecondaryColor + ? Colors.white + : Colors.white), + ), ), ), - ), - if (suffixIcon != null) ...[ - SizedBox(width: widthSuffix), - suffixIcon! - ] else - Container() - ], + if (suffixIcon != null) ...[ + SizedBox(width: widthSuffix), + suffixIcon! + ] else + Container() + ], + ), ), ), ); diff --git a/lib/features/auth/registration/view/registration_password_view.dart b/lib/features/auth/registration/view/registration_password_view.dart new file mode 100644 index 0000000..032995b --- /dev/null +++ b/lib/features/auth/registration/view/registration_password_view.dart @@ -0,0 +1,151 @@ +import 'package:cims_apps/application/assets/path_assets.dart'; +import 'package:cims_apps/application/component/button/button_view.dart'; +import 'package:cims_apps/application/component/image/image_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/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/submission_data/submission_parent.dart'; +import 'package:cims_apps/features/auth/registration/viewmodel/registration_viewmodel.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class RegistrationPasswordView extends StatelessWidget { + const RegistrationPasswordView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => RegistrationViewModel(), + builder: (context, child) { + return Scaffold( + appBar: AppBar( + title: const Text('Sign Up'), + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Consumer( + builder: (context, provider, child) { + return Form( + key: provider.formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TextCaption( + title: 'Create your password', + subtitle: + 'The password you create serves as your login', + ), + TextFormView( + name: 'Password', + hintText: 'Input password', + ctrl: provider.passwordCtrl, + obscureText: !provider.showPassword, + validator: (value) { + if (value!.isEmpty) { + return 'Password must filled'; + } else { + return null; + } + }, + suffixIcon: GestureDetector( + onTap: () { + provider.toggleVisibility(); + }, + child: Icon( + provider.showPassword + ? Icons.visibility_off_outlined + : Icons.visibility_off_outlined, + color: ColorPalette.greyDarker, + ), + ), + ), + const SizedBox( + height: 32.0, + ), + TextFormView( + name: 'Confirm Password', + hintText: 'Input password', + ctrl: provider.confirmPasswordCtrl, + obscureText: !provider.showPasswordConfirm, + validator: (value) { + if (value!.isEmpty) { + return 'Password must filled'; + } else if (value != provider.passwordCtrl.text) { + return 'Password must be same'; + } else { + return null; + } + }, + suffixIcon: GestureDetector( + onTap: () { + provider.toggleVisibilityConfirm(); + }, + child: Icon( + provider.showPasswordConfirm + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, + color: ColorPalette.greyDarker, + ), + ), + ), + ButtonView( + name: 'Confirm', + onPressed: () { + if (provider.formKey.currentState!.validate()) { + routePush(context, page: const DialogSuccess()); + } + }, + ) + ], + ), + ); + }), + ), + ); + }); + } +} + +class DialogSuccess extends StatelessWidget { + const DialogSuccess({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ImageView( + image: PathAssets.imgSuccessSignup, + width: SizeConfig.width * .8, + ), + const TextCaption( + title: 'Success', + subtitle: + 'Congratulations, your account creation was successful!', + crossAxisAlignment: CrossAxisAlignment.center, + textAlignSubtitle: TextAlign.center, + ), + SizedBox( + height: SizeConfig.height * .2, + ), + ButtonView( + name: 'Next', + marginVertical: 8.0, + onPressed: () { + routePush(context, + page: const SubmissionParent(), + routeType: RouteType.pushReplace); + }, + ) + ], + ), + ), + ); + } +} diff --git a/lib/features/auth/registration/view/registration_view.dart b/lib/features/auth/registration/view/registration_view.dart index b98fb40..59d5f60 100644 --- a/lib/features/auth/registration/view/registration_view.dart +++ b/lib/features/auth/registration/view/registration_view.dart @@ -2,7 +2,7 @@ import 'package:cims_apps/application/component/button/button_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/initial_registration_step.dart'; +import 'package:cims_apps/features/auth/registration/view/registration_password_view.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -29,7 +29,7 @@ class RegistrationView extends StatelessWidget { ButtonView( name: 'Next', onPressed: () { - routePush(context, page: const InitialRegistrationStep()); + routePush(context, page: const RegistrationPasswordView()); }, ), Align( diff --git a/lib/features/auth/registration/view/submission_data/submission_parent.dart b/lib/features/auth/registration/view/submission_data/submission_parent.dart index 6c962f4..087e8dc 100644 --- a/lib/features/auth/registration/view/submission_data/submission_parent.dart +++ b/lib/features/auth/registration/view/submission_data/submission_parent.dart @@ -1,10 +1,12 @@ import 'package:cims_apps/application/component/button/button_view.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/submission_data/initial_take_photo.dart'; import 'package:cims_apps/features/auth/registration/view/submission_data/submit_email.dart'; import 'package:cims_apps/features/auth/registration/view/submission_data/submit_personal_data.dart'; import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart'; +import 'package:cims_apps/features/bottom_navigation_view.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -71,53 +73,63 @@ class _SubmissionParentState extends State { return ChangeNotifierProvider( create: (context) => SubmissionDataViewModel(), builder: (context, child) { - return Scaffold( - appBar: AppBar( - title: const Text('Registration'), - ), - body: Stack( - children: [ - Consumer( - builder: (context, provider, child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: List.generate( - provider.stepAmount, - (index) => _stepItem( - isCurrentStep: provider.currentStep == index + 1, + return WillPopScope( + onWillPop: () async { + await routePush(context, + page: const BottomNavigationView(), + routeType: RouteType.pushReplace); + return false; + }, + child: Scaffold( + appBar: AppBar( + title: const Text('Registration'), + ), + body: Stack( + children: [ + Consumer( + builder: (context, provider, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: List.generate( + provider.stepAmount, + (index) => _stepItem( + isCurrentStep: + provider.currentStep == index + 1, + ), ), ), ), - ), - Expanded( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: _content(provider.currentStep), + Expanded( + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 16.0), + child: _content(provider.currentStep), + ), ), - ), - provider.currentStep == 3 - ? const SizedBox() - : Align( - alignment: Alignment.bottomCenter, - child: ButtonView( - name: 'Next', - marginVertical: 16.0, - onPressed: () { - provider.nextSubmission(context); - }, - ), - ) - ], - ); - }), - ], + provider.currentStep == 3 + ? const SizedBox() + : Align( + alignment: Alignment.bottomCenter, + child: ButtonView( + name: 'Next', + marginVertical: 16.0, + onPressed: () { + provider.nextSubmission(context); + }, + ), + ) + ], + ); + }), + ], + ), ), ); }); diff --git a/lib/features/auth/registration/viewmodel/registration_viewmodel.dart b/lib/features/auth/registration/viewmodel/registration_viewmodel.dart new file mode 100644 index 0000000..c58548a --- /dev/null +++ b/lib/features/auth/registration/viewmodel/registration_viewmodel.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class RegistrationViewModel extends ChangeNotifier { + TextEditingController passwordCtrl = TextEditingController(); + TextEditingController confirmPasswordCtrl = TextEditingController(); + var formKey = GlobalKey(); + bool showPassword = false; + bool showPasswordConfirm = false; + + void toggleVisibility() { + showPassword = !showPassword; + notifyListeners(); + } + + void toggleVisibilityConfirm() { + showPasswordConfirm = !showPasswordConfirm; + notifyListeners(); + } +}