From 0194ab9189929282930e8f8a120cb1ca5cc23d23 Mon Sep 17 00:00:00 2001 From: Aamir Muhammad Date: Sun, 13 Jul 2025 09:42:27 +0300 Subject: [PATCH] register Design. --- assets/images/svg/Check Mark.lottie | Bin 1181 -> 0 bytes assets/images/svg/call.svg | 3 + assets/images/svg/cancel.svg | 3 + assets/images/svg/confirm.svg | 3 + assets/images/svg/email.svg | 3 + assets/images/svg/globe.svg | 3 + assets/images/svg/uae.svg | 16 +- assets/images/svg/user-circle.svg | 5 + assets/images/svg/user-full.svg | 4 + .../otp/otp_validation_bootmsheet_widget.dart | 41 +- .../health_calculator/carbs/carbs.dart | 448 ++++++++++++------ lib/pages/login/register_new.dart | 176 ++++--- lib/pages/login/register_new_step_2.dart | 313 ++++++++++++ lib/uitl/utils.dart | 72 ++- lib/widgets/others/app_scaffold_widget.dart | 3 +- 15 files changed, 855 insertions(+), 238 deletions(-) delete mode 100644 assets/images/svg/Check Mark.lottie create mode 100644 assets/images/svg/call.svg create mode 100755 assets/images/svg/cancel.svg create mode 100755 assets/images/svg/confirm.svg create mode 100644 assets/images/svg/email.svg create mode 100644 assets/images/svg/globe.svg create mode 100644 assets/images/svg/user-circle.svg create mode 100644 assets/images/svg/user-full.svg create mode 100644 lib/pages/login/register_new_step_2.dart diff --git a/assets/images/svg/Check Mark.lottie b/assets/images/svg/Check Mark.lottie deleted file mode 100644 index 28630fbd70259a7f2d78496216b7b0cffe802a42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1181 zcmWIWW@Zs#U|`^25ZtjoNW?E`-iC$K5eqL{{Bi|tf0oV6N z*()77FRZI#^iPOc(9^XrA;HAZ_x-yyG3DRuKgHc+l3$}cjYnDI#z9%*F#n~W<~uD6 z=}>z2-`nQ)605tOX@6(S-98|b?k|&RFi)(bQTFwRf~n2oZrQ3m!EP~2rXIRimC1Hh zy8Xl}?Vs;AvZN?axBAWUy7Dh$0E$yfj@>`{mWhF3F3_DOK&Jv-nwwaXnV(mzZ*Gxl zmTX{|sB2{@Ywv>1|om8FV>a`u${Sn z+wRueg_D<+=8N)oOl)g42|Z)CO5=a+bE!EK9IljQ?amZtvOfOo*S*KZ>rb}jO`CG* z_x9)cYSZs`ExIy`<*a7tCE+iNv!|y{4&Jpe+h=ctsc-1K@Y0p)>(8lODwLhRt?AXD zburmq>&>p*36$!%R%EE(&Fb^Ybg7W9^GfZEQty@G3xXFmr_FoKzcVht>U4H2*Qs!} zxC8gv&RnW6VEDc6z|=%n>l+U*mAaPC4oujaC@ygA)&2)713u&~JG^)C&0htvZ4W~E z4?0CRJmuMDbY}kZ?N8@1?21#)IebvH-$$h`jN^Xa>z%UyXP6fo|2bN)rF&Own)A`V z>0IlL8E3w*-DoBweRRLEU9YWs=YhZj%lC_AwQ=F6Ie#zh zO-_9-Se>q9;Pc0XA+CjGkwC}++vZ(<5^iZO+kTg@&ga-;ft97N|F2u1fN! zX>RwbjW?~Hw5&Y9KKcIkmydtXUFqnxBKVn`@68|^gTqUA`&#+$YI?u-@Vx&*k>-aA z4&9f%d+`v4)~@pHDd1Cf77Ad??J*wf{fMW1;HvjNc~Q z5u&u&$6qUTX8n1#OD?N6mgl*R$6Muha_54z4orXk zm~XS+p?bfTV9f^~gF6f!$k`p&EJ*s3C}h%nc0=&IFW*m{-l`{kZ)?tP?f`E_CJ_eQ oc^#OCkN`@~N7ss;_YnG41DWLH!~kzrHjpVyKsXmjzhVaQ09JkYD*ylh diff --git a/assets/images/svg/call.svg b/assets/images/svg/call.svg new file mode 100644 index 00000000..33891359 --- /dev/null +++ b/assets/images/svg/call.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/cancel.svg b/assets/images/svg/cancel.svg new file mode 100755 index 00000000..c48bc126 --- /dev/null +++ b/assets/images/svg/cancel.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/confirm.svg b/assets/images/svg/confirm.svg new file mode 100755 index 00000000..62cfa014 --- /dev/null +++ b/assets/images/svg/confirm.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/email.svg b/assets/images/svg/email.svg new file mode 100644 index 00000000..09c68a33 --- /dev/null +++ b/assets/images/svg/email.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/globe.svg b/assets/images/svg/globe.svg new file mode 100644 index 00000000..f17981fc --- /dev/null +++ b/assets/images/svg/globe.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/uae.svg b/assets/images/svg/uae.svg index 69da43ac..1047f418 100644 --- a/assets/images/svg/uae.svg +++ b/assets/images/svg/uae.svg @@ -1,9 +1,13 @@ - - + + + + + + + - - - - + + + diff --git a/assets/images/svg/user-circle.svg b/assets/images/svg/user-circle.svg new file mode 100644 index 00000000..8dc74ed1 --- /dev/null +++ b/assets/images/svg/user-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/svg/user-full.svg b/assets/images/svg/user-full.svg new file mode 100644 index 00000000..ed1159ae --- /dev/null +++ b/assets/images/svg/user-full.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart index 2bd1b5f4..8a0c6660 100644 --- a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart +++ b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart @@ -6,18 +6,13 @@ import 'package:hmg_patient_app/uitl/utils.dart'; import 'package:hmg_patient_app/widgets/text/app_texts_widget.dart'; class GenericBottomSheet extends StatefulWidget { - final String countryCode; - final String initialPhoneNumber; + String? countryCode; + String? initialPhoneNumber; final List buttons; TextEditingController? textController; + final bool isForEmail; - GenericBottomSheet({ - Key? key, - this.countryCode = "+966", - this.initialPhoneNumber = "", - required this.buttons, - this.textController, - }) : super(key: key); + GenericBottomSheet({Key? key, this.countryCode = "", this.initialPhoneNumber = "", required this.buttons, this.textController, this.isForEmail = false}) : super(key: key); @override _GenericBottomSheetState createState() => _GenericBottomSheetState(); @@ -27,7 +22,9 @@ class _GenericBottomSheetState extends State { @override void initState() { super.initState(); - widget.textController = TextEditingController(text: widget.initialPhoneNumber); + if (!widget.isForEmail) { + widget.textController = TextEditingController(text: widget.initialPhoneNumber); + } } @override @@ -47,7 +44,8 @@ class _GenericBottomSheetState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppText("Enter Phone Number", fontSize: 28, letterSpacing: -2, fontFamily: 'poppins', color: Color(0xFF2E3039), fontWeight: FontWeight.w600), + AppText(widget.isForEmail ? "Enter Email Address" : "Enter Phone Number", + fontSize: 28, letterSpacing: -2, fontFamily: context.fontFamily, color: Color(0xFF2E3039), fontWeight: FontWeight.w600), InkWell( onTap: () { Navigator.of(context).pop(); @@ -57,7 +55,8 @@ class _GenericBottomSheetState extends State { ), const SizedBox(height: 10), // Subtitle - AppText("Enter your phone number to receive OTP verification code", fontSize: 16, fontFamily: 'poppins', color: Color(0xFF2E3039), fontWeight: FontWeight.w500), + AppText(widget.isForEmail ? "Enter your email address to complete the process of creating a medical file" : "Enter your phone number to receive OTP verification code", + fontSize: 16, fontFamily: context.fontFamily, color: Color(0xFF2E3039), fontWeight: FontWeight.w500), const SizedBox(height: 10), widget.textController != null ? Column( @@ -65,9 +64,20 @@ class _GenericBottomSheetState extends State { children: [ Directionality( textDirection: TextDirection.ltr, - child: inputWidget(TranslationBase.of(context).phoneNumber, "5xxxxxxxx", widget.textController!, onChange: (value) { - widget.textController!.text = value!; - }, isEnable: true, prefix: "966", hasSelection: false, isBorderAllowed: false, isAllowLeadingIcon: true, leadingIcon: "assets/images/svg/smart-phone.svg"), + child: inputWidget( + widget.isForEmail ? TranslationBase.of(context).email : TranslationBase.of(context).phoneNumber, + widget.isForEmail ? "demo@gmail.com" : "5xxxxxxxx", + widget.textController!, + onChange: (value) { + widget.textController!.text = value!; + }, + isEnable: true, + prefix: widget.isForEmail ? null : widget.countryCode, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + leadingIcon: widget.isForEmail ? "assets/images/svg/email.svg" :"assets/images/svg/smart-phone.svg", + ), ), ], ) @@ -109,7 +119,6 @@ class CustomButton extends StatelessWidget { this.fontFamily, this.fontWeight = FontWeight.w500, this.isDisabled = false, - this.icon, }) : super(key: key); diff --git a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart index adf838bc..ce2acb69 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart @@ -322,170 +322,344 @@ Widget inputWidget( String? leadingIcon, bool removePadding = false, bool isAllowRadius = true, + bool isReadOnly = false, List? dropdownItems, String? selectedValue, SelectionType? selectionType, }) { return Builder( builder: (context) { - return Container( - padding: removePadding ? const EdgeInsets.only(top: 16, bottom: 16) : const EdgeInsets.symmetric(horizontal: 16, vertical: 15), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: isAllowRadius ? BorderRadius.circular(15) : null, - color: Colors.white, - border: isBorderAllowed ? Border.all(color: const Color(0xffefefef), width: 1) : null, - ), - child: Row( - children: [ - if (isAllowLeadingIcon && leadingIcon != null) - Container( - height: 40, - width: 40, - margin: const EdgeInsets.only(right: 10), - padding: isLeadingCountry ? null : const EdgeInsets.all(5), - decoration: const BoxDecoration( - color: Color(0xFFEFEFF0), - borderRadius: BorderRadius.all(Radius.circular(10)), + final isRtl = Directionality.of(context) == TextDirection.rtl; + + return Directionality( + textDirection: Directionality.of(context), + child: Container( + padding: removePadding ? const EdgeInsets.only(top: 16, bottom: 16) : const EdgeInsets.symmetric(horizontal: 16, vertical: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: isAllowRadius ? BorderRadius.circular(15) : null, + color: Colors.white, + border: isBorderAllowed ? Border.all(color: const Color(0xffefefef), width: 1) : null, + ), + child: Row( + textDirection: Directionality.of(context), + children: [ + if (isAllowLeadingIcon && leadingIcon != null) + Container( + height: 40, + width: 40, + margin: isRtl ? const EdgeInsets.only(left: 10) : const EdgeInsets.only(right: 10), + padding: isLeadingCountry ? null : const EdgeInsets.all(5), + decoration: const BoxDecoration( + color: Color(0xFFEFEFF0), + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: SvgPicture.asset(leadingIcon, width: 24, height: 24), ), - child: SvgPicture.asset(leadingIcon, width: 24, height: 24), - ), - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _labelText, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, - color: const Color(0xff898A8D), - fontFamily: context.fontFamily, - letterSpacing: -0.2, - height: 18 / 12, + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: isRtl ? CrossAxisAlignment.end : CrossAxisAlignment.start, + children: [ + Directionality( + textDirection: Directionality.of(context), + child: Text( + _labelText, + textAlign: isRtl ? TextAlign.right : TextAlign.left, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: const Color(0xff898A8D), + fontFamily: context.fontFamily, + letterSpacing: -0.2, + height: 18 / 12, + ), + ), ), - ), - hasSelection - ? GestureDetector( - onTap: isEnable - ? () async { - if (selectionType == SelectionType.dropdown) { - final renderBox = context.findRenderObject() as RenderBox; - final offset = renderBox.localToGlobal(Offset.zero); - - final selected = await showMenu( - context: context, - position: RelativeRect.fromLTRB( - offset.dx, - offset.dy + renderBox.size.height, - offset.dx + 1, - 0, - ), - items: dropdownItems?.map((e) { - return PopupMenuItem( - value: e, - child: Text(e), - ); - }).toList() ?? - [], - ); - - if (selected != null && onChange != null) { - onChange(selected); - } - } else if (selectionType == SelectionType.calendar) { - final picked = await showDatePicker( - context: context, + hasSelection + ? GestureDetector( + onTap: isEnable && !isReadOnly + ? () async { + if (selectionType == SelectionType.dropdown) { + final renderBox = context.findRenderObject() as RenderBox; + final offset = renderBox.localToGlobal(Offset.zero); - initialDate: DateTime.now(), - firstDate: DateTime(1900), - lastDate: DateTime(2100), - ); + final selected = await showMenu( + context: context, + position: RelativeRect.fromLTRB( + offset.dx, + offset.dy + renderBox.size.height, + offset.dx + 1, + 0, + ), + items: dropdownItems + ?.map( + (e) => PopupMenuItem( + value: e, + child: Text(e), + ), + ) + .toList() ?? + [], + ); - if (picked != null && onChange != null) { - onChange(picked.toIso8601String()); + if (selected != null && onChange != null) { + onChange(selected); + } + } else if (selectionType == SelectionType.calendar) { + final picked = await showDatePicker(context: context, initialDate: DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime(2100)); + if (picked != null && onChange != null) { + onChange(picked.toIso8601String()); + } } } - } - : null, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - selectedValue ?? _hintText, - style: TextStyle( - fontSize: 14, - height: 21 / 14, - fontWeight: FontWeight.w500, - fontFamily: context.fontFamily, - color: selectedValue != null ? const Color(0xff2E3039) : const Color(0xffB0B0B0), - letterSpacing: -0.2, + : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + (selectedValue == null || selectedValue.isEmpty) ? _hintText : selectedValue, + textAlign: isRtl ? TextAlign.right : TextAlign.left, + textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + fontFamily: context.fontFamily, + color: (selectedValue != null && selectedValue.isNotEmpty) ? const Color(0xff2E3039) : const Color(0xffB0B0B0), + letterSpacing: -0.2, + ), ), ), - ), - if (hasSelectionCustomIcon && selectionCustomIcon != null) - SvgPicture.asset(selectionCustomIcon, width: 24, height: 24) - else - const Icon(Icons.keyboard_arrow_down_outlined), - ], - ), - ) - : TextField( - enabled: isEnable, - scrollPadding: EdgeInsets.zero, - keyboardType: TextInputType.number, - controller: _controller, - textAlignVertical: TextAlignVertical.top, - onChanged: onChange, - style: TextStyle( - fontSize: 14, - height: 21 / 14, - fontFamily: context.fontFamily, - fontWeight: FontWeight.w500, - color: const Color(0xff2E3039), - letterSpacing: -0.2, - ), - decoration: InputDecoration( - isDense: true, - hintText: _hintText, - hintStyle: TextStyle( + if (hasSelectionCustomIcon && selectionCustomIcon != null) + SvgPicture.asset(selectionCustomIcon, width: 24, height: 24) + else + const Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ) + : TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.number, + controller: _controller, + readOnly: isReadOnly, + textAlignVertical: TextAlignVertical.top, + textAlign: isRtl ? TextAlign.right : TextAlign.left, + textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr, + onChanged: onChange, + style: TextStyle( fontSize: 14, - height: 21 / 16, + height: 21 / 14, fontFamily: context.fontFamily, fontWeight: FontWeight.w500, color: const Color(0xff2E3039), letterSpacing: -0.2, ), - prefixIconConstraints: const BoxConstraints(minWidth: 45), - prefixIcon: prefix == null - ? null - : Text( - "+" + prefix, - style: TextStyle( - fontSize: 14, - height: 21 / 14, - fontFamily: context.fontFamily, - fontWeight: FontWeight.w500, - color: const Color(0xff2E303A), - letterSpacing: -0.2, + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 16, + fontFamily: context.fontFamily, + fontWeight: FontWeight.w500, + color: const Color(0xff898A8D), + letterSpacing: -0.2, + ), + prefixIconConstraints: const BoxConstraints(minWidth: 45), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontFamily: context.fontFamily, + fontWeight: FontWeight.w500, + color: const Color(0xff2E303A), + letterSpacing: -0.2, + ), ), - ), - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), ), - ), - ], + ], + ), ), - ), - ], + ], + ), ), ); }, ); + // return Builder( + // builder: (context) { + // return Directionality( + // textDirection:Directionality.of(context), + // child: Container( + // padding: removePadding ? const EdgeInsets.only(top: 16, bottom: 16) : const EdgeInsets.symmetric(horizontal: 16, vertical: 15), + // alignment: Alignment.center, + // decoration: BoxDecoration( + // borderRadius: isAllowRadius ? BorderRadius.circular(15) : null, + // color: Colors.white, + // border: isBorderAllowed ? Border.all(color: const Color(0xffefefef), width: 1) : null, + // ), + // child: Row( + // children: [ + // if (isAllowLeadingIcon && leadingIcon != null) + // Container( + // height: 40, + // width: 40, + // margin: const EdgeInsets.only(right: 10), + // padding: isLeadingCountry ? null : const EdgeInsets.all(5), + // decoration: const BoxDecoration( + // color: Color(0xFFEFEFF0), + // borderRadius: BorderRadius.all(Radius.circular(10)), + // ), + // child: SvgPicture.asset(leadingIcon, width: 24, height: 24), + // ), + // Expanded( + // child: Column( + // mainAxisSize: MainAxisSize.min, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // _labelText, + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w500, + // color: const Color(0xff898A8D), + // fontFamily: context.fontFamily, + // letterSpacing: -0.2, + // height: 18 / 12, + // ), + // ), + // hasSelection + // ? GestureDetector( + // onTap: isEnable + // ? () async { + // if (selectionType == SelectionType.dropdown) { + // final renderBox = context.findRenderObject() as RenderBox; + // final offset = renderBox.localToGlobal(Offset.zero); + // + // final selected = await showMenu( + // context: context, + // position: RelativeRect.fromLTRB( + // offset.dx, + // offset.dy + renderBox.size.height, + // offset.dx + 1, + // 0, + // ), + // items: dropdownItems?.map((e) { + // return PopupMenuItem( + // value: e, + // child: Text(e), + // ); + // }).toList() ?? + // [], + // ); + // + // if (selected != null && onChange != null) { + // onChange(selected); + // } + // } else if (selectionType == SelectionType.calendar) { + // final picked = await showDatePicker( + // context: context, + // + // initialDate: DateTime.now(), + // firstDate: DateTime(1900), + // lastDate: DateTime(2100), + // ); + // + // if (picked != null && onChange != null) { + // onChange(picked.toIso8601String()); + // } + // } + // } + // : null, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Expanded( + // child: Text( + // selectedValue ?? _hintText, + // style: TextStyle( + // fontSize: 14, + // height: 21 / 14, + // fontWeight: FontWeight.w500, + // fontFamily: context.fontFamily, + // color: selectedValue != null ? const Color(0xff2E3039) : const Color(0xffB0B0B0), + // letterSpacing: -0.2, + // ), + // ), + // ), + // if (hasSelectionCustomIcon && selectionCustomIcon != null) + // SvgPicture.asset(selectionCustomIcon, width: 24, height: 24) + // else + // const Icon(Icons.keyboard_arrow_down_outlined), + // ], + // ), + // ) + // : TextField( + // enabled: isEnable, + // scrollPadding: EdgeInsets.zero, + // keyboardType: TextInputType.number, + // controller: _controller, + // textAlignVertical: TextAlignVertical.top, + // onChanged: onChange, + // style: TextStyle( + // fontSize: 14, + // height: 21 / 14, + // fontFamily: context.fontFamily, + // fontWeight: FontWeight.w500, + // color: const Color(0xff2E3039), + // letterSpacing: -0.2, + // ), + // decoration: InputDecoration( + // isDense: true, + // hintText: _hintText, + // hintStyle: TextStyle( + // fontSize: 14, + // height: 21 / 16, + // fontFamily: context.fontFamily, + // fontWeight: FontWeight.w500, + // color: const Color(0xff898A8D), + // letterSpacing: -0.2, + // ), + // prefixIconConstraints: const BoxConstraints(minWidth: 45), + // prefixIcon: prefix == null + // ? null + // : Text( + // "+" + prefix, + // style: TextStyle( + // fontSize: 14, + // height: 21 / 14, + // fontFamily: context.fontFamily, + // fontWeight: FontWeight.w500, + // color: const Color(0xff2E303A), + // letterSpacing: -0.2, + // ), + // ), + // contentPadding: EdgeInsets.zero, + // border: InputBorder.none, + // focusedBorder: InputBorder.none, + // enabledBorder: InputBorder.none, + // ), + // ), + // ], + // ), + // ), + // ], + // ), + // ), + // ); + // }, + // ); } // Widget inputWidget( diff --git a/lib/pages/login/register_new.dart b/lib/pages/login/register_new.dart index 9098c4db..d655002f 100644 --- a/lib/pages/login/register_new.dart +++ b/lib/pages/login/register_new.dart @@ -6,6 +6,7 @@ import 'package:hmg_patient_app/pages/AlHabibMedicalService/health_calculator/ca import 'package:hmg_patient_app/pages/login/login-type.dart'; import 'package:hmg_patient_app/pages/login/register-info.dart'; import 'package:hmg_patient_app/pages/login/register.dart'; +import 'package:hmg_patient_app/pages/login/register_new_step_2.dart'; import 'package:hmg_patient_app/services/authentication/auth_provider.dart'; import 'package:hmg_patient_app/theme/colors.dart'; import 'package:hmg_patient_app/uitl/app_shared_preferences.dart'; @@ -17,6 +18,8 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app/widgets/text/app_texts_widget.dart'; import 'package:provider/provider.dart'; +import '../../widgets/transitions/fade_page.dart'; + class RegisterNew extends StatefulWidget { @override _RegisterNew createState() => _RegisterNew(); @@ -24,15 +27,16 @@ class RegisterNew extends StatefulWidget { class _RegisterNew extends State { final nationalIDorFile = TextEditingController(); - TextEditingController phoneController = TextEditingController(); + final phoneController = TextEditingController(); Country selectedCountry = Country.saudiArabia; bool isTermsAccepted = false; + DateTime? selectedDOB; + final int loginType = LoginType.loginType; late String mobileNo; String countryCode = '966'; var isHijri; final util = Utils(); - late DateTime selectedDate; late String dob; bool isButtonDisabled = true; final authService = new AuthProvider(); @@ -163,7 +167,7 @@ class _RegisterNew extends State { body: SafeArea( child: SingleChildScrollView( - reverse: true, + reverse: false, padding: EdgeInsets.only( left: 24, right: 24, @@ -192,7 +196,7 @@ class _RegisterNew extends State { ), SizedBox(height: 24), Directionality( - textDirection: TextDirection.ltr, + textDirection: Directionality.of(context), child: Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), padding: EdgeInsets.only(left: 16, right: 16), @@ -205,8 +209,8 @@ class _RegisterNew extends State { isEnable: true, prefix: null, hasSelection: true, - dropdownItems: Country.values.map((e) => e.displayName).toList(), - selectedValue: selectedCountry.displayName, + dropdownItems: Country.values.map((e) => context.selectedLanguage == "ar" ? e.nameArabic : e.displayName).toList(), + selectedValue: context.selectedLanguage == "ar" ? selectedCountry.nameArabic : selectedCountry.displayName, selectionType: SelectionType.dropdown, onChange: (val) { if (val != null) { @@ -246,9 +250,13 @@ class _RegisterNew extends State { isAllowLeadingIcon: true, hasSelectionCustomIcon: true, selectionType: SelectionType.calendar, + selectedValue: selectedDOB != null ? Utils.formatDateToDisplay(selectedDOB.toString()) : null, selectionCustomIcon: "assets/images/svg/calendar.svg", leadingIcon: "assets/images/svg/birthday-cake.svg", onChange: (value) { print("=========== " + value!); + selectedDOB = DateTime.parse(value); + + setState(() {}); }), ], ), @@ -296,73 +304,89 @@ class _RegisterNew extends State { text: TranslationBase.of(context).register, icon: "assets/images/svg/note-edit.svg", onPressed: () { - bool isValid = Utils.validateIqama(nationalIDorFile.text); - if (isValid) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - isDismissible: false, - backgroundColor: Colors.transparent, - builder: (bottomSheetContext) => Padding( - padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), - child: SingleChildScrollView( - child: GenericBottomSheet( - countryCode: "966", - initialPhoneNumber: "", - textController: phoneController, - buttons: [ - Padding( - padding: const EdgeInsets.only(bottom: 10), - child: CustomButton( - text: "Send me OTP on SMS", - onPressed: () { - int? val = Utils.onOtpBtnPressed(OTPType.sms, phoneController); - // if (val != null) checkUserAuthentication(val); - }, - backgroundColor: Colors.red, - borderColor: Colors.red, - textColor: Colors.white, - icon: "assets/images/svg/message.svg", - ), + // bool isValid = Utils.validateIqama(nationalIDorFile.text); + if (nationalIDorFile == null) { + Utils.showErrorToast("Please enter your national id."); + return; + } + if (selectedCountry == null) { + Utils.showErrorToast("Please select your country."); + return; + } + + if (selectedDOB == null) { + Utils.showErrorToast("Please enter your date of birth."); + return; + } + if (!isTermsAccepted) { + Utils.showErrorToast("Please accept the terms and conditions."); + return; + } + + showModalBottomSheet( + context: context, + isScrollControlled: true, + isDismissible: false, + backgroundColor: Colors.transparent, + builder: (bottomSheetContext) => Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), + child: SingleChildScrollView( + child: GenericBottomSheet( + countryCode: selectedCountry.countryCode, + initialPhoneNumber: "", + textController: phoneController, + buttons: [ + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton( + text: "Send me OTP on SMS", + onPressed: () { + int? val = Utils.onOtpBtnPressed(OTPType.sms, phoneController); + registerUser(val); + //if (val != null) checkUserAuthentication(val); + }, + backgroundColor: Colors.red, + borderColor: Colors.red, + textColor: Colors.white, + icon: "assets/images/svg/message.svg", ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: AppText( - "OR", - fontSize: 16, - fontFamily: 'poppins', - color: Color(0xFF2E3039), - fontWeight: FontWeight.w500, - ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: AppText( + "OR", + fontSize: 16, + fontFamily: context.fontFamily, + color: Color(0xFF2E3039), + fontWeight: FontWeight.w500, ), - ], - ), - Padding( - padding: const EdgeInsets.only(bottom: 10), - child: CustomButton( - text: "Send me OTP on WhatsApp", - onPressed: () { - int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, phoneController); - // if (val != null) checkUserAuthentication(val); - }, - backgroundColor: Colors.white, - borderColor: Color(0xFF2E3039), - textColor: Color(0xFF2E3039), - icon: "assets/images/svg/whatsapp.svg", ), + ], + ), + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton( + text: "Send me OTP on WhatsApp", + onPressed: () { + int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, phoneController); + registerUser(val); + // if (val != null) checkUserAuthentication(val); + }, + backgroundColor: Colors.white, + borderColor: Color(0xFF2E3039), + textColor: Color(0xFF2E3039), + icon: "assets/images/svg/whatsapp.svg", ), - ], - ), + ), + ], ), ), - ); - } else { - Utils.showErrorToast("Please enter a valid Iqama number."); - } + ), + ); }, fontFamily: context.fontFamily, ), @@ -397,8 +421,7 @@ class _RegisterNew extends State { ), recognizer: TapGestureRecognizer() ..onTap = () { - // Navigator.of(context).push(FadePage(page: RegisterNew())); - // locator().loginRegistration.visited_alhabib_group(true); + Navigator.of(context).pop(); }, ), ], @@ -451,7 +474,7 @@ class _RegisterNew extends State { mHeight(2), Container( padding: EdgeInsets.all(5), - decoration: containerRadius(color!.withOpacity(0.2), 4), + decoration: containerRadius(color.withOpacity(0.2), 4), child: Text( status!, style: TextStyle( @@ -467,4 +490,17 @@ class _RegisterNew extends State { ], ); } + + void registerUser(int? value) { + //OTPType.sms ? 1 : 2; + print("Country: ${selectedCountry.name}"); + print("nationalId: ${nationalIDorFile.text}"); + print("DOB: ${selectedDOB}"); + if (value == 1) { + print("OTP sent successfully to ${phoneController.text} using SMS"); + } else { + print("OTP sent successfully to ${phoneController.text} using Whatsapp"); + } + Navigator.of(context).push(FadePage(page: RegisterNewStep2())); + } } diff --git a/lib/pages/login/register_new_step_2.dart b/lib/pages/login/register_new_step_2.dart new file mode 100644 index 00000000..bf301285 --- /dev/null +++ b/lib/pages/login/register_new_step_2.dart @@ -0,0 +1,313 @@ +import 'package:flutter/gestures.dart'; +import 'package:hmg_patient_app/config/size_config.dart'; +import 'package:hmg_patient_app/core/viewModels/project_view_model.dart'; +import 'package:hmg_patient_app/new_ui/otp/otp_validation_bootmsheet_widget.dart'; +import 'package:hmg_patient_app/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart'; +import 'package:hmg_patient_app/pages/login/login-type.dart'; +import 'package:hmg_patient_app/pages/login/register-info.dart'; +import 'package:hmg_patient_app/pages/login/register.dart'; +import 'package:hmg_patient_app/services/authentication/auth_provider.dart'; +import 'package:hmg_patient_app/theme/colors.dart'; +import 'package:hmg_patient_app/uitl/app_shared_preferences.dart'; +import 'package:hmg_patient_app/uitl/translations_delegate_base.dart'; +import 'package:hmg_patient_app/uitl/utils.dart'; +import 'package:hmg_patient_app/uitl/utils_new.dart'; +import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app/widgets/text/app_texts_widget.dart'; +import 'package:provider/provider.dart'; + +class RegisterNewStep2 extends StatefulWidget { + @override + _RegisterNew createState() => _RegisterNew(); +} + +class _RegisterNew extends State { + final nationalIDorFile = TextEditingController(); + final emailAddress = TextEditingController(); + DateTime? selectedDOB; + + final int loginType = LoginType.loginType; + late String mobileNo; + String countryCode = '966'; + var isHijri; + final util = Utils(); + late String dob; + bool isButtonDisabled = true; + final authService = new AuthProvider(); + final sharedPref = new AppSharedPreferences(); + late PageController _controller; + late bool isLoading; + int _currentIndex = 0; + + @override + void initState() { + super.initState(); + _controller = new PageController(); + } + + @override + void dispose() { + super.dispose(); + } + + changePageViewIndex(pageIndex) { + _controller.jumpToPage(pageIndex); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "Personal Details Verification", + isShowDecPage: false, + isShowAppBar: true, + isshowBackButton: true, + showNewAppBar: true, + backgroundColor: Color(0xffF8F8F8), + showNewAppBarTitle: true, + showDropDown: false, + isShowLanguageChanger: false, + showHomeAppBarIcon: false, + resizeToAvoidBottomInset: true, + appBarIcons: [], + dropDownIndexChange: (value) { + Utils.changeAppLanguage(context: context); + }, + body: SafeArea( + child: SingleChildScrollView( + reverse: false, + padding: EdgeInsets.only(left: 24, right: 24, top: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Directionality( + textDirection: Directionality.of(context), + child: Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), + padding: EdgeInsets.only(left: 16, right: 16), + child: Column( + children: [ + inputWidget(TranslationBase.of(context).name, "Mohammad Hussain Abdul Ghaffar", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/user-circle.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).nationalIdNumber, "25293444933", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/student-card.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).gender, "Male", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/user-full.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).maritalStatus, "Married", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/smart-phone.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).nationality, "Pakistani", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/globe.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).mobileNumber, "234567876543", nationalIDorFile, + isEnable: true, + prefix: null, + removePadding: true, + isAllowRadius: false, + hasSelection: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + isReadOnly: true, + leadingIcon: "assets/images/svg/call.svg", + onChange: (value) {}), + Divider(height: 1), + inputWidget(TranslationBase.of(context).dob, "11 July, 1994", nationalIDorFile, + isEnable: true, + prefix: null, + hasSelection: false, + removePadding: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + hasSelectionCustomIcon: false, + isReadOnly: true, + selectionType: SelectionType.calendar, + selectedValue: selectedDOB != null ? Utils.formatDateToDisplay(selectedDOB.toString()) : null, + selectionCustomIcon: "assets/images/svg/calendar.svg", + leadingIcon: "assets/images/svg/birthday-cake.svg", + onChange: (value) {}), + ], + ), + ), + ), + SizedBox(height: 150), + Row( + children: [ + Expanded( + child: CustomButton( + text: TranslationBase.of(context).cancel, + icon: "assets/images/svg/cancel.svg", + onPressed: () { + if (nationalIDorFile == null) { + Utils.showErrorToast("Please enter your national id."); + return; + } + + if (selectedDOB == null) { + Utils.showErrorToast("Please enter your date of birth."); + return; + } + }, + fontFamily: context.fontFamily, + backgroundColor: Color(0xFFFEE9EA), + borderColor: Color(0xFFFEE9EA), + textColor: Color(0xFFED1C2B), + ), + ), + SizedBox( + width: 16, + ), + Expanded( + child: CustomButton( + text: TranslationBase.of(context).confirm, + icon: "assets/images/svg/confirm.svg", + onPressed: () { + // // bool isValid = Utils.validateIqama(nationalIDorFile.text); + // if (nationalIDorFile == null) { + // Utils.showErrorToast("Please enter your national id."); + // return; + // } + // if (selectedDOB == null) { + // Utils.showErrorToast("Please enter your date of birth."); + // return; + // } + + showModalBottomSheet( + context: context, + isScrollControlled: true, + isDismissible: false, + backgroundColor: Colors.transparent, + builder: (bottomSheetContext) => Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), + child: SingleChildScrollView( + child: GenericBottomSheet( + textController: emailAddress, + isForEmail: true, + buttons: [ + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton(text: "Submit", onPressed: () {}, backgroundColor: Colors.red, borderColor: Colors.red, textColor: Colors.white), + ), + ], + ), + ), + ), + ); + }, + fontFamily: context.fontFamily, + ), + ) + ], + ), + SizedBox(height: 14), + ], + ), + ), + )); + } + + Widget showProgress({String? title, String? status, Color? color, bool isNeedBorder = true}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 26, + height: 26, + decoration: containerRadius(color!, 200), + child: Icon( + Icons.done, + color: Colors.white, + size: 16, + ), + ), + if (isNeedBorder) + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: mDivider(Colors.grey), + )), + ], + ), + mHeight(8), + Text( + title!, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + letterSpacing: -0.44, + ), + ), + mHeight(2), + Container( + padding: EdgeInsets.all(5), + decoration: containerRadius(color.withOpacity(0.2), 4), + child: Text( + status!, + style: TextStyle( + fontSize: 8, + fontWeight: FontWeight.w600, + letterSpacing: -0.32, + color: color, + ), + ), + ), + ], + ) + ], + ); + } + + void registerUser(int? value) {} +} diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 9c1e19ef..e5a63975 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -90,21 +90,14 @@ class Utils { } static bool validateIqama(String iqamaNumber) { - // Remove any non-digit characters String cleanedIqama = iqamaNumber.replaceAll(RegExp(r'[^0-9]'), ''); - - // Check if length is 10 digits if (cleanedIqama.length != 10) { return false; } - - // Check if first digit is 2 or 1 (common for Iqama) int firstDigit = int.parse(cleanedIqama[0]); if (firstDigit != 2 && firstDigit != 1) { return false; } - - // Checksum validation (similar to Saudi National ID) int sum = 0; for (int i = 0; i < 10; i++) { int digit = int.parse(cleanedIqama[i]); @@ -112,7 +105,6 @@ class Utils { int product = digit * weight; sum += (product > 9) ? product - 9 : product; // Sum digits if product > 9 } - return sum % 10 == 0; } @@ -128,6 +120,44 @@ class Utils { } } + + + static String formatDateToDisplay(String isoDateString) { + try { + final dateTime = DateTime.parse(isoDateString); + final day = dateTime.day.toString().padLeft(2, '0'); + final year = dateTime.year.toString(); + + // Map month number to short month name + const monthNames = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ]; + final month = monthNames[dateTime.month - 1]; + + return '$day $month, $year'; + return '$day $month, $year'; + } catch (e) { + print("Error formatting date: $e"); + return ""; + } + } + + static String formatDateToUsage(String isoDateString) { + try { + final dateTime = DateTime.parse(isoDateString); + final day = dateTime.day.toString().padLeft(2, '0'); + final month = dateTime.month.toString().padLeft(2, '0'); + final year = dateTime.year.toString(); + + return '$day-$month-$year'; + } catch (e) { + print("Error formatting date: $e"); + return ""; + } + } + + static Widget showLottie({ required BuildContext context, String assetPath = 'assets/icons/no_property.json', @@ -1175,6 +1205,15 @@ extension CountryExtension on Country { } } + String get nameArabic { + switch (this) { + case Country.saudiArabia: + return "المملكة العربية السعودية"; + case Country.unitedArabEmirates: + return "الإمارات العربية المتحدة"; + } + } + String get iconPath { switch (this) { case Country.saudiArabia: @@ -1184,6 +1223,15 @@ extension CountryExtension on Country { } } + String get countryCode { + switch (this) { + case Country.saudiArabia: + return "966"; + case Country.unitedArabEmirates: + return "971"; + } + } + static Country fromDisplayName(String name) { switch (name) { case "Kingdom Of Saudi Arabia": @@ -1204,6 +1252,14 @@ extension FontFamilyExtension on BuildContext { } } +extension SelectedLanguageExtension on BuildContext { + String get selectedLanguage { + final language = read().currentLanguage; + return language; + } +} + + /* userBoard.asMap().map((i, element) => MapEntry(i, Stack( GestureDetector(onTap: () { diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 9f89b1dd..161a9bcd 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -110,6 +110,7 @@ class AppScaffold extends StatefulWidget { this.isPharmacy = false, this.showPharmacyCart = true, this.isOfferPackages = false, + this.showDropDown = false, this.showOfferPackagesCart = false, this.title, this.description, @@ -123,7 +124,6 @@ class AppScaffold extends StatefulWidget { this.icon, this.showHomeAppBarIcon = true, this.imagesInfo, - this.showDropDown = false, this.dropDownList, this.dropdownIndexValue, this.dropDownIndexChange, @@ -251,6 +251,7 @@ resizeToAvoidBottomInset: widget.resizeToAvoidBottomInset, isShowBackButton: widget.isshowBackButton, dropDownIndexChange: widget.dropDownIndexChange, appBarIcons: widget.appBarIcons, + isShowLanguageChanger: widget.isShowLanguageChanger, onTap: () { widget.onTap;