diff --git a/assets/icons/icon-lock.png b/assets/icons/icon-lock.png new file mode 100644 index 0000000..6690e35 Binary files /dev/null and b/assets/icons/icon-lock.png differ diff --git a/lib/application/assets/path_assets.dart b/lib/application/assets/path_assets.dart index 449440f..770064a 100644 --- a/lib/application/assets/path_assets.dart +++ b/lib/application/assets/path_assets.dart @@ -39,6 +39,7 @@ class PathAssets { static const String iconCreatePlan = 'assets/icons/icon-create-plan.png'; static const String iconChecklistOutlined = 'assets/icons/icon-ceklis-outline.png'; + static const String iconLock = 'assets/icons/icon-lock.png'; /// IMAGE static const String imgSplashLogo = 'assets/images/splash-logo.png'; diff --git a/lib/application/component/set_pin_view/set_pin_view.dart b/lib/application/component/set_pin_view/set_pin_view.dart new file mode 100644 index 0000000..d2a4626 --- /dev/null +++ b/lib/application/component/set_pin_view/set_pin_view.dart @@ -0,0 +1,135 @@ +import 'package:cims_apps/application/assets/path_assets.dart'; +import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart'; +import 'package:cims_apps/application/component/image/image_view.dart'; +import 'package:cims_apps/application/component/set_pin_view/set_pin_viewmodel.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_success_view.dart'; +import 'package:flutter/material.dart'; +import 'package:pinput/pinput.dart'; +import 'package:provider/provider.dart'; + +class SetPinView extends StatelessWidget { + final String currentPin; + final void Function(BuildContext context, String pin) submitPin; + + const SetPinView({ + Key? key, + required this.currentPin, + required this.submitPin, + }) : super(key: key); + + Widget _stepItem({bool isCurrentStep = false, bool isDone = false}) { + return Container( + margin: + const EdgeInsets.only(right: 4.0, left: 4.0, top: 16.0, bottom: 40.0), + height: 6, + width: SizeConfig.width * .08, + decoration: BoxDecoration( + color: isCurrentStep || isDone + ? ColorPalette.primary + : ColorPalette.greyBorderNeutrals, + borderRadius: BorderRadius.circular(50), + ), + ); + } + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + final pinInputController = TextEditingController(); + const pinInputLength = 6; + const defaultPinTheme = PinTheme( + margin: EdgeInsets.symmetric(horizontal: 4.0, vertical: 16.0), + textStyle: TextStyle( + fontSize: 22, + color: Colors.black, + fontWeight: FontWeight.w600, + ), + decoration: BoxDecoration(), + ); + + final pInputFocusNode = FocusNode(); + + final focusedPinTheme = defaultPinTheme.copyWith( + decoration: defaultPinTheme.decoration?.copyWith(), + ); + + final submittedPinTheme = defaultPinTheme.copyWith( + decoration: defaultPinTheme.decoration?.copyWith(), + ); + final followingPinTheme = defaultPinTheme.copyWith( + width: 13, + height: 13, + textStyle: const TextStyle( + fontSize: 16, + color: Color.fromRGBO(30, 60, 87, 1), + fontWeight: FontWeight.w600, + ), + decoration: defaultPinTheme.decoration?.copyWith( + color: ColorPalette.white, + border: Border.all(color: ColorPalette.slate300), + borderRadius: BorderRadius.circular(100), + ), + ); + return ChangeNotifierProvider( + create: (context) => SetPinViewModel(), + builder: (context, child) { + return Scaffold( + appBar: CustomAppBar( + height: SizeConfig.height * .1, title: 'Registration'), + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Consumer( + builder: (context, provider, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: List.generate( + 9, + (index) => _stepItem(isCurrentStep: true, isDone: true), + ), + ), + ImageView( + image: PathAssets.iconLock, + width: SizeConfig.width * .15, + ), + Text( + !provider.isPinCompleted + ? 'Set your PIN' + : 'Confirm your PIN', + style: textTheme.headlineLarge, + ), + Pinput( + onCompleted: (pin) { + if (!provider.isPinCompleted) { + provider.changePin(); + pinInputController.clear(); + } else { + routePush(context, + routeType: RouteType.pushReplace, + page: const RegistrationSuccessView()); + } + }, + keyboardType: TextInputType.number, + obscureText: true, + autofocus: true, + isCursorAnimationEnabled: false, + length: pinInputLength, + controller: pinInputController, + defaultPinTheme: defaultPinTheme, + focusNode: pInputFocusNode, + focusedPinTheme: focusedPinTheme, + submittedPinTheme: submittedPinTheme, + followingPinTheme: followingPinTheme, + ), + ], + ); + }), + ), + ); + }); + } +} diff --git a/lib/application/component/set_pin_view/set_pin_viewmodel.dart b/lib/application/component/set_pin_view/set_pin_viewmodel.dart new file mode 100644 index 0000000..d1142a0 --- /dev/null +++ b/lib/application/component/set_pin_view/set_pin_viewmodel.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; + +class SetPinViewModel extends ChangeNotifier { + bool isPinCompleted = false; + void changePin() { + isPinCompleted = !isPinCompleted; + notifyListeners(); + } +} diff --git a/lib/features/auth/registration/view/submission_data/terms_and_condition/terms_and_condition_view.dart b/lib/features/auth/registration/view/submission_data/terms_and_condition/terms_and_condition_view.dart index 88524b6..abe5406 100644 --- a/lib/features/auth/registration/view/submission_data/terms_and_condition/terms_and_condition_view.dart +++ b/lib/features/auth/registration/view/submission_data/terms_and_condition/terms_and_condition_view.dart @@ -1,8 +1,8 @@ import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart'; import 'package:cims_apps/application/component/button/button_view.dart'; +import 'package:cims_apps/application/component/set_pin_view/set_pin_view.dart'; import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/core/route/route.dart'; -import 'package:cims_apps/features/auth/registration/view/submission_data/submission_parent.dart'; import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -90,7 +90,10 @@ class TermsAndConditionView extends StatelessWidget { onPressed: () { provider.nextSubmission(context); routePush(context, - page: const SubmissionParent()); + page: SetPinView( + currentPin: '', + submitPin: (context, pin) {}, + )); }, marginVertical: 16)) ], diff --git a/lib/main.dart b/lib/main.dart index 2755a41..4d24d24 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -33,6 +33,38 @@ class MyApp extends StatelessWidget { )), fontFamily: 'Manrope', scaffoldBackgroundColor: Colors.white, + textTheme: const TextTheme( + headlineSmall: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: ColorPalette.slate800, + ), + headlineLarge: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: ColorPalette.slate800, + ), + displayMedium: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: ColorPalette.slate800, + ), + displayLarge: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: ColorPalette.slate800, + ), + bodyMedium: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: ColorPalette.slate500, + ), + bodyLarge: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: ColorPalette.slate500, + ), + ), colorScheme: const ColorScheme.light().copyWith( primary: const Color(0xff2563EB), onPrimary: const Color(0xFFFF9130),