From 1616f22925923be6868fb079ae87c3f70bb55abf Mon Sep 17 00:00:00 2001 From: Dian Bayu Nugroho Date: Mon, 5 Feb 2024 18:10:28 +0700 Subject: [PATCH] add initial take photo --- assets/icons/icon-shield.png | Bin 0 -> 1665 bytes lib/application/assets/path_assets.dart | 1 + .../select_form/select_form_view.dart | 176 ++++++++++++++++++ .../submission_data/initial_take_photo.dart | 91 +++++++++ .../viewmodel/submission_data_viewmodel.dart | 31 +++ 5 files changed, 299 insertions(+) create mode 100644 assets/icons/icon-shield.png create mode 100644 lib/application/component/select_form/select_form_view.dart create mode 100644 lib/features/auth/registration/view/submission_data/initial_take_photo.dart create mode 100644 lib/features/auth/registration/viewmodel/submission_data_viewmodel.dart diff --git a/assets/icons/icon-shield.png b/assets/icons/icon-shield.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a9572d3ab6af1c308daaf481a459e62494aa10 GIT binary patch literal 1665 zcmV-{27dX8P)@~0drDELIAGL9O(c600d`2O+f$vv5yP{!Grc1`0p!t@;XnLKUKXL*xHU#gW|`)FXr= z%&NR*N^wCGv=MK0`@;?hFG{!&67cov*4sy*0l7C@8W5@<-933H2?b%6;~BfQwa|f_ z$W^@C&GQB`fCdH=X2V7Xn`Z}$ZODOK#G5_ZqL5KoHTJU}OfnUZMEmNayMv5L(J*cQ zW-|oq<fRXG8SzZTRvV}WphqlJikBtM?3%!8xYJ8 zG@vb`(fU#~UZg4H+~Sc~m5y8I9PZ1JuL1f97DZdy+avVE$(c3ZC>={Ye{$aWT&sdX zO|K4y@g0Cy2V`|%%*>%lrU$|?V_*vuCn)4O@Qw?v4YhAN_T$MOazwma+kb6vXqC4u z5(xYU9-Ns_k_-kl9-csvLFgdEUB~-(;q-7(T2|bY->S~%)_kA0vVD$FU`V*LgQds) z-`(1Nzrg{22ZdaLK95<$!V#|yZybSQDo|t)ZAZA7b9RCYy5$GQt;+3GZ(x1mkT9LH%4%>z4^A@TA*p z89N5uAzR`(k+vjAo0^ajj0rmskK3R*(``vFC721^IQGS>dXDnQlh)yhQ+1c+!s{9$ z?k4$N4Q$B>uIt*D&dm#@>hWGBn4_b?rt#?fs`_ua<*<4SbE-go0miJA$7Zb9j zBNrfg>v;&Q4T@kc8<}THL9Af)BN|O?$uJDX3p)0uXTcXLaKIbuBc}bX1Y-|n#8Dy4JnI>Sawxkci`H1HnD_$_#wIL&-1kBx*1jtq6 z_BaO+nR=w?W0+l?G6}f4^>*REZ@;$aGi~@2kbght6VVbUZl99YfcE@1;2Psc-QnWc z#fgb|+bsJ&U2#1(a^Yg4c+}1XsP}#P!mOxiA~CgM!1F3Ca@KI&n6fxQOcjq_y+IRo zxMs+epw^_QBVyI6T({;+`Ib0y@7RSt*QWW(XY{;JtvEj#TRdvMMmL{OxT2ug1UVDi zT8{OMiAv09-Yekh_J4wj&1wByKZ)z}sN(V}`aepK_HTiY!_05Dxc%dKOHSYR;0iD< zuN;S&#UrkQfU^om%q1RCWC7<9j+k3KqKE>{D;$xEctnu|OhY&#HSvgG;|ML8>$#&y z`Z%&9Nk`QvQWcN5+k9hs+<4x7O_E0Vdp5`b$M listItem; + final ValueChanged onSelect; + final FormFieldValidator? validator; + final _borderRadius = const Radius.circular(24); + final bool? enabled; + const SelectFormView( + {Key? key, + required this.name, + this.hintText, + this.hintTextStyle, + this.ctrl, + this.bottomSheetTitle, + required this.listItem, + required this.onSelect, + this.validator, + this.enabled}) + : super(key: key); + + @override + Widget build(BuildContext context) { + bottomSheet() { + showModalBottomSheet( + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: _borderRadius, + topRight: _borderRadius, + ), + ), + builder: (BuildContext context) { + ItemSelectForm? selectedForm; + String? selectedKey; + if (listItem.isNotEmpty) { + var res = listItem.where((element) => element.key == selectedKey); + if (res.isNotEmpty) { + selectedForm = res.first; + } + } + return StatefulBuilder(builder: ( + BuildContext context, + StateSetter stateSetter, + ) { + return Container( + height: SizeConfig.height * .45, + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + bottomSheetTitle ?? Container(), + // const SizedBox(height: 16), + Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + children: [ + ...listItem.map( + (e) => Card( + elevation: 0, + color: Colors.transparent, + shape: const RoundedRectangleBorder( + side: BorderSide( + color: ColorPalette.greyBorder, + ), + borderRadius: + BorderRadius.all(Radius.circular(12)), + ), + child: ListTile( + title: Text( + e.text, + style: const TextStyle( + fontSize: 14, + ), + ), + subtitle: e.description != null + ? Text( + e.description!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ) + : null, + // trailing: const Icon( + // Icons.check_circle, + // color: ColorPalette.primary, + // ), + trailing: Radio( + focusColor: ColorPalette.primary, + activeColor: ColorPalette.primary, + visualDensity: const VisualDensity( + horizontal: VisualDensity.minimumDensity, + vertical: VisualDensity.minimumDensity, + ), + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + value: e.key, + groupValue: selectedKey, + onChanged: (value) { + // selectedForm = + // ItemSelectForm(e.key, e.text); + // stateSetter(() { + // selectedKey = selectedForm!.key; + // }); + }, + ), + onTap: () { + ctrl?.text = e.text; + onSelect(e.key); + Navigator.of(context).pop(); + }, + ), + ), + ), + ], + ), + ), + ), + ButtonView( + name: 'Select', + marginVertical: 4.0, + onPressed: () { + // print('object $') + }, + ) + ], + ), + ); + }); + }, + ); + } + + return TextFormView( + name: name, + readOnly: true, + enabled: enabled ?? true, + onTap: () { + if (listItem.isNotEmpty) bottomSheet(); + }, + validator: validator, + hintText: hintText, + hintTextStyle: hintTextStyle, + ctrl: ctrl, + suffixIcon: Icon( + Icons.keyboard_arrow_down, + size: SizeConfig.width * .07, + ), + ); + } +} diff --git a/lib/features/auth/registration/view/submission_data/initial_take_photo.dart b/lib/features/auth/registration/view/submission_data/initial_take_photo.dart new file mode 100644 index 0000000..10f20a2 --- /dev/null +++ b/lib/features/auth/registration/view/submission_data/initial_take_photo.dart @@ -0,0 +1,91 @@ +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/theme/color_palette.dart'; +import 'package:cims_apps/core/utils/size_config.dart'; +import 'package:flutter/material.dart'; + +class InitialTakePhoto extends StatelessWidget { + const InitialTakePhoto({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List listImg = [ + {'urlImg': PathAssets.imgKtpBlur, 'tag': 'Blurry Photo'}, + {'urlImg': PathAssets.imgKtpLight, 'tag': 'Light Reflection'}, + {'urlImg': PathAssets.imgKtpCropped, 'tag': 'Cropped Photo'}, + {'urlImg': PathAssets.imgKtpClear, 'tag': 'Clear Photo'}, + ]; + return SizedBox( + height: SizeConfig.height * .75, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const TextCaption( + title: 'Take a photo your ID card', + subtitle: + 'Make sure your photo is clearly legible for identity verification purposes', + ), + SizedBox( + width: SizeConfig.height, + child: Wrap( + alignment: WrapAlignment.spaceBetween, + spacing: 10, + runSpacing: 10, + 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 * .42, + ), + const SizedBox( + height: 8, + ), + Text( + tag, + style: const TextStyle( + color: ColorPalette.slate800, + fontWeight: FontWeight.w600), + ), + ], + ); + }), + ), + ), + // const Spacer(), + const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ImageView( + image: PathAssets.iconShield, + width: 20, + height: 22, + ), + SizedBox( + width: 8, + ), + Expanded( + child: Text( + 'In accordance with OJK regulations, an ID card is required to purchase mutual funds.', + style: TextStyle( + fontWeight: FontWeight.w600, + color: ColorPalette.primary, + ), + ), + ) + ], + ), + ButtonView( + name: 'Take a Photo', + marginVertical: 16.0, + onPressed: () {}, + ) + ], + ), + ); + } +} diff --git a/lib/features/auth/registration/viewmodel/submission_data_viewmodel.dart b/lib/features/auth/registration/viewmodel/submission_data_viewmodel.dart new file mode 100644 index 0000000..c7a97fb --- /dev/null +++ b/lib/features/auth/registration/viewmodel/submission_data_viewmodel.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +class SubmissionDataViewModel extends ChangeNotifier { + int currentStep = 1; + int stepAmount = 9; + bool _isEmailVerify = false; + bool get isEmailVerify => _isEmailVerify; + + submitEmail() { + _isEmailVerify = !_isEmailVerify; + notifyListeners(); + } + + onWillPopSubmission(BuildContext context) { + if (currentStep != 1) { + currentStep--; + notifyListeners(); + } else { + Navigator.of(context).pop(true); + } + } + + nextSubmission(BuildContext context) { + if (currentStep < stepAmount) { + currentStep++; + } else { + //ToDo : Go To next step after completing the submission + } + notifyListeners(); + } +}