diff --git a/assets/icons/icon-question.png b/assets/icons/icon-question.png new file mode 100644 index 0000000..23c5881 Binary files /dev/null and b/assets/icons/icon-question.png differ diff --git a/assets/images/img-guide-bank.png b/assets/images/img-guide-bank.png new file mode 100644 index 0000000..c2aca7a Binary files /dev/null and b/assets/images/img-guide-bank.png differ diff --git a/assets/images/img-guide1.png b/assets/images/img-guide1.png new file mode 100644 index 0000000..08dbe0e Binary files /dev/null and b/assets/images/img-guide1.png differ diff --git a/assets/images/img-guide2.png b/assets/images/img-guide2.png new file mode 100644 index 0000000..b3347ab Binary files /dev/null and b/assets/images/img-guide2.png differ diff --git a/lib/application/assets/path_assets.dart b/lib/application/assets/path_assets.dart index ed0d088..9bccc8c 100644 --- a/lib/application/assets/path_assets.dart +++ b/lib/application/assets/path_assets.dart @@ -10,10 +10,14 @@ class PathAssets { static const String iconGoogle = 'assets/icons/icon-google.png'; static const String icon1 = 'assets/icons/icon-1.png'; static const String iconConnect = 'assets/icons/icon-connect.png'; - static const String iconPortofolioBonds = 'assets/icons/icon-portofolio-bonds.png'; - static const String iconPortofolioShares = 'assets/icons/icon-portofolio-shares.png'; - static const String iconPortofolioSharia = 'assets/icons/icon-portofolio-sharia.png'; - static const String iconPortofolioMoneyMarket = 'assets/icons/icon-portofolio-moneymarket.png'; + static const String iconPortofolioBonds = + 'assets/icons/icon-portofolio-bonds.png'; + static const String iconPortofolioShares = + 'assets/icons/icon-portofolio-shares.png'; + static const String iconPortofolioSharia = + 'assets/icons/icon-portofolio-sharia.png'; + static const String iconPortofolioMoneyMarket = + 'assets/icons/icon-portofolio-moneymarket.png'; static const String iconShield = 'assets/icons/icon-shield.png'; static const String iconFlag = 'assets/icons/icon-flag.png'; static const String iconKtp1 = 'assets/icons/icon-ktp1.png'; @@ -28,6 +32,7 @@ class PathAssets { static const String iconBalance = 'assets/icons/icon-balance.png'; static const String iconMoneyReceive = 'assets/icons/icon-money-receive.png'; static const String iconCoins = 'assets/icons/icon-coins.png'; + static const String iconQuestion = 'assets/icons/icon-question.png'; /// IMAGE static const String imgSplashLogo = 'assets/images/splash-logo.png'; @@ -40,7 +45,8 @@ 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 imgDashboardAccount = 'assets/images/img-dashboard-account.png'; + static const String imgDashboardAccount = + 'assets/images/img-dashboard-account.png'; static const String imgCarousel = 'assets/images/img-carousel.png'; static const String imgArticles = 'assets/images/img-articles.png'; static const String imgProduct = 'assets/images/img-product.png'; @@ -49,11 +55,15 @@ class PathAssets { static const String imgBgSelfie = 'assets/images/img-bg-photo-selfie.png'; static const String imgDataReport = 'assets/images/img-data-report.png'; static const String imgDataAnalysis = 'assets/images/img-data-analysis.png'; - static const String imgBusinessFailure = 'assets/images/img-business-failure.png'; + static const String imgBusinessFailure = + 'assets/images/img-business-failure.png'; static const String imgLeader = 'assets/images/img-leader.png'; static const String imgMoneyIncome = 'assets/images/img-money-income.png'; static const String imgGrowing = 'assets/images/img-growing.png'; static const String imgCat = 'assets/images/img-cat.png'; static const String imgDeer = 'assets/images/img-deer.png'; static const String imgLion = 'assets/images/img-lion.png'; + static const String imgGuideBank = 'assets/images/img-guide-bank.png'; + static const String imgGuide1 = 'assets/images/img-guide1.png'; + static const String imgGuide2 = 'assets/images/img-guide2.png'; } diff --git a/lib/application/component/take_picture_screen/DisplayPictureScreen.dart b/lib/application/component/take_picture_screen/display_picture_screen.dart similarity index 95% rename from lib/application/component/take_picture_screen/DisplayPictureScreen.dart rename to lib/application/component/take_picture_screen/display_picture_screen.dart index 417d161..eee0650 100644 --- a/lib/application/component/take_picture_screen/DisplayPictureScreen.dart +++ b/lib/application/component/take_picture_screen/display_picture_screen.dart @@ -112,7 +112,7 @@ class DisplayPictureScreen extends StatelessWidget { children: [ Container( width: SizeConfig.width * .42, - height: SizeConfig.height * .15, + height: SizeConfig.height * .13, padding: const EdgeInsets.symmetric( vertical: 8.0, horizontal: 8.0), decoration: BoxDecoration( @@ -162,7 +162,9 @@ class DisplayPictureScreen extends StatelessWidget { provider.initCamera().then((cameras) { routePush(context, page: TakePictureScreen( - camera: cameras.first, + camera: content == 'ktp' + ? cameras[0] + : cameras[1], takeContent: content, )); }); @@ -170,9 +172,9 @@ class DisplayPictureScreen extends StatelessWidget { ), ), SizedBox( - width: SizeConfig.width * .42, + width: SizeConfig.width * .4, child: ButtonView( - marginVertical: 8.0, + marginVertical: 0.0, name: 'Next', onPressed: () { provider.nextSubmission(context); diff --git a/lib/application/component/take_picture_screen/take_picture_screen.dart b/lib/application/component/take_picture_screen/take_picture_screen.dart index a659c32..405409b 100644 --- a/lib/application/component/take_picture_screen/take_picture_screen.dart +++ b/lib/application/component/take_picture_screen/take_picture_screen.dart @@ -1,7 +1,7 @@ import 'package:camera/camera.dart'; import 'package:cims_apps/application/assets/path_assets.dart'; import 'package:cims_apps/application/component/image/image_view.dart'; -import 'package:cims_apps/application/component/take_picture_screen/DisplayPictureScreen.dart'; +import 'package:cims_apps/application/component/take_picture_screen/display_picture_screen.dart'; import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/utils/size_config.dart'; import 'package:flutter/material.dart'; diff --git a/lib/application/component/text_caption/text_caption.dart b/lib/application/component/text_caption/text_caption.dart index 00ab5b6..400e70c 100644 --- a/lib/application/component/text_caption/text_caption.dart +++ b/lib/application/component/text_caption/text_caption.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class TextCaption extends StatelessWidget { final String title, subtitle; - final TextAlign? textAlignSubtitle; + final TextAlign? textAlign, textAlignSubtitle; final CrossAxisAlignment? crossAxisAlignment; const TextCaption({ Key? key, @@ -11,6 +11,7 @@ class TextCaption extends StatelessWidget { this.subtitle = '', this.textAlignSubtitle, this.crossAxisAlignment, + this.textAlign, }) : super(key: key); @override @@ -23,6 +24,7 @@ class TextCaption extends StatelessWidget { children: [ Text( title, + textAlign: textAlign ?? TextAlign.start, style: const TextStyle( fontSize: 24, fontWeight: FontWeight.w700, diff --git a/lib/application/component/text_form/text_form_view.dart b/lib/application/component/text_form/text_form_view.dart index 724db8b..6bf6db6 100644 --- a/lib/application/component/text_form/text_form_view.dart +++ b/lib/application/component/text_form/text_form_view.dart @@ -81,123 +81,127 @@ class TextFormView extends StatelessWidget { if (inputFormatters != null && maxLength != null) { inputFormatters?.add(LengthLimitingTextInputFormatter(maxLength)); } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - name.isNotEmpty - ? validator != null - ? Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - name, - style: const TextStyle( - fontSize: 16, - // color: ColorPalette.greyLight, - ), + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + name.isNotEmpty + // ? validator != null + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + name, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorPalette.slate800, ), - suffixLable ?? - const Text( - "", - style: TextStyle( - fontSize: 16, - color: Colors.red, - ), - ), - ], - ) - : Text( - name, - style: const TextStyle( - fontSize: 16, ), - ) - : const SizedBox(), - trailingTitleWidget ?? const SizedBox(), - ], - ), - const SizedBox(height: 8.0), - TextFormField( - focusNode: focusNode, - onTapOutside: (event) => FocusScope.of(context).unfocus(), - minLines: textrea ? 8 : 1, - maxLines: textrea ? null : 1, - initialValue: initialValue, - enabled: enabled, - controller: ctrl, - maxLength: maxLength, - keyboardType: keyboardType, - onTap: onTap, - onEditingComplete: onSubmit, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: fontColorDisabled ?? Colors.black, + suffixLable ?? + const Text( + "", + style: TextStyle( + fontSize: 16, + color: Colors.red, + ), + ), + ], + ) + : Text( + name, + style: const TextStyle( + fontSize: 16, + ), + ), + // : const SizedBox(), + trailingTitleWidget ?? const SizedBox(), + ], ), - readOnly: readOnly, - validator: validator, - obscureText: obscureText, - onChanged: onChanged, - inputFormatters: inputFormatters ?? - [ - RemoveEmojiInputFormatter(), - if (maxLength != null) - LengthLimitingTextInputFormatter(maxLength) - ], - enableInteractiveSelection: enableInteractiveSelection, - textAlign: isTextAlignCenter ? TextAlign.center : TextAlign.left, - decoration: InputDecoration( - helperText: helperText, - errorStyle: errorStyle, - errorText: errorText, - errorMaxLines: 2, - hintStyle: hintTextStyle ?? - const TextStyle( - fontSize: 14, - color: ColorPalette.greyFont, - fontWeight: FontWeight.normal, + const SizedBox(height: 8.0), + TextFormField( + focusNode: focusNode, + onTapOutside: (event) => FocusScope.of(context).unfocus(), + minLines: textrea ? 8 : 1, + maxLines: textrea ? null : 1, + initialValue: initialValue, + enabled: enabled, + controller: ctrl, + maxLength: maxLength, + keyboardType: keyboardType, + onTap: onTap, + onEditingComplete: onSubmit, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: fontColorDisabled ?? Colors.black, + ), + readOnly: readOnly, + validator: validator, + obscureText: obscureText, + onChanged: onChanged, + inputFormatters: inputFormatters ?? + [ + RemoveEmojiInputFormatter(), + if (maxLength != null) + LengthLimitingTextInputFormatter(maxLength) + ], + enableInteractiveSelection: enableInteractiveSelection, + textAlign: isTextAlignCenter ? TextAlign.center : TextAlign.left, + decoration: InputDecoration( + helperText: helperText, + errorStyle: errorStyle, + errorText: errorText, + errorMaxLines: 2, + hintStyle: hintTextStyle ?? + const TextStyle( + fontSize: 14, + color: ColorPalette.greyFont, + fontWeight: FontWeight.normal, + ), + isDense: true, + hintText: hintText, + filled: true, + fillColor: enabled && disableColor == false + ? Colors.white + : const Color.fromARGB(255, 233, 236, 239), + disabledBorder: OutlineInputBorder( + borderRadius: _borderRadius, + borderSide: BorderSide( + color: disabledborderColor ?? ColorPalette.greyBorder, ), - isDense: true, - hintText: hintText, - filled: true, - fillColor: enabled && disableColor == false - ? Colors.white - : const Color.fromARGB(255, 233, 236, 239), - disabledBorder: OutlineInputBorder( - borderRadius: _borderRadius, - borderSide: BorderSide( - color: disabledborderColor ?? ColorPalette.greyBorder, ), - ), - enabledBorder: OutlineInputBorder( - borderRadius: _borderRadius, - borderSide: BorderSide( - color: enabledborderColor ?? ColorPalette.greyBorder, + enabledBorder: OutlineInputBorder( + borderRadius: _borderRadius, + borderSide: BorderSide( + color: enabledborderColor ?? ColorPalette.greyBorder, + ), ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: _borderRadius, - borderSide: BorderSide( - color: focusedBorderColor ?? ColorPalette.greyBorder, + focusedBorder: OutlineInputBorder( + borderRadius: _borderRadius, + borderSide: BorderSide( + color: focusedBorderColor ?? ColorPalette.greyBorder, + ), ), - ), - border: OutlineInputBorder(borderRadius: _borderRadius), - suffixIcon: suffixIcon, - prefixIcon: prefixIcon, - suffixIconConstraints: suffixIconConstraints, - prefixIconConstraints: preffixIconConstraints, - prefix: prefix, - contentPadding: contentPadding ?? const EdgeInsets.symmetric( - horizontal: 8.0, - vertical: 16.0, - ) - ), - ) - ], + border: OutlineInputBorder(borderRadius: _borderRadius), + suffixIcon: suffixIcon, + prefixIcon: prefixIcon, + suffixIconConstraints: suffixIconConstraints, + prefixIconConstraints: preffixIconConstraints, + prefix: prefix, + contentPadding: contentPadding ?? + const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 16.0, + )), + ) + ], + ), ); } } diff --git a/lib/features/auth/login/view/login_view.dart b/lib/features/auth/login/view/login_view.dart index 35157ca..28da9f2 100644 --- a/lib/features/auth/login/view/login_view.dart +++ b/lib/features/auth/login/view/login_view.dart @@ -10,7 +10,7 @@ import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/features/auth/login/view/password_view.dart'; import 'package:cims_apps/features/auth/login/view/phone_number_view.dart'; import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart'; -import 'package:cims_apps/features/auth/registration/view/risk_profile/risk_profile_view.dart'; +import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/risk_profile_view.dart'; import 'package:cims_apps/features/bottom_navigation_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -44,7 +44,7 @@ class _LoginViewState extends State { create: (context) => LoginViewModel(), child: WillPopScope( onWillPop: () async { - if(currentPage == 1){ + if (currentPage == 1) { currentPage--; pageController.jumpToPage(0); return false; @@ -69,14 +69,14 @@ class _LoginViewState extends State { ], ), shape: const RoundedRectangleBorder( - side: BorderSide(color: ColorPalette.slate200) - ), + side: BorderSide(color: ColorPalette.slate200)), ), body: PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, children: [ - PhoneNumberView(nextStep: nextStep, controller: phoneNumberController), + PhoneNumberView( + nextStep: nextStep, controller: phoneNumberController), PasswordView(nextStep: nextStep, controller: passwordController) ], ), @@ -86,10 +86,10 @@ class _LoginViewState extends State { } void nextStep() { - if(pageController.page == 0){ + if (pageController.page == 0) { currentPage++; pageController.jumpToPage(1); - }else{ + } else { routePush(context, page: RiskProfileView()); } } diff --git a/lib/features/auth/registration/view/risk_profile/question_view.dart b/lib/features/auth/registration/view/risk_profile/question_view.dart deleted file mode 100644 index c758c80..0000000 --- a/lib/features/auth/registration/view/risk_profile/question_view.dart +++ /dev/null @@ -1,164 +0,0 @@ -import 'package:cims_apps/application/assets/path_assets.dart'; -import 'package:cims_apps/application/component/button/button_back.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/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/risk_profile/results_view.dart'; -import 'package:cims_apps/features/auth/registration/view/risk_profile/risk_profile_view.dart'; -import 'package:cims_apps/features/auth/registration/view/risk_profile/risk_profile_view_model/risk_profile_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class QuestionView extends StatefulWidget { - const QuestionView({super.key}); - - @override - State createState() => _QuestionViewState(); -} - -class _QuestionViewState extends State { - int currentPage = 0; - PageController pageController = PageController(); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => RiskProfileViewModel(), - child: Consumer( - builder: (context, provider, child) { - return Scaffold( - appBar: AppBar( - toolbarHeight: 70, - backgroundColor: Colors.white, - surfaceTintColor: Colors.white, - automaticallyImplyLeading: false, - centerTitle: true, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ButtonBack(), - const Text('Risk Profile', textAlign: TextAlign.center), - SizedBox( - width: SizeConfig.width * 0.1 - ) - ], - ), - shape: const RoundedRectangleBorder( - side: BorderSide(color: ColorPalette.slate200) - ), - ), - body: PageView( - controller: pageController, - physics: NeverScrollableScrollPhysics(), - children: provider.listRiskProfileQuestion.asMap().entries.map((e) { - return containerQuestion( - e.value, - e.key, - (index, score) => provider.selectedAnswer(index, score) - ); - }).toList(), - ), - bottomNavigationBar: SizedBox( - height: 84, - child: ButtonView( - name: 'Next', - marginVertical: 16, - onPressed: () { - if(currentPage > 3){ - int totalScore = provider.listScore.reduce((value, element) => value + element); - provider.setTypeResult(totalScore); - routePush(context, page: ResultsView(totalScore: totalScore.toString(), typeResult: provider.typeResult)); - }else{ - setState(() { - currentPage += 1; - }); - pageController.nextPage(duration: Duration(milliseconds: 300), curve: Curves.ease); - } - }, - ), - ), - ); - } - ), - ); - } - - Widget containerQuestion(RiskProfileQuestion data, int index, void Function(int index, int score) onTapAnswers) { - return SizedBox( - height: SizeConfig.height, - width: SizeConfig.width, - child: ListView( - padding: EdgeInsets.all(24), - children: [ - ImageView( - image: data.img, - fit: BoxFit.fitWidth, - ), - SizedBox( - height: 16, - ), - Text( - '${index + 1} of 5 question', - style: TextStyle( - fontWeight: FontWeight.bold, - color: ColorPalette.primary - ), - ), - SizedBox( - height: 12, - ), - Text( - data.question, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 24, - color: ColorPalette.slate800 - ), - ), - SizedBox( - height: 16, - ), - Column( - children: data.answers.asMap().entries.map((e) { - bool selected = data.selectedScore == e.value.score; - return GestureDetector( - onTap: () { - onTapAnswers(index, e.value.score); - }, - child: AnimatedContainer( - duration: Duration(milliseconds: 300), - margin: EdgeInsets.only(top: 12), - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - border: Border.all(color: selected ? ColorPalette.primary : ColorPalette.slate200), - borderRadius: BorderRadius.circular(8) - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - e.value.title, - style: TextStyle( - fontSize: 16, - color: selected ? ColorPalette.primary : ColorPalette.slate500, - fontWeight: FontWeight.w500 - ), - ), - ), - if(selected)...[ - Icon(Icons.check_circle_rounded, color: ColorPalette.primary) - ] - ], - ), - ), - ); - }).toList(), - ) - ], - ), - ); - } -} diff --git a/lib/features/auth/registration/view/submission_data/data_bank/guide_screen.dart b/lib/features/auth/registration/view/submission_data/data_bank/guide_screen.dart new file mode 100644 index 0000000..1320fcf --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/data_bank/guide_screen.dart @@ -0,0 +1,126 @@ +import 'package:cims_apps/application/assets/path_assets.dart'; +import 'package:cims_apps/application/component/button/button_back.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/theme/color_palette.dart'; +import 'package:cims_apps/core/utils/size_config.dart'; +import 'package:flutter/material.dart'; + +class GuideScreen extends StatelessWidget { + const GuideScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List listImg = [ + { + 'urlImg': PathAssets.imgGuide1, + 'title': 'Passbook', + 'subtitle': 'Look in your passbook for the account number' + }, + { + 'urlImg': PathAssets.imgGuide2, + 'title': 'Mobile Banking App', + 'subtitle': + 'Open the mobile banking app and you will find your account number' + }, + ]; + + listGuide() { + return Column( + children: listImg.map((e) { + return Container( + width: SizeConfig.width, + height: SizeConfig.height * .18, + padding: const EdgeInsets.all(16.0), + margin: const EdgeInsets.symmetric(vertical: 8.0), + decoration: BoxDecoration( + color: ColorPalette.white, + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: ColorPalette.slate400, + width: 2, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: ImageView( + image: e['urlImg'], + width: SizeConfig.width * .4, + fit: BoxFit.fill, + borderRadius: 8, + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + e['title'], + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorPalette.slate800, + ), + ), + Text( + e['subtitle'], + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: ColorPalette.slate500, + ), + ), + ], + ), + ) + ], + )); + }).toList(), + ); + } + + return Scaffold( + appBar: AppBar( + toolbarHeight: 70, + backgroundColor: Colors.white, + surfaceTintColor: Colors.white, + automaticallyImplyLeading: false, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const ButtonBack(), + const Text('Guide'), + SizedBox( + width: SizeConfig.width * 0.1, + ) + ], + ), + shape: const RoundedRectangleBorder( + side: BorderSide(color: ColorPalette.slate200)), + ), + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const ImageView(image: PathAssets.imgGuideBank), + const TextCaption( + textAlign: TextAlign.center, + title: 'Guide to knowing your account number'), + listGuide(), + ButtonView( + name: 'close', + isOutlined: true, + onPressed: () => Navigator.pop(context), + ) + ], + ), + ), + ); + } +} diff --git a/lib/features/auth/registration/view/submission_data/data_bank/submit_bank_account.dart b/lib/features/auth/registration/view/submission_data/data_bank/submit_bank_account.dart new file mode 100644 index 0000000..d0618be --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/data_bank/submit_bank_account.dart @@ -0,0 +1,56 @@ +import 'package:cims_apps/application/assets/path_assets.dart'; +import 'package:cims_apps/application/component/image/image_view.dart'; +import 'package:cims_apps/application/component/select_form/select_form_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/features/auth/registration/view/submission_data/data_bank/guide_screen.dart'; +import 'package:flutter/material.dart'; + +class SubmitBankAccount extends StatelessWidget { + const SubmitBankAccount({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List listForm = [ + ItemSelectForm('key1', 'BCA'), + ItemSelectForm('key2', 'BRI'), + ItemSelectForm('key3', 'BNI'), + ItemSelectForm('key4', 'BANK MANDIRI'), + ItemSelectForm('key5', 'CIMB NIAGA'), + ]; + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TextCaption(title: 'Input your bank account data'), + SelectFormView( + name: 'Bank Name', + listItem: listForm, + onSelect: (value) {}, + ), + TextFormView( + name: 'Account Number', + trailingTitleWidget: SizedBox( + width: 24, + child: GestureDetector( + onTap: () { + routePush(context, page: GuideScreen()); + }, + child: const ImageView(image: PathAssets.iconQuestion), + ), + ), + ), + TextFormView(name: 'Account Owner Name'), + const Text( + "Make sure the account you use is in your name, not someone else's", + style: TextStyle( + color: ColorPalette.slate400, + ), + ) + ], + ), + ); + } +} diff --git a/lib/features/auth/registration/view/submission_data/risk_profile/question_view.dart b/lib/features/auth/registration/view/submission_data/risk_profile/question_view.dart new file mode 100644 index 0000000..2200106 --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/risk_profile/question_view.dart @@ -0,0 +1,164 @@ +import 'package:cims_apps/application/assets/path_assets.dart'; +import 'package:cims_apps/application/component/button/button_back.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/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/risk_profile/results_view.dart'; +import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/risk_profile_view_model/risk_profile_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class QuestionView extends StatefulWidget { + const QuestionView({super.key}); + + @override + State createState() => _QuestionViewState(); +} + +class _QuestionViewState extends State { + int currentPage = 0; + PageController pageController = PageController(); + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => RiskProfileViewModel(), + child: + Consumer(builder: (context, provider, child) { + return Scaffold( + appBar: AppBar( + toolbarHeight: 70, + backgroundColor: Colors.white, + surfaceTintColor: Colors.white, + automaticallyImplyLeading: false, + centerTitle: true, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ButtonBack(), + const Text('Risk Profile', textAlign: TextAlign.center), + SizedBox(width: SizeConfig.width * 0.1) + ], + ), + shape: const RoundedRectangleBorder( + side: BorderSide(color: ColorPalette.slate200)), + ), + body: PageView( + controller: pageController, + physics: NeverScrollableScrollPhysics(), + children: provider.listRiskProfileQuestion.asMap().entries.map((e) { + return containerQuestion(e.value, e.key, + (index, score) => provider.selectedAnswer(index, score)); + }).toList(), + ), + bottomNavigationBar: SizedBox( + height: 84, + child: ButtonView( + name: 'Next', + marginVertical: 16, + onPressed: () { + if (currentPage > 3) { + int totalScore = provider.listScore + .reduce((value, element) => value + element); + provider.setTypeResult(totalScore); + routePush(context, + page: ResultsView( + totalScore: totalScore.toString(), + typeResult: provider.typeResult)); + } else { + setState(() { + currentPage += 1; + }); + pageController.nextPage( + duration: Duration(milliseconds: 300), + curve: Curves.ease); + } + }, + ), + ), + ); + }), + ); + } + + Widget containerQuestion(RiskProfileQuestion data, int index, + void Function(int index, int score) onTapAnswers) { + return SizedBox( + height: SizeConfig.height, + width: SizeConfig.width, + child: ListView( + padding: EdgeInsets.all(24), + children: [ + ImageView( + image: data.img, + fit: BoxFit.fitWidth, + ), + SizedBox( + height: 16, + ), + Text( + '${index + 1} of 5 question', + style: TextStyle( + fontWeight: FontWeight.bold, color: ColorPalette.primary), + ), + SizedBox( + height: 12, + ), + Text( + data.question, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 24, + color: ColorPalette.slate800), + ), + SizedBox( + height: 16, + ), + Column( + children: data.answers.asMap().entries.map((e) { + bool selected = data.selectedScore == e.value.score; + return GestureDetector( + onTap: () { + onTapAnswers(index, e.value.score); + }, + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + margin: EdgeInsets.only(top: 12), + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + border: Border.all( + color: selected + ? ColorPalette.primary + : ColorPalette.slate200), + borderRadius: BorderRadius.circular(8)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + e.value.title, + style: TextStyle( + fontSize: 16, + color: selected + ? ColorPalette.primary + : ColorPalette.slate500, + fontWeight: FontWeight.w500), + ), + ), + if (selected) ...[ + Icon(Icons.check_circle_rounded, + color: ColorPalette.primary) + ] + ], + ), + ), + ); + }).toList(), + ) + ], + ), + ); + } +} diff --git a/lib/features/auth/registration/view/risk_profile/results_view.dart b/lib/features/auth/registration/view/submission_data/risk_profile/results_view.dart similarity index 97% rename from lib/features/auth/registration/view/risk_profile/results_view.dart rename to lib/features/auth/registration/view/submission_data/risk_profile/results_view.dart index 6faac0f..063e846 100644 --- a/lib/features/auth/registration/view/risk_profile/results_view.dart +++ b/lib/features/auth/registration/view/submission_data/risk_profile/results_view.dart @@ -6,7 +6,7 @@ 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:cims_apps/features/auth/registration/view/risk_profile/risk_profile_view_model/risk_profile_view_model.dart'; +import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/risk_profile_view_model/risk_profile_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; diff --git a/lib/features/auth/registration/view/risk_profile/risk_profile_view.dart b/lib/features/auth/registration/view/submission_data/risk_profile/risk_profile_view.dart similarity index 80% rename from lib/features/auth/registration/view/risk_profile/risk_profile_view.dart rename to lib/features/auth/registration/view/submission_data/risk_profile/risk_profile_view.dart index c274599..1d20482 100644 --- a/lib/features/auth/registration/view/risk_profile/risk_profile_view.dart +++ b/lib/features/auth/registration/view/submission_data/risk_profile/risk_profile_view.dart @@ -5,7 +5,7 @@ import 'package:cims_apps/application/component/image/image_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/risk_profile/question_view.dart'; +import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/question_view.dart'; import 'package:flutter/material.dart'; class RiskProfileView extends StatelessWidget { @@ -24,14 +24,11 @@ class RiskProfileView extends StatelessWidget { children: [ ButtonBack(), const Text('Risk Profile', textAlign: TextAlign.center), - SizedBox( - width: SizeConfig.width * 0.1 - ) + SizedBox(width: SizeConfig.width * 0.1) ], ), shape: const RoundedRectangleBorder( - side: BorderSide(color: ColorPalette.slate200) - ), + side: BorderSide(color: ColorPalette.slate200)), ), body: Container( width: SizeConfig.width, @@ -50,10 +47,9 @@ class RiskProfileView extends StatelessWidget { 'Know Your Risk Profile', textAlign: TextAlign.center, style: TextStyle( - color: ColorPalette.slate800, - fontWeight: FontWeight.bold, - fontSize: 24 - ), + color: ColorPalette.slate800, + fontWeight: FontWeight.bold, + fontSize: 24), ), SizedBox( height: 12, @@ -62,10 +58,9 @@ class RiskProfileView extends StatelessWidget { 'We will provide recommendations that match your profile and risk tolerance level.', textAlign: TextAlign.center, style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: ColorPalette.slate500 - ), + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorPalette.slate500), ), ], ), @@ -85,10 +80,9 @@ class RiskProfileView extends StatelessWidget { Text( 'Your data is secure and encrypted', style: TextStyle( - fontWeight: FontWeight.w600, - color: ColorPalette.primary, - fontSize: 16 - ), + fontWeight: FontWeight.w600, + color: ColorPalette.primary, + fontSize: 16), ) ], ), diff --git a/lib/features/auth/registration/view/risk_profile/risk_profile_view_model/risk_profile_view_model.dart b/lib/features/auth/registration/view/submission_data/risk_profile/risk_profile_view_model/risk_profile_view_model.dart similarity index 100% rename from lib/features/auth/registration/view/risk_profile/risk_profile_view_model/risk_profile_view_model.dart rename to lib/features/auth/registration/view/submission_data/risk_profile/risk_profile_view_model/risk_profile_view_model.dart 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 585d7c3..cdaa065 100644 --- a/lib/features/auth/registration/view/submission_data/submission_parent.dart +++ b/lib/features/auth/registration/view/submission_data/submission_parent.dart @@ -2,9 +2,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/data_bank/submit_bank_account.dart'; +import 'package:cims_apps/features/auth/registration/view/submission_data/submit_data_id_card.dart'; import 'package:cims_apps/features/auth/registration/view/submission_data/submit_photo_ktp.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/view/submission_data/submit_photo_selfie.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'; @@ -42,17 +45,11 @@ class _SubmissionParentState extends State { case 3: return const SubmitPhotoKtp(); case 4: - return Container( - child: Text("Step 4"), - ); + return const SubmitPhotoSelfie(); case 5: - return Container( - child: Text("Step 5"), - ); + return const SubmitDataIdCard(); case 6: - return Container( - child: Text("Step 6"), - ); + return const SubmitBankAccount(); case 7: return Container( child: Text("Step 7"), @@ -113,7 +110,8 @@ class _SubmissionParentState extends State { child: _content(provider.getCurrentStep), ), ), - provider.getCurrentStep == 3 + provider.getCurrentStep == 3 || + provider.getCurrentStep == 4 ? const SizedBox() : Align( alignment: Alignment.bottomCenter, diff --git a/lib/features/auth/registration/view/submission_data/submit_data_id_card.dart b/lib/features/auth/registration/view/submission_data/submit_data_id_card.dart new file mode 100644 index 0000000..b7364ba --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/submit_data_id_card.dart @@ -0,0 +1,218 @@ +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/utils/size_config.dart'; +import 'package:flutter/material.dart'; + +class SubmitDataIdCard extends StatelessWidget { + const SubmitDataIdCard({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List listImg = [ + {'urlImg': PathAssets.imgKtpClear, 'tag': 'ID Card'}, + {'urlImg': PathAssets.imgSelfieClear, 'tag': 'Selfie with ID Card'}, + ]; + + bottomSheet() { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return StatefulBuilder( + builder: (context, setState) { + return Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.vertical(top: Radius.circular(18))), + height: SizeConfig.height * .32, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + const ImageView( + image: PathAssets.iconShield, + width: 20, + height: 22, + ), + const SizedBox( + width: 8, + ), + const Expanded( + child: Text( + 'Will my data be safe?', + style: TextStyle( + fontWeight: FontWeight.w600, + color: ColorPalette.primary, + ), + ), + ), + IconButton( + onPressed: () => Navigator.pop(context), + icon: const Icon( + Icons.close, + color: ColorPalette.slate400, + ), + ) + ], + ), + const Text( + 'We only request data in accordance with OJK regulations. Your data is encrypted and will not be shared with third parties without your consent.', + style: TextStyle( + color: ColorPalette.slate400, + ), + ), + ButtonView( + name: 'OK', + isOutlined: true, + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + ); + }, + ); + }, + ); + } + + Widget photoDocument() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Text( + 'Photo Document', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorPalette.slate800, + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: listImg.map((e) { + return Column( + children: [ + SizedBox( + height: SizeConfig.height * .18, + width: SizeConfig.width * .45, + child: ImageView( + image: e['urlImg'], + fit: BoxFit.fill, + borderRadius: 12, + ), + ), + SizedBox( + width: SizeConfig.width * .43, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + e['tag'], + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.w600, + color: ColorPalette.slate800, + ), + ), + SizedBox( + width: 38, + child: IconButton( + style: IconButton.styleFrom( + backgroundColor: Colors.white, + shape: const CircleBorder( + side: BorderSide( + color: ColorPalette.slate200))), + onPressed: () {}, + icon: const Icon( + Icons.camera_alt_outlined, + color: ColorPalette.slate500, + )), + ), + ], + ), + ) + ], + ); + }).toList(), + ) + ], + ); + } + + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TextCaption(title: 'Check your ID card data for accuracy'), + TextFormView(name: 'NIK'), + TextFormView(name: 'Full Name'), + TextFormView( + name: 'Birth Date', + suffixIcon: const Icon( + Icons.calendar_today_rounded, + color: ColorPalette.slate400, + ), + ), + photoDocument(), + Container( + width: SizeConfig.width, + padding: const EdgeInsets.symmetric(horizontal: 16.0), + margin: const EdgeInsets.symmetric(vertical: 16.0), + decoration: BoxDecoration( + color: ColorPalette.blue50, + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: ColorPalette.greyLights, + width: 1, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const ImageView( + image: PathAssets.iconShield, + width: 20, + height: 22, + ), + const SizedBox( + width: 8, + ), + const Expanded( + child: Text( + 'Will my data be safe?', + style: TextStyle( + fontWeight: FontWeight.w600, + color: ColorPalette.primary, + ), + ), + ), + IconButton( + onPressed: () { + bottomSheet(); + }, + icon: const Icon( + Icons.arrow_forward_ios, + color: ColorPalette.primary, + size: 20, + ), + ) + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/features/auth/registration/view/submission_data/submit_photo_ktp.dart b/lib/features/auth/registration/view/submission_data/submit_photo_ktp.dart index d01b583..84df759 100644 --- a/lib/features/auth/registration/view/submission_data/submit_photo_ktp.dart +++ b/lib/features/auth/registration/view/submission_data/submit_photo_ktp.dart @@ -99,7 +99,7 @@ class SubmitPhotoKtp extends StatelessWidget { provider.initCamera().then((cameras) { routePush(context, page: TakePictureScreen( - camera: cameras.first, + camera: cameras[0], takeContent: 'ktp', )); }); diff --git a/lib/features/auth/registration/view/submission_data/submit_photo_selfie.dart b/lib/features/auth/registration/view/submission_data/submit_photo_selfie.dart new file mode 100644 index 0000000..0458cde --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/submit_photo_selfie.dart @@ -0,0 +1,125 @@ +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/take_picture_screen/take_picture_screen.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/viewmodel/submission_data_viewmodel.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class SubmitPhotoSelfie extends StatelessWidget { + const SubmitPhotoSelfie({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List listImg = [ + { + 'urlImg': PathAssets.imgSelfieBlur, + 'tag': 'Blurry and ID card is not visible' + }, + { + 'urlImg': PathAssets.imgSelfieClear, + 'tag': 'ID card and face clearly visible' + }, + ]; + return MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (context) => SubmissionDataViewModel(), + ) + ], + builder: (context, child) { + return SizedBox( + height: SizeConfig.height * .75, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const TextCaption( + title: 'Take a selfie with your ID card', + subtitle: + 'Make sure your face and identity are clearly visible to ensure your identity is correct.', + ), + SizedBox( + height: SizeConfig.height * .42, + width: SizeConfig.width, + child: Wrap( + alignment: WrapAlignment.spaceBetween, + spacing: 2, + runSpacing: 2, + children: List.generate(listImg.length, (index) { + final urlList = listImg[index]['urlImg']; + final tag = listImg[index]['tag']; + return Column( + children: [ + ImageView( + image: urlList, + width: SizeConfig.width * .35, + ), + const SizedBox( + height: 8, + ), + SizedBox( + width: SizeConfig.width * .42, + child: Text( + tag, + textAlign: TextAlign.center, + style: const TextStyle( + color: ColorPalette.slate800, + fontWeight: FontWeight.w600), + ), + ), + ], + ); + }), + ), + ), + const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ImageView( + image: PathAssets.iconShield, + width: 20, + height: 22, + ), + SizedBox( + width: 8, + ), + Expanded( + child: Text( + 'In accordance with OJK regulations, a selfie with ID card is required to purchase mutual funds.', + maxLines: 2, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: ColorPalette.primary, + ), + ), + ) + ], + ), + Consumer( + builder: (context, provider, child) { + return ButtonView( + name: 'Take a Photo', + marginVertical: 16.0, + onPressed: () { + provider.initCamera().then((cameras) { + routePush(context, + page: TakePictureScreen( + camera: cameras[1], + takeContent: 'selfie', + )); + }); + }, + ); + }) + ], + ), + ); + }); + } +}