From 0309299f44b84aa1a0360832be876fa05ad4dafc Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Thu, 4 Sep 2025 10:02:07 +0300 Subject: [PATCH] changes --- assets/langs/ar-SA.json | 2 +- assets/langs/en-US.json | 3 +- lib/generated/locale_keys.g.dart | 2 +- lib/presentation/authentication/register.dart | 1 + .../authentication/register_step2.dart | 38 +++---- .../dropdown/country_dropdown_widget.dart | 98 ++++++++++++++----- lib/widgets/dropdown/dropdown_widget.dart | 34 +++++-- lib/widgets/input_widget.dart | 58 ++++++----- 8 files changed, 155 insertions(+), 81 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 46362bb..2c7ac9b 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -782,7 +782,7 @@ "resultsPending": "النتائج معلقة", "resultsAvailable": "النتائج متاحة", "viewReport": "عرض التقرير", - "prescriptionDeliveryError": "هذه العيادة لا تدعم إعادة التعبئة والتسليم." + "prescriptionDeliveryError": "هذه العيادة لا تدعم إعادة التعبئة والتسليم.", "receiveOtpToast": "أين تود تلقي رمز التحقق OTP؟", "enterPhoneNumber": "أدخل رقم الهاتف", "enterEmailDesc": "أدخل عنوان بريدك الإلكتروني لإكمال عملية إنشاء ملف طبي", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 22509d8..d01d9f6 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -783,8 +783,7 @@ "resultsPending": "Results Pending", "resultsAvailable": "Results Available", "viewReport": "View Report", - "prescriptionDeliveryError": "This clinic doesn't support refill" - "loginOrRegister": "Login or Register", + "prescriptionDeliveryError": "This clinic doesn't support refill", "prepareToElevate": "Prepared to elevate your health and well-being?", "iAcceptTermsConditions": "I Accept the Terms and Conditions", "alreadyHaveAccount": "Already have an account?", diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index e6e3090..0210e4c 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -774,13 +774,13 @@ abstract class LocaleKeys { static const validPassportNumber = 'validPassportNumber'; static const continuePlan = 'continuePlan'; static const aboutApp = 'aboutApp'; + static const dontHaveAccount = 'dontHaveAccount'; static const loginOrRegister = 'loginOrRegister'; static const myFiles = 'myFiles'; static const resultsPending = 'resultsPending'; static const resultsAvailable = 'resultsAvailable'; static const viewReport = 'viewReport'; static const prescriptionDeliveryError = 'prescriptionDeliveryError'; - static const dontHaveAccount = 'dontHaveAccount'; static const receiveOtpToast = 'receiveOtpToast'; static const enterPhoneNumber = 'enterPhoneNumber'; static const enterEmailDesc = 'enterEmailDesc'; diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index 20c83f5..1e8a0c7 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -218,6 +218,7 @@ class _RegisterNew extends State { countryCode: "966", initialPhoneNumber: "", textController: TextEditingController(), + isEnableCountryDropdown: true, onChange: (String? value) {}, buttons: [ Padding( diff --git a/lib/presentation/authentication/register_step2.dart b/lib/presentation/authentication/register_step2.dart index dbffe91..295dd8a 100644 --- a/lib/presentation/authentication/register_step2.dart +++ b/lib/presentation/authentication/register_step2.dart @@ -53,6 +53,7 @@ class _RegisterNew extends State { Widget build(BuildContext context) { return Scaffold( + appBar: CustomAppBar(onBackPressed: () {}, onLanguageChanged: (lang) {}, hideLogoAndLang: true,), body: SingleChildScrollView( reverse: false, @@ -78,8 +79,8 @@ class _RegisterNew extends State { keyboardType: TextInputType.text, isAllowLeadingIcon: true, isReadOnly: isFromDubai ? false : true, - leadingIcon: AppAssets.user_circle), - Divider(height: 1), + leadingIcon: AppAssets.user_circle).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), TextInputWidget( labelText: LocaleKeys.nationalIdNumber.tr(), hintText: isFromDubai ? "widget.payload.nationalID!" : (widget.nHICData!.idNumber ?? ""), @@ -90,8 +91,8 @@ class _RegisterNew extends State { isBorderAllowed: false, isAllowLeadingIcon: true, isReadOnly: true, - leadingIcon: AppAssets.student_card), - Divider(height: 1), + leadingIcon: AppAssets.student_card).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), isFromDubai ? DropdownWidget( labelText: LocaleKeys.gender.tr(), @@ -108,7 +109,7 @@ class _RegisterNew extends State { isAllowRadius: false, padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, - // leadingIcon: 'assets/images/svg/user-full.svg', + leadingIcon: AppAssets.user_full, ).withVerticalPadding(8) : TextInputWidget( labelText: LocaleKeys.gender.tr(), @@ -121,8 +122,9 @@ class _RegisterNew extends State { isAllowLeadingIcon: true, isReadOnly: isFromDubai ? false : true, leadingIcon: AppAssets.user_full, - onChange: (value) {}), - Divider(height: 1), + + onChange: (value) {}).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), isFromDubai ? DropdownWidget( labelText: LocaleKeys.maritalStatus.tr(), @@ -136,7 +138,7 @@ class _RegisterNew extends State { isAllowRadius: false, padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, - // leadingIcon: 'assets/images/svg/smart-phone.svg', + leadingIcon: AppAssets.smart_phone, ).withVerticalPadding(8) : TextInputWidget( labelText: LocaleKeys.maritalStatus.tr(), @@ -150,8 +152,8 @@ class _RegisterNew extends State { isAllowLeadingIcon: true, isReadOnly: true, leadingIcon: AppAssets.smart_phone, - onChange: (value) {}), - Divider(height: 1), + onChange: (value) {}).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), isFromDubai ? DropdownWidget( labelText: LocaleKeys.country.tr(), @@ -165,7 +167,7 @@ class _RegisterNew extends State { isAllowRadius: false, padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, - // leadingIcon: 'assets/images/svg/globe.svg', + leadingIcon: AppAssets.globe, ).withVerticalPadding(8) : TextInputWidget( labelText: LocaleKeys.nationality.tr(), @@ -179,8 +181,8 @@ class _RegisterNew extends State { isAllowLeadingIcon: true, isReadOnly: true, leadingIcon: AppAssets.globe, - onChange: (value) {}), - Divider(height: 1), + onChange: (value) {}).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), TextInputWidget( labelText: LocaleKeys.mobileNumber.tr(), hintText: ("widget.payload.mobileNo" ?? ""), @@ -192,8 +194,8 @@ class _RegisterNew extends State { isAllowLeadingIcon: true, isReadOnly: true, leadingIcon: AppAssets.call, - onChange: (value) {}), - Divider(height: 1), + onChange: (value) {}).paddingSymmetrical(0.h,16.h), + Divider(height: 1, color: AppColors.greyColor,), TextInputWidget( labelText: LocaleKeys.dob.tr(), hintText: isFromDubai ? "widget.payload.dob!" : (widget.nHICData!.dateOfBirth ?? ""), @@ -203,11 +205,11 @@ class _RegisterNew extends State { isBorderAllowed: false, isAllowLeadingIcon: true, isReadOnly: true, - // selectionType: SelectionType.calendar, + // : SelectionType.calendar, // selectedValue: widget.payload.dob != null ? Utils.formatDateToDisplay(widget.payload.dob.toString()) : null, // selectionCustomIcon: AppAssets.calendar, - // leadingIcon: AppAssets.birthday_cake, - onChange: (value) {}), + leadingIcon: AppAssets.birthday_cake, + onChange: (value) {}).paddingSymmetrical(0.h,16.h), ], ), ), diff --git a/lib/widgets/dropdown/country_dropdown_widget.dart b/lib/widgets/dropdown/country_dropdown_widget.dart index 603cfed..3d28e23 100644 --- a/lib/widgets/dropdown/country_dropdown_widget.dart +++ b/lib/widgets/dropdown/country_dropdown_widget.dart @@ -11,6 +11,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; class CustomCountryDropdown extends StatefulWidget { final List countryList; final Function(CountryEnum)? onCountryChange; + final Function(String)? onPhoneNumberChanged; final bool isRtl; final bool isFromBottomSheet; final bool isEnableTextField; @@ -20,6 +21,7 @@ class CustomCountryDropdown extends StatefulWidget { Key? key, required this.countryList, this.onCountryChange, + this.onPhoneNumberChanged, required this.isRtl, this.isFromBottomSheet = false, this.isEnableTextField = false, @@ -34,34 +36,55 @@ class _CustomCountryDropdownState extends State { CountryEnum? selectedCountry; late OverlayEntry _overlayEntry; bool _isDropdownOpen = false; + FocusNode textFocusNode = new FocusNode(); @override void initState() { super.initState(); selectedCountry = CountryEnum.saudiArabia; + + if (widget.isEnableTextField && widget.isFromBottomSheet) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted && textFocusNode.canRequestFocus) { + FocusScope.of(context).requestFocus(textFocusNode); + } + }); + } + } + + @override + void dispose() { + textFocusNode.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - if (_isDropdownOpen) { - _closeDropdown(); - } else { - _openDropdown(); - } - }, - child: Container( - height: 40.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h), - child: Row( - children: [ - Utils.buildSvgWithAssets(icon: selectedCountry != null ? selectedCountry!.iconPath : AppAssets.ksa, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Utils.buildSvgWithAssets(icon: _isDropdownOpen ? AppAssets.dropdow_icon : AppAssets.dropdow_icon), - SizedBox(width: 4.h), - if (widget.isFromBottomSheet) - Column( + return Container( + height: 40.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h), + child: Row( + children: [ + GestureDetector( + onTap: () { + if (_isDropdownOpen) { + _closeDropdown(); + } else { + _openDropdown(); + } + }, + child: Utils.buildSvgWithAssets(icon: selectedCountry != null ? selectedCountry!.iconPath : AppAssets.ksa, width: 40.h, height: 40.h)), + SizedBox(width: 8.h), + Utils.buildSvgWithAssets(icon: _isDropdownOpen ? AppAssets.dropdow_icon : AppAssets.dropdow_icon), + SizedBox(width: 4.h), + if (widget.isFromBottomSheet) + GestureDetector( + onTap: () { + if (widget.isEnableTextField && textFocusNode.canRequestFocus) { + FocusScope.of(context).requestFocus(textFocusNode); + } + }, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -80,23 +103,36 @@ class _CustomCountryDropdownState extends State { style: TextStyle(fontSize: 12.fSize, height: 21 / 18, fontWeight: FontWeight.w600, letterSpacing: -0.2), ), SizedBox(width: 4.h), - if (widget.isEnableTextField) widget.textField!, + if (widget.isEnableTextField) + SizedBox( + height: 20, + width: 200, + child: TextField( + focusNode: textFocusNode, + decoration: InputDecoration(hintText: "", isDense: true, border: InputBorder.none), + keyboardType: TextInputType.phone, + onChanged: widget.onPhoneNumberChanged), + ), ], ) ], ), - if (!widget.isFromBottomSheet) - Text( - selectedCountry != null ? selectedCountry!.displayName : "Select Country", - style: TextStyle(fontSize: 14.fSize, height: 21 / 14, fontWeight: FontWeight.w500, letterSpacing: -0.2), - ), - ], - ), + ), + if (!widget.isFromBottomSheet) + Text( + selectedCountry != null ? selectedCountry!.displayName : "Select Country", + style: TextStyle(fontSize: 14.fSize, height: 21 / 14, fontWeight: FontWeight.w500, letterSpacing: -0.2), + ), + ], ), ); } void _openDropdown() { + if (textFocusNode.hasFocus) { + textFocusNode.unfocus(); + } + RenderBox renderBox = context.findRenderObject() as RenderBox; Offset offset = renderBox.localToGlobal(Offset.zero); @@ -162,5 +198,13 @@ class _CustomCountryDropdownState extends State { setState(() { _isDropdownOpen = false; }); + + if (widget.isEnableTextField && widget.isFromBottomSheet) { + Future.delayed(Duration(milliseconds: 100), () { + if (mounted && textFocusNode.canRequestFocus) { + FocusScope.of(context).requestFocus(textFocusNode); + } + }); + } } } diff --git a/lib/widgets/dropdown/dropdown_widget.dart b/lib/widgets/dropdown/dropdown_widget.dart index 268e44a..2a0cad3 100644 --- a/lib/widgets/dropdown/dropdown_widget.dart +++ b/lib/widgets/dropdown/dropdown_widget.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart' show Icons, PopupMenuItem, showMenu, Colo import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; class DropdownWidget extends StatelessWidget { final String labelText; @@ -16,6 +17,7 @@ class DropdownWidget extends StatelessWidget { final EdgeInsetsGeometry? padding; final bool hasSelectionCustomIcon; final String? selectionCustomIcon; + final String? leadingIcon; const DropdownWidget({ Key? key, @@ -30,29 +32,49 @@ class DropdownWidget extends StatelessWidget { this.padding, this.hasSelectionCustomIcon = false, this.selectionCustomIcon, + this.leadingIcon, }) : super(key: key); @override Widget build(BuildContext context) { + Widget content = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [_buildLabelText(), _buildDropdown(context)], + ); + return Container( padding: padding, - alignment: Alignment.center, + alignment: Alignment.center, // This might need adjustment based on layout decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: Colors.white, borderRadius: isAllowRadius ? 15.h : null, side: isBorderAllowed ? BorderSide(color: const Color(0xffefefef), width: 1) : null, ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( + // Wrap with a Row + crossAxisAlignment: CrossAxisAlignment.center, // Align items vertically in the center children: [ - _buildLabelText(), - _buildDropdown(context), + if (leadingIcon != null) ...[ + _buildLeadingIcon(), + SizedBox(width: 3.h), + ], + Expanded(child: content), ], ), ); } + Widget _buildLeadingIcon() { + return Container( + height: 40.h, + width: 40.h, + margin: EdgeInsets.only(right: 10.h), + padding: EdgeInsets.all(8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h, color: AppColors.greyColor), + child: Utils.buildSvgWithAssets(icon: leadingIcon!)); + } + Widget _buildLabelText() { return Text( labelText, diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 6cefbbf..b8d36e7 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -74,26 +74,32 @@ class TextInputWidget extends StatelessWidget { child: Row( textDirection: Directionality.of(context), children: [ - if (isAllowLeadingIcon && leadingIcon != null) + if (isAllowLeadingIcon && leadingIcon != null && !isCountryDropDown) + _buildLeadingIcon(context), isCountryDropDown ? CustomCountryDropdown( - countryList: CountryEnum.values, - onCountryChange: (CountryEnum? value) {}, - isRtl: Directionality.of(context) == TextDirection.rtl, - isFromBottomSheet: isCountryDropDown, - isEnableTextField:true, - textField: _buildTextField(context), - ) + countryList: CountryEnum.values, + onCountryChange: (CountryEnum? value) { + print(value); + }, + isRtl: Directionality.of(context) == TextDirection.rtl, + isFromBottomSheet: isCountryDropDown, + isEnableTextField: true, + onPhoneNumberChanged: (value) { + print(value); + }, + textField: _buildTextField(context), + ) : Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildLabelText(), - _buildTextField(context), - ], - ), - ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildLabelText(), + _buildTextField(context), + ], + ), + ), ], ), ), @@ -172,15 +178,15 @@ class TextInputWidget extends StatelessWidget { prefixIcon: prefix == null ? null : Text( - "+" + prefix!, - style: TextStyle( - fontSize: 14.fSize, - height: 21 / 14, - fontWeight: FontWeight.w500, - color: Color(0xff2E303A), - letterSpacing: -0.2, - ), - ), + "+" + prefix!, + style: TextStyle( + fontSize: 14.fSize, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.2, + ), + ), contentPadding: EdgeInsets.zero, border: InputBorder.none, focusedBorder: InputBorder.none,