From 8f1e4500cc212b626509482cae4d65d1eda1c559 Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Tue, 2 Sep 2025 12:17:34 +0300 Subject: [PATCH] register & Exception bottom sheet, country dropdown. --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 8 +- lib/extensions/string_extensions.dart | 13 +- lib/generated/locale_keys.g.dart | 4 + lib/main.dart | 3 - lib/presentation/authentication/login.dart | 177 ++-- lib/presentation/authentication/register.dart | 790 +++++------------- lib/presentation/home/landing_page.dart | 5 +- lib/providers/authentication_view_model.dart | 6 - lib/theme/colors.dart | 1 + lib/widgets/appbar/app_bar_widget.dart | 65 +- .../bottomsheet/exception_bottom_sheet.dart | 111 +++ .../dropdown/country_dropdown_widget.dart | 165 ++++ .../{ => dropdown}/dropdown_widget.dart | 88 +- lib/widgets/input_widget.dart | 47 +- lib/widgets/language_switcher.dart | 7 +- pubspec.lock | 30 +- 17 files changed, 721 insertions(+), 805 deletions(-) delete mode 100644 lib/providers/authentication_view_model.dart create mode 100644 lib/widgets/bottomsheet/exception_bottom_sheet.dart create mode 100644 lib/widgets/dropdown/country_dropdown_widget.dart rename lib/widgets/{ => dropdown}/dropdown_widget.dart (56%) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index ebcee14..57f9bcd 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -783,7 +783,11 @@ "enterEmailDesc": "أدخل عنوان بريدك الإلكتروني لإكمال عملية إنشاء ملف طبي", "enterPhoneDesc": "أدخل رقم هاتفك لتلقي رمز التحقق ", "pleaseChooseOption": "الرجاء اختيار من الخيارات أدناه لتلقي رمز التحقق OTP", - "prepareToElevate": "هل أنت مستعد لتحسين صحتك ورفاهتك؟" + "prepareToElevate": "هل أنت مستعد لتحسين صحتك ورفاهتك؟", + "iAcceptTermsConditions": "أوافق على الشروط والأحكام", + "alreadyHaveAccount": "هل لديك حساب بالفعل؟", + "loginNow": "تسجيل الدخول الآن", + "notice": "إشعار" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index b45c697..311db65 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -776,8 +776,12 @@ "enterPhoneNumber": "Enter Phone Number", "enterEmailDesc": "Enter your email address to complete the process of creating a medical file", "enterPhoneDesc": "Enter your phone number to receive OTP verification code", - "pleaseChooseOption": "Please select from the below options to receive OTP" + "pleaseChooseOption": "Please select from the below options to receive OTP", "dontHaveAccount": "Don't have an account?", "loginOrRegister": "Login or Register", - "prepareToElevate": "Prepared to elevate your health and well-being?" + "prepareToElevate": "Prepared to elevate your health and well-being?", + "iAcceptTermsConditions": "I Accept the Terms and Conditions", + "alreadyHaveAccount": "Already have an account?", + "loginNow": "Login Now", + "notice": "Notice" } \ No newline at end of file diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index ec9ff99..187939e 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -1,3 +1,4 @@ +import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:auto_size_text/auto_size_text.dart'; @@ -233,6 +234,12 @@ extension EmailValidator on String { style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), ); + Widget toText36({Color? color, bool isBold = false, bool isCenter = false}) => Text( + this, + textAlign: isCenter ? TextAlign.center : null, + style: TextStyle(height: 47 / 36, color: color ?? AppColors.blackColor, fontSize: 36.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal), + ); + Widget toText44({Color? color, bool isBold = false}) => Text( this, style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), @@ -374,7 +381,6 @@ class FontUtils { } } - extension CountryExtension on Country { String get displayName { switch (this) { @@ -397,9 +403,9 @@ extension CountryExtension on Country { String get iconPath { switch (this) { case Country.saudiArabia: - return "assets/images/svg/ksa.svg"; + return AppAssets.ksa; case Country.unitedArabEmirates: - return "assets/images/svg/uae.svg"; + return AppAssets.uae; } } @@ -425,4 +431,3 @@ extension CountryExtension on Country { } } } - diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 819fb22..f219526 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -782,5 +782,9 @@ abstract class LocaleKeys { static const enterPhoneDesc = 'enterPhoneDesc'; static const pleaseChooseOption = 'pleaseChooseOption'; static const prepareToElevate = 'prepareToElevate'; + static const iAcceptTermsConditions = 'iAcceptTermsConditions'; + static const alreadyHaveAccount = 'alreadyHaveAccount'; + static const loginNow = 'loginNow'; + static const notice = 'notice'; } diff --git a/lib/main.dart b/lib/main.dart index 31c5c56..a9afd60 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,9 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; -import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/utils/size_config.dart'; -import 'package:hmg_patient_app_new/providers/authentication_view_model.dart'; import 'package:hmg_patient_app_new/providers/bottom_navigation_provider.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; @@ -22,7 +20,6 @@ import 'firebase_options.dart'; var globalMessengerKey = GlobalKey(); final navigatorKey = GlobalKey(); - @pragma('vm:entry-point') Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index da85baa..87f40ca 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -1,18 +1,17 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/gestures.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; -import 'package:hmg_patient_app_new/core/utils/size_utils.dart' hide Sizer; +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/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/authentication/register.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:sizer/sizer.dart'; class LoginScreen extends StatefulWidget { @override @@ -32,98 +31,92 @@ class _LoginScreen extends State { @override Widget build(BuildContext context) { - return Sizer(// Wrap with Sizer - builder: (context, orientation, deviceType) { - return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - appBar: CustomAppBar( - onBackPressed: () { - }, - onLanguageChanged: (String value) { - // context.setLocale(value == 'en' ? Locale('ar', 'SA') : Locale('en', 'US')); - }, - ), - body: GestureDetector( - onTap: () { - FocusScope.of(context).unfocus(); // Dismiss the keyboard when tapping outside - }, - child: SingleChildScrollView( - child: Padding( - padding: EdgeInsets.only(left: 6.sp, right: 6.sp), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 45.w, height: 22.sp, repeat: true, fit: BoxFit.cover), - SizedBox(height: 19.sp), // Adjusted to sizer unit - LocaleKeys.welcomeToDrSulaiman.tr().toText22(isBold: true, color: AppColors.textColor), - // Text( - // LocaleKeys.welcomeToDrSulaiman.tr(), - // style: context.dynamicTextStyle( - // fontSize: 22, - // fontWeight: FontWeight.w600, - // color: AppColors.textColor, - // letterSpacing: -0.4, - // height: 40 / 28, - // ), - // ), - SizedBox(height: 4.sp), // Adjusted to sizer unit (approx 32px) - TextInputWidget( - labelText: "${LocaleKeys.nationalId.tr()} / ${LocaleKeys.fileNo.tr()}", - hintText: "xxxxxxxxx", - controller: TextEditingController(), - keyboardType: TextInputType.number, - isEnable: true, - prefix: null, - autoFocus: true, - isBorderAllowed: false, - isAllowLeadingIcon: true, - padding: EdgeInsets.symmetric(vertical: 1.sp, horizontal: 2.w), - leadingIcon: AppAssets.student_card, - errorMessage: "Please enter a valid national ID or file number", - hasError: true, - ), - SizedBox(height: 2.sp), // Adjusted to sizer unit (approx 16px) - CustomButton( - text: LocaleKeys.login.tr(), - icon: AppAssets.login1, - iconColor: Colors.white, - onPressed: () {}, - ), - SizedBox(height: 2.sp), // Adjusted to sizer unit (approx 14px) - Center( - child: RichText( - textAlign: TextAlign.center, - text: TextSpan( - style: context.dynamicTextStyle( - color: Colors.black, - fontSize: 14.sp, // Adjusted to sizer unit - height: 26 / 16, // This height is a ratio, may need re-evaluation - fontWeight: FontWeight.w500, - ), - children: [ - TextSpan(text: LocaleKeys.dontHaveAccount.tr(), style: context.dynamicTextStyle()), - TextSpan(text: " "), - TextSpan( - text: LocaleKeys.registernow.tr(), - style: context.dynamicTextStyle( - color: AppColors.primaryRedColor, - fontSize: 14.sp, // Adjusted to sizer unit - height: 26 / 16, // Ratio - fontWeight: FontWeight.w500, - ), - recognizer: TapGestureRecognizer()..onTap = () {}, - ), - ], + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + appBar: CustomAppBar( + onBackPressed: () { + Navigator.of(context).pop(); + }, + onLanguageChanged: (String value) { + // context.setLocale(value == 'en' ? Locale('ar', 'SA') : Locale('en', 'US')); + }, + ), + body: GestureDetector( + onTap: () { + FocusScope.of(context).unfocus(); // Dismiss the keyboard when tapping outside + }, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 24.h), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 200.h, height: 200.h, repeat: true, fit: BoxFit.cover), + SizedBox(height: 130.h), // Adjusted to sizer unit + LocaleKeys.welcomeToDrSulaiman.tr().toText32(isBold: true, color: AppColors.textColor), + SizedBox(height: 32.h), + TextInputWidget( + labelText: "${LocaleKeys.nationalId.tr()} / ${LocaleKeys.fileNo.tr()}", + hintText: "xxxxxxxxx", + controller: TextEditingController(), + keyboardType: TextInputType.number, + isEnable: true, + prefix: null, + autoFocus: true, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 10.h), + leadingIcon: AppAssets.student_card, + errorMessage: "Please enter a valid national ID or file number", + hasError: true, + ), + SizedBox(height: 16.h), // Adjusted to sizer unit (approx 16px) + CustomButton( + text: LocaleKeys.login.tr(), + icon: AppAssets.login1, + iconColor: Colors.white, + onPressed: () {}, + ), + SizedBox(height: 10.h), // Adjusted to sizer unit (approx 14px) + Center( + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: context.dynamicTextStyle( + color: Colors.black, + fontSize: 14.fSize, // Adjusted to sizer unit + height: 26 / 16, // This height is a ratio, may need re-evaluation + fontWeight: FontWeight.w500, ), - ).withVerticalPadding(2.sp), // Adjusted to sizer unit - ), - ], - ), + children: [ + TextSpan(text: LocaleKeys.dontHaveAccount.tr(), style: context.dynamicTextStyle()), + TextSpan(text: " "), + TextSpan( + text: LocaleKeys.registernow.tr(), + style: context.dynamicTextStyle( + color: AppColors.primaryRedColor, + fontSize: 14.fSize, // Adjusted to sizer unit + height: 26 / 16, // Ratio + fontWeight: FontWeight.w500, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).push( + MaterialPageRoute(builder: (BuildContext context) => RegisterNew()), + ); + }, + ), + ], + ), + ).withVerticalPadding(2), // Adjusted to sizer unit + ), + ], ), ), ), - ); - }); + ), + ); } } diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index 9b900b5..5564c46 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -1,579 +1,211 @@ -// import'dart:convert'; -// -// import 'package:easy_localization/easy_localization.dart'; -// import 'package:flutter/gestures.dart'; -// import 'package:flutter_svg/flutter_svg.dart'; -// import 'package:hijri_gregorian_calendar/hijri_gregorian_calendar.dart'; -// import 'package:hmg_patient_app/config/config.dart'; -// import 'package:hmg_patient_app/config/shared_pref_kay.dart'; -// import 'package:hmg_patient_app/config/size_config.dart'; -// import 'package:hmg_patient_app/core/service/client/base_app_client.dart'; -// import 'package:hmg_patient_app/core/viewModels/project_view_model.dart'; -// import 'package:hmg_patient_app/models/Appointments/toDoCountProviderModel.dart'; -// import 'package:hmg_patient_app/models/Authentication/check_activation_code_response.dart'; -// import 'package:hmg_patient_app/models/Authentication/check_paitent_authentication_req.dart'; -// import 'package:hmg_patient_app/models/Authentication/check_user_status_reponse.dart'; -// import 'package:hmg_patient_app/models/Authentication/check_user_status_req.dart'; -// import 'package:hmg_patient_app/models/Authentication/checkpatient_for_registration.dart'; -// import 'package:hmg_patient_app/models/Authentication/register_info_response.dart'; -// import 'package:hmg_patient_app/models/Authentication/send_activation_request.dart'; -// import 'package:hmg_patient_app/new_ui/new_ext.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/pages/login/register_new_step_2.dart'; -// import 'package:hmg_patient_app/pages/login/user-login-agreement-page.dart'; -// import 'package:hmg_patient_app/pages/login/welcome.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/app_toast.dart'; -// import 'package:hmg_patient_app/uitl/font_utils.dart'; -// import 'package:hmg_patient_app/uitl/gif_loader_dialog_utils.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/drawer/langauge_picker.dart'; -// import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart'; -// import 'package:flutter/material.dart'; -// import 'package:hmg_patient_app/widgets/otp/sms-popup.dart'; -// import 'package:hmg_patient_app/widgets/text/app_texts_widget.dart'; -// import 'package:hmg_patient_app_new/core/app_state.dart'; -// import 'package:hmg_patient_app_new/core/enums.dart'; -// import 'package:hmg_patient_app_new/core/utils/utils.dart'; -// import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; -// import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -// import 'package:hmg_patient_app_new/widgets/dropdown_widget.dart'; -// import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -// import 'package:provider/provider.dart'; -// -// import '../../core/viewModels/appointment_rate_view_model.dart'; -// import '../../locator.dart'; -// import '../../models/Authentication/authenticated_user.dart'; -// import '../../models/Authentication/select_device_imei_res.dart'; -// import '../../models/InPatientServices/get_admission_info_response_model.dart'; -// import '../../models/InPatientServices/get_admission_request_info_response_model.dart'; -// import '../../new_ui/exception_widget/ExceptionBottomSheet.dart'; -// import '../../services/clinic_services/get_clinic_service.dart'; -// import '../../widgets/dialogs/alert_dialog.dart'; -// import '../../widgets/dialogs/confirm_dialog.dart'; -// import '../../widgets/transitions/fade_page.dart'; -// import 'package:intl/intl.dart' as intl; -// -// import '../landing/landing_page.dart'; -// import '../rateAppointment/rate_appointment_doctor.dart'; -// -// class RegisterNew extends StatefulWidget { -// @override -// _RegisterNew createState() => _RegisterNew(); -// } -// -// class _RegisterNew extends State { -// @override -// void initState() { -// super.initState(); -// } -// -// @override -// void dispose() { -// super.dispose(); -// } -// -// @override -// Widget build(BuildContext context) { -// -// AppState appState = getIt.get(); -// return Scaffold( -// body: GestureDetector( -// onTap: () { -// FocusScope.of(context).unfocus(); -// }, -// child: ScrollConfiguration( -// behavior: ScrollConfiguration.of(context).copyWith(overscroll: false, physics: const ClampingScrollPhysics()), -// child: NotificationListener( -// onNotification: (notification) { -// notification.disallowIndicator(); -// return true; -// }, -// child: SingleChildScrollView( -// physics: ClampingScrollPhysics(), -// padding: EdgeInsets.only( -// left: 24, -// right: 24, -// ), -// child: Column( -// mainAxisSize: MainAxisSize.min, -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Utils.showLottie( -// context: context, -// assetPath: 'assets/animations/lottie/register.json', -// width: MediaQuery -// .of(context) -// .size -// .width * 0.45, -// height: MediaQuery -// .of(context) -// .size -// .height * 0.22, -// fit: BoxFit.cover, -// repeat: true), -// SizedBox(height: 8), -// LocaleKeys.prepareToElevate.tr().toText28( -// textScaler: TextScaler.linear(MediaQuery.textScalerOf(context).scale(1)), -// ), -// SizedBox(height: 24), -// Directionality( -// textDirection: Directionality.of(context), -// child: Container( -// decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), -// padding: EdgeInsets.only(left: 16, right: 16, top: 0, bottom: 0), -// child: Column( -// children: [ -// DropdownWidget( -// labelText: LocaleKeys.country.tr(), -// hintText: LocaleKeys.ksa.tr(), -// isEnable: true, -// selectedValue: AppStat.selectedLanguage == "ar" ? selectedCountry.nameArabic : selectedCountry.displayName, -// dropdownItems: Country.values.map((e) => "ar" ? e.displayName : e.displayName).toList(), -// -// // dropdownItems: Country.values.map((e) => (e.name).first).toList(), -// // dropdownItems: Country.values.map((e) => "ar" ? e.nameArabic : e.displayName).toList(), -// // selectedValue: context.selectedLanguage == "ar" ? selectedCountry.nameArabic : selectedCountry.displayName, -// // selectionType: SelectionType.dropdown, -// onChange: (val) { -// if (val != null) { -// } -// }, -// isBorderAllowed: false, -// isAllowLeadingIcon: true, -// hasSelectionCustomIcon: true, -// removePadding: true, -// isLeadingCountry: true, -// isAllowRadius: false, -// padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), -// selectionCustomIcon: "assets/images/svg/arrow-down.svg", -// leadingIcon: selectedCountry.iconPath, -// ).withVerticalPadding(8), -// Divider(height: 1), -// Directionality( -// textDirection: TextDirection.ltr, -// child: newInputWidget(TranslationBase -// .of(context) -// .nationalIdNumber, "xxxxxxxxx", nationalIDorFile, -// isEnable: true, -// prefix: null, -// removePadding: true, -// isAllowRadius: false, -// hasSelection: false, -// isBorderAllowed: false, -// isAllowLeadingIcon: true, -// autoFocus: true, -// padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), -// leadingIcon: "assets/images/svg/student-card.svg", -// onChange: (value) { -// print(value); -// }).withVerticalPadding(8), -// ), -// Divider(height: 1), -// Directionality( -// textDirection: TextDirection.ltr, -// child: newInputWidget(TranslationBase -// .of(context) -// .dob, "11 July, 1994", nationalIDorFile, -// isEnable: true, -// prefix: null, -// hasSelection: true, -// removePadding: true, -// isBorderAllowed: false, -// isAllowLeadingIcon: true, -// hasSelectionCustomIcon: true, -// selectionType: SelectionType.calendar, -// selectedValue: selectedDOB != null -// ? isHijri == 1 -// ? Utils.formatHijriDateToDisplay(selectedDOB!.toIso8601String()) -// : Utils.formatDateToDisplay(selectedDOB.toString()) -// : null, -// selectionCustomIcon: "assets/images/svg/calendar.svg", -// lang: context.selectedLanguage, -// padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), -// leadingIcon: "assets/images/svg/birthday-cake.svg", -// onChange: (value) { -// selectedDOB = DateTime.parse(value!); -// if (isHijri == 1) { -// var hijriDate = HijriGregConverter.gregorianToHijri(DateTime.parse(value)); -// selectedDOB = DateTime(hijriDate.year, hijriDate.month, hijriDate.day); -// } else { -// selectedDOB = DateTime.parse(value); -// } -// print(selectedDOB!.toIso8601String()); -// setState(() {}); -// }, -// onCalendarTypeChanged: (bool value) { -// if (value) { -// isHijri = 0; -// } else { -// isHijri = 1; -// } -// }).withVerticalPadding(8), -// ), -// ], -// ), -// ), -// ), -// SizedBox(height: 25), -// GestureDetector( -// onTap: () { -// setState(() { -// isTermsAccepted = !isTermsAccepted; -// }); -// }, -// child: Row( -// children: [ -// AnimatedContainer( -// duration: const Duration(milliseconds: 200), -// height: 24, -// width: 24, -// decoration: BoxDecoration( -// color: isTermsAccepted ? const Color(0xFFE92227) : Colors.transparent, -// borderRadius: BorderRadius.circular(6), -// border: Border.all( -// color: isTermsAccepted ? const Color(0xFFE92227) : Colors.grey, -// width: 2, -// ), -// ), -// child: isTermsAccepted ? const Icon(Icons.check, size: 16, color: Colors.white) : null, -// ), -// SizedBox(width: 12), -// Expanded( -// child: Text( -// TranslationBase -// .of(context) -// .iAcceptTermsConditions, -// style: context.dynamicTextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), -// ), -// ), -// ], -// ), -// ), -// SizedBox(height: 25), -// CustomButton( -// text: TranslationBase -// .of(context) -// .register, -// icon: "assets/images/svg/note-edit.svg", -// onPressed: () { -// // bool isValid = Utils.validateIqama(nationalIDorFile.text); -// if (nationalIDorFile == null || nationalIDorFile.text.isEmpty) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseEnterNationalId, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// // Utils.showErrorToast(TranslationBase.of(context).pleaseEnterNationalId); -// return; -// } -// if ((!Utils.validateIqama(nationalIDorFile.text) && selectedCountry.countryCode == '966') || -// (!Utils.validateUaeNationalId(nationalIDorFile.text) && selectedCountry.countryCode == '971')) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .incorrectNationalId, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// return; -// } -// if (selectedCountry == null || selectedCountry.countryCode.isEmpty) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseSelectCountry, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// return; -// } -// -// if (selectedDOB == null) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseSelectDOB, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// return; -// } -// if (!isTermsAccepted) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseAcceptTermsConditions, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// return; -// } -// -// if (phoneController != null) { -// phoneController.clear(); -// } -// 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, -// onChange: (String? value) { -// mobileNo = value!; -// }, -// buttons: [ -// Padding( -// padding: const EdgeInsets.only(bottom: 10), -// child: CustomButton( -// text: TranslationBase -// .of(context) -// .sendOTPSMS, -// onPressed: () { -// if (mobileNo.isEmpty) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseEnterMobile, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// } else if (!Utils.validateMobileNumber(mobileNo)) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseEnterValidMobile, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// } else { -// registerUser(1); -// } -// }, -// backgroundColor: CustomColors.bgRedColor, -// borderColor: CustomColors.bgRedBorderColor, -// 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( -// TranslationBase -// .of(context) -// .oR, -// fontSize: 16, -// fontFamily: context.fontFamily, -// color: Color(0xFF2E3039), -// fontWeight: FontWeight.w500, -// ), -// ), -// ], -// ), -// Padding( -// padding: const EdgeInsets.only(bottom: 10, top: 10), -// child: CustomButton( -// text: TranslationBase -// .of(context) -// .sendOTPWHATSAPP, -// onPressed: () { -// if (mobileNo.isEmpty) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseEnterMobile, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// } else if (!Utils.validateMobileNumber(mobileNo)) { -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: TranslationBase -// .of(context) -// .pleaseEnterValidMobile, -// showCancel: false, -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// ), -// ); -// } else { -// registerUser(4); -// } -// // int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, mobileNo, context); -// // registerUser(val); -// }, -// backgroundColor: Colors.white, -// borderColor: Color(0xFF2E3039), -// textColor: Color(0xFF2E3039), -// icon: "assets/images/svg/whatsapp.svg", -// ), -// ), -// ], -// myFocusNode: myFocusNode, -// ), -// ), -// ), -// ); -// Future.delayed(Duration(milliseconds: 500), () { -// myFocusNode.requestFocus(); -// }); -// }, -// fontFamily: context.fontFamily, -// ), -// SizedBox(height: 14), -// Center( -// child: RichText( -// textAlign: TextAlign.center, -// text: TextSpan( -// style: context.dynamicTextStyle( -// color: Colors.black, -// fontSize: 16, -// height: 26 / 16, -// fontWeight: FontWeight.w500, -// ), -// children: [ -// TextSpan(text: TranslationBase -// .of(context) -// .alreadyHaveAccount, style: context.dynamicTextStyle()), -// TextSpan(text: " "), -// TextSpan( -// text: TranslationBase -// .of(context) -// .loginNow, -// style: context.dynamicTextStyle( -// color: CustomColors.bgRedColor, -// fontSize: 16, -// height: 26 / 16, -// fontWeight: FontWeight.w500, -// ), -// recognizer: TapGestureRecognizer() -// ..onTap = () { -// Navigator.of(context).pop(); -// }, -// ), -// ], -// ), -// ), -// ), -// SizedBox(height: 30), -// ], -// ), -// ), -// ), -// ),) -// ); -// } -// -// 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, -// ), -// ), -// ), -// ], -// ) -// ], -// ); -// } -// } +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/enums.dart'; +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/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart' show CustomButton; +import 'package:hmg_patient_app_new/widgets/dropdown/country_dropdown_widget.dart'; +import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; + +class RegisterNew extends StatefulWidget { + @override + _RegisterNew createState() => _RegisterNew(); +} + +class _RegisterNew extends State { + bool isTermsAccepted = true; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + AppState appState = getIt.get(); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + appBar: CustomAppBar( + onBackPressed: () { + Navigator.of(context).pop(); + }, + onLanguageChanged: (String value) { + // context.setLocale(value == 'en' ? Locale('ar', 'SA') : Locale('en', 'US')); + }, + ), + body: GestureDetector( + onTap: () { + FocusScope.of(context).unfocus(); + }, + child: ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith(overscroll: false, physics: const ClampingScrollPhysics()), + child: NotificationListener( + onNotification: (notification) { + notification.disallowIndicator(); + return true; + }, + child: SingleChildScrollView( + physics: ClampingScrollPhysics(), + padding: EdgeInsets.symmetric(horizontal: 24.h), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.h, height: 200.h, fit: BoxFit.cover, repeat: true), + SizedBox(height: 16.h), + LocaleKeys.prepareToElevate.tr().toText32(isBold: true), + SizedBox(height: 24.h), + Directionality( + textDirection: Directionality.of(context), + child: Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), + padding: EdgeInsets.symmetric(horizontal: 16.h), + child: Column( + children: [ + CustomCountryDropdown( + countryList: Country.values, + onCountryChange: (Country? value) {}, + isRtl: Directionality.of(context) == TextDirection.LTR, + ).withVerticalPadding(8.h), + + // DropdownWidget( + // labelText: LocaleKeys.country.tr(), + // hintText: LocaleKeys.ksa.tr(), + // isEnable: true, + // selectedValue: appState.getLanguageID(context) == "1" ? "selectedCountry.nameArabic" : "selectedCountry.displayName", + // dropdownItems: Country.values.map((e) => appState.getLanguageID(context) == " 1" ? e.displayName : e.displayName).toList(), + // onChange: (val) { + // if (val != null) {} + // }, + // isBorderAllowed: false, + // hasSelectionCustomIcon: true, + // isAllowRadius: false, + // padding: EdgeInsets.symmetric(vertical: 8.h), + // selectionCustomIcon: AppAssets.arrow_down, + // ).withVerticalPadding(8), + Divider(height: 1.h), + TextInputWidget( + labelText: LocaleKeys.nationalIdNumber.tr(), + hintText: "xxxxxxxxx", + controller: TextEditingController(), + isEnable: true, + prefix: null, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + + autoFocus: true, + padding: EdgeInsets.symmetric(vertical: 8.h), + leadingIcon: AppAssets.student_card, + onChange: (value) { + print(value); + }).withVerticalPadding(8), + Divider(height: 1), + TextInputWidget( + labelText: LocaleKeys.dob.tr(), + hintText: "11 July, 1994", + controller: TextEditingController(), + isEnable: true, + prefix: null, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + padding: EdgeInsets.symmetric(vertical: 8.h), + leadingIcon: AppAssets.birthday_cake, + onChange: (value) {}, + ).withVerticalPadding(8), + ], + ), + ), + ), + SizedBox(height: 25.h), + GestureDetector( + onTap: () {}, + child: Row( + children: [ + AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: 24.h, + width: 24.h, + decoration: BoxDecoration( + color: isTermsAccepted ? const Color(0xFFE92227) : Colors.transparent, + borderRadius: BorderRadius.circular(6), + border: Border.all( + color: isTermsAccepted ? const Color(0xFFE92227) : Colors.grey, + width: 2.h, + ), + ), + child: isTermsAccepted ? Icon(Icons.check, size: 16.fSize, color: Colors.white) : null, + ), + SizedBox(width: 12.h), + Expanded( + child: Text( + LocaleKeys.iAcceptTermsConditions.tr(), + style: context.dynamicTextStyle(fontSize: 14.fSize, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), + ), + ), + ], + ), + ), + SizedBox(height: 25.h), + CustomButton( + text: "Register", + icon: AppAssets.note_edit, + onPressed: () {}, + ), + SizedBox(height: 14), + Center( + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: context.dynamicTextStyle( + color: Colors.black, + fontSize: 16.fSize, + height: 26 / 16, + fontWeight: FontWeight.w500, + ), + children: [ + TextSpan(text: LocaleKeys.alreadyHaveAccount.tr(), style: context.dynamicTextStyle()), + TextSpan(text: " "), + TextSpan( + text: LocaleKeys.loginNow.tr(), + style: context.dynamicTextStyle( + color: AppColors.primaryRedColor, + fontSize: 16.fSize, + height: 26 / 16, + fontWeight: FontWeight.w500, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).pop(); + }, + ), + ], + ), + ), + ), + SizedBox(height: 30), + ], + ), + ), + ),) + , + ) + ); + } +} diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index feb7f69..dd9f85c 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -9,6 +9,7 @@ import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; @@ -44,8 +45,8 @@ class _LandingPageState extends State { CustomButton( text: LocaleKeys.loginOrRegister.tr(context: context), onPressed: () { - Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (BuildContext context) => LandingPage()), + Navigator.of(context).push( + MaterialPageRoute(builder: (BuildContext context) => LoginScreen()), ); }, backgroundColor: Color(0xffFEE9EA), diff --git a/lib/providers/authentication_view_model.dart b/lib/providers/authentication_view_model.dart deleted file mode 100644 index 1641148..0000000 --- a/lib/providers/authentication_view_model.dart +++ /dev/null @@ -1,6 +0,0 @@ - -import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/app_state.dart'; -class AuthenticationViewModel extends ChangeNotifier { -// Add properties and methods related to authentication here -} diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index b7a1fb4..252d887 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -30,6 +30,7 @@ class AppColors { static const Color textColor = Color(0xFF2E3039); static const Color borderOnlyColor = Color(0xFF2E3039); static const blackColor = textColor; + static const inputLabelTextColor = Color(0xff898A8D); //Chips static const Color successColor = Color(0xff18C273); diff --git a/lib/widgets/appbar/app_bar_widget.dart b/lib/widgets/appbar/app_bar_widget.dart index dde02ed..2fdbc94 100644 --- a/lib/widgets/appbar/app_bar_widget.dart +++ b/lib/widgets/appbar/app_bar_widget.dart @@ -1,7 +1,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +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/widgets/language_switcher.dart'; import '../../generated/locale_keys.g.dart'; @@ -24,45 +26,44 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { return AppBar( backgroundColor: Colors.transparent, leading: null, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // Arrow Back with click handler - Expanded( - child: Align( - alignment: Alignment.centerLeft, - child: GestureDetector( - onTap: onBackPressed, - child: Utils.buildSvgWithAssets( - icon: AppAssets.arrow_back, - width: 32, - height: 32, + automaticallyImplyLeading: false, + title: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: GestureDetector( + onTap: onBackPressed, + child: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 32.h, height: 32.h), ), ), ), - ), - // Logo - Utils.buildSvgWithAssets( - icon: AppAssets.habiblogo, - ), + // Logo + Utils.buildSvgWithAssets( + icon: AppAssets.habiblogo, + ), - // Language Selector - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: LanguageSelector( - currentLanguage: context.locale.languageCode, - showOnlyIcon: false, - onLanguageChanged: onLanguageChanged, - languages: [ - {'code': 'ar', 'name': LocaleKeys.arabic.tr()}, - {'code': 'en', 'name': LocaleKeys.english.tr()} - ], + // Language Selector + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: LanguageSelector( + currentLanguage: context.locale.languageCode, + showOnlyIcon: false, + onLanguageChanged: onLanguageChanged, + languages: [ + {'code': 'ar', 'name': LocaleKeys.arabic.tr()}, + {'code': 'en', 'name': LocaleKeys.english.tr()} + ], + ), ), ), - ), - ], + ], + ), ), centerTitle: true, ); diff --git a/lib/widgets/bottomsheet/exception_bottom_sheet.dart b/lib/widgets/bottomsheet/exception_bottom_sheet.dart new file mode 100644 index 0000000..f0ea651 --- /dev/null +++ b/lib/widgets/bottomsheet/exception_bottom_sheet.dart @@ -0,0 +1,111 @@ +import 'dart:io'; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +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/string_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; + +class ExceptionBottomSheet extends StatelessWidget { + String message; + bool showOKButton; + bool showCancel; + Function() onOkPressed; + Function()? onCancelPressed; + + ExceptionBottomSheet({Key? key, required this.message, this.showOKButton = true, this.showCancel = false, required this.onOkPressed, this.onCancelPressed}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SafeArea( + bottom: Platform.isIOS ? false : true, // Adjust for iOS to avoid bottom padding + child: GestureDetector( + onTap: () { + FocusScope.of(context).unfocus(); // Dismiss the keyboard when tapping outside + }, + child: Builder(builder: (context) { + return Directionality( + textDirection: Directionality.of(context), + child: Container( + padding: EdgeInsets.all(24.h), + decoration: BoxDecoration( + color: Color(0xFFF8F8FA), + borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.notice.tr().toText28(), + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: Utils.buildSvgWithAssets(icon: AppAssets.cross_circle), + ) + ], + ), + SizedBox(height: 10.h), + (message ?? "").toText16(isBold: false, color: AppColors.textColor), + SizedBox(height: 10.h), + SizedBox(height: 24.h), + if (showOKButton && showCancel) + Row( + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.cancel.tr(), + onPressed: onCancelPressed != null + ? onCancelPressed! + : () { + Navigator.of(context).pop(); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + icon: AppAssets.cancel, + iconColor: AppColors.primaryRedColor, + ), + ), + SizedBox(width: 5.h), + Expanded( + child: CustomButton( + text: showCancel ? LocaleKeys.confirm.tr() : LocaleKeys.ok.tr(), + onPressed: onOkPressed, + backgroundColor: AppColors.bgGreenColor, + borderColor: AppColors.bgGreenColor, + textColor: Colors.white, + icon: AppAssets.confirm, + ), + ), + ], + ), + if (showOKButton && !showCancel) + Padding( + padding: EdgeInsets.only(bottom: 10.h), + child: CustomButton( + text: LocaleKeys.ok.tr(), + onPressed: onOkPressed, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedBorderColor, + textColor: Colors.white, + icon: AppAssets.confirm, + ), + ), + ], + ), + ), + ); + }), + ), + ); + } +} diff --git a/lib/widgets/dropdown/country_dropdown_widget.dart b/lib/widgets/dropdown/country_dropdown_widget.dart new file mode 100644 index 0000000..81ac60a --- /dev/null +++ b/lib/widgets/dropdown/country_dropdown_widget.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/enums.dart'; +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/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; + +class CustomCountryDropdown extends StatefulWidget { + final List countryList; + final Function(Country)? onCountryChange; + final bool isRtl; + + const CustomCountryDropdown({ + Key? key, + required this.countryList, + this.onCountryChange, + required this.isRtl, + }) : super(key: key); + + @override + _CustomCountryDropdownState createState() => _CustomCountryDropdownState(); +} + +class _CustomCountryDropdownState extends State { + Country? selectedCountry; + late OverlayEntry _overlayEntry; + bool _isDropdownOpen = false; + + @override + void initState() { + super.initState(); + selectedCountry = Country.saudiArabia; + } + + @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), + Text( + selectedCountry != null ? selectedCountry!.displayName : "Select Country", + style: TextStyle( + fontSize: 14.fSize, + height: 21 / 14, + fontWeight: FontWeight.w500, + letterSpacing: -0.2, + ), + ), + ], + ), + ), + ); + } + + void _openDropdown() { + RenderBox renderBox = context.findRenderObject() as RenderBox; + Offset offset = renderBox.localToGlobal(Offset.zero); + + _overlayEntry = OverlayEntry( + builder: (context) => Stack( + children: [ + // Dismiss dropdown when tapping outside + Positioned.fill( + child: GestureDetector( + onTap: _closeDropdown, + behavior: HitTestBehavior.translucent, + child: Container(), + ), + ), + Positioned( + top: offset.dy + renderBox.size.height, + left: widget.isRtl ? offset.dx + 15.h : offset.dx - 15.h, + width: renderBox.size.width, + child: Material( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: Colors.white, + borderRadius: 12, + ), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(12), + // boxShadow: [ + // BoxShadow( + // color: Color(0xFFF8F8FA), + // blurRadius: 8.h, + // offset: Offset( + // 0, + // 2, + // ), + // ), + // ], + // ), + child: Column( + children: widget.countryList + .map( + (country) => GestureDetector( + onTap: () { + setState(() { + selectedCountry = country; + }); + widget.onCountryChange?.call(country); + _closeDropdown(); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 16.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + borderRadius: 16.h, + ), + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: country.iconPath, + width: 38.h, + height: 38.h, + ), + SizedBox(width: 12.h), + Text(country.displayName, + style: TextStyle( + fontSize: 14.fSize, + height: 21 / 14, + fontWeight: FontWeight.w500, + letterSpacing: -0.2, + )), + ], + ), + ), + ), + ) + .toList(), + ), + ), + ), + ), + ], + ), + ); + + Overlay.of(context)?.insert(_overlayEntry); + setState(() { + _isDropdownOpen = true; + }); + } + + void _closeDropdown() { + _overlayEntry.remove(); + setState(() { + _isDropdownOpen = false; + }); + } +} diff --git a/lib/widgets/dropdown_widget.dart b/lib/widgets/dropdown/dropdown_widget.dart similarity index 56% rename from lib/widgets/dropdown_widget.dart rename to lib/widgets/dropdown/dropdown_widget.dart index a778f2e..268e44a 100644 --- a/lib/widgets/dropdown_widget.dart +++ b/lib/widgets/dropdown/dropdown_widget.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart' show Icons, PopupMenuItem, showMenu, Colors; +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'; @@ -38,10 +39,8 @@ class DropdownWidget extends StatelessWidget { alignment: Alignment.center, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: Colors.white, - borderRadius: isAllowRadius ? 15 : null, - side: isBorderAllowed - ? BorderSide(color: const Color(0xffefefef), width: 1) - : null, + borderRadius: isAllowRadius ? 15.h : null, + side: isBorderAllowed ? BorderSide(color: const Color(0xffefefef), width: 1) : null, ), child: Column( mainAxisSize: MainAxisSize.min, @@ -57,8 +56,8 @@ class DropdownWidget extends StatelessWidget { Widget _buildLabelText() { return Text( labelText, - style: const TextStyle( - fontSize: 12, + style: TextStyle( + fontSize: 12.fSize, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -0.2, @@ -71,33 +70,41 @@ class DropdownWidget extends StatelessWidget { return GestureDetector( onTap: isEnable ? () async { - 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 + renderBox.size.width, - 0, - ), - items: dropdownItems - .map( - (e) => PopupMenuItem( - value: e, - child: Text(e), - ), - ) - .toList(), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - ); + 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 + renderBox.size.width, + 0, + ), + items: dropdownItems + .map( + (e) => PopupMenuItem( + value: e, + child: Text( + e, + style: TextStyle( + fontSize: 14.fSize, + height: 21 / 14, + fontWeight: FontWeight.w500, + letterSpacing: -0.2, + ), + ), + ), + ) + .toList(), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ); - if (selected != null && onChange != null) { - onChange!(selected); - } - } + if (selected != null && onChange != null) { + onChange!(selected); + } + } : null, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -105,28 +112,21 @@ class DropdownWidget extends StatelessWidget { children: [ Expanded( child: Text( - (selectedValue == null || selectedValue!.isEmpty) - ? hintText - : selectedValue!, + (selectedValue == null || selectedValue!.isEmpty) ? hintText : selectedValue!, textAlign: TextAlign.left, textDirection: TextDirection.ltr, style: TextStyle( - fontSize: 14, + fontSize: 14.fSize, height: 21 / 14, fontWeight: FontWeight.w500, - color: (selectedValue != null && selectedValue!.isNotEmpty) - ? const Color(0xff2E3039) - : const Color(0xffB0B0B0), + color: (selectedValue != null && selectedValue!.isNotEmpty) ? const Color(0xff2E3039) : const Color(0xffB0B0B0), letterSpacing: -0.2, ), ), ), - if (hasSelectionCustomIcon && selectionCustomIcon != null) - Utils.buildSvgWithAssets(icon: selectionCustomIcon!) - else - const Icon(Icons.keyboard_arrow_down_outlined), + if (hasSelectionCustomIcon && selectionCustomIcon != null) Utils.buildSvgWithAssets(icon: selectionCustomIcon!) else const Icon(Icons.keyboard_arrow_down_outlined), ], ), ); } -} \ No newline at end of file +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index f2446a7..ca72fe8 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_export.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'; // TODO: Import AppColors if bgRedColor is defined there // import 'package:hmg_patient_app_new/core/ui_utils/app_colors.dart'; @@ -54,9 +56,7 @@ class TextInputWidget extends StatelessWidget { @override Widget build(BuildContext context) { - // Assuming AppColors.bgRedColor exists, otherwise using Colors.red - final errorColor = Colors.red; // Replace with AppColors.bgRedColor if available - + final errorColor = AppColors.primaryRedColor; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -66,7 +66,7 @@ class TextInputWidget extends StatelessWidget { alignment: Alignment.center, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: Colors.white, - borderRadius: isAllowRadius ? 15 : null, + borderRadius: isAllowRadius ? 12 : null, side: isBorderAllowed ? BorderSide(color: hasError ? errorColor : const Color(0xffefefef), width: 1) : null, ), child: Row( @@ -88,12 +88,12 @@ class TextInputWidget extends StatelessWidget { ), if (hasError && errorMessage != null) Padding( - padding: const EdgeInsets.only(top: 4.0, left: 12.0), // Adjust padding as needed + padding: EdgeInsets.only(top: 4.h, left: 12.h), // Adjust padding as needed child: Text( errorMessage!, style: TextStyle( color: errorColor, - fontSize: 12, + fontSize: 12.fSize, ), ), ), @@ -103,21 +103,24 @@ class TextInputWidget extends StatelessWidget { Widget _buildLeadingIcon(BuildContext context) { return Container( - height: 40, - width: 40, - margin: const EdgeInsets.only(right: 10), - padding: const EdgeInsets.all(8), - decoration: const BoxDecoration(color: Color(0xFFEFEFF0), borderRadius: BorderRadius.all(Radius.circular(10))), + 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, - style: const TextStyle( - fontSize: 12, + style: TextStyle( + fontSize: 12.fSize, fontWeight: FontWeight.w500, - color: Color(0xff898A8D), + color: AppColors.inputLabelTextColor, letterSpacing: -0.2, height: 18 / 12, ), @@ -137,30 +140,30 @@ class TextInputWidget extends StatelessWidget { onChanged: onChange, focusNode: focusNode, autofocus: autoFocus, - style: const TextStyle( - fontSize: 14, + style: TextStyle( + fontSize: 14.fSize, height: 21 / 14, fontWeight: FontWeight.w500, - color: Color(0xff2E3039), + color: AppColors.textColor, letterSpacing: -0.2, ), decoration: InputDecoration( isDense: true, hintText: hintText, - hintStyle: const TextStyle( - fontSize: 14, + hintStyle: TextStyle( + fontSize: 14.fSize, height: 21 / 16, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -0.2, ), - prefixIconConstraints: const BoxConstraints(minWidth: 45), + prefixIconConstraints: BoxConstraints(minWidth: 45.h), prefixIcon: prefix == null ? null : Text( "+" + prefix!, - style: const TextStyle( - fontSize: 14, + style: TextStyle( + fontSize: 14.fSize, height: 21 / 14, fontWeight: FontWeight.w500, color: Color(0xff2E303A), diff --git a/lib/widgets/language_switcher.dart b/lib/widgets/language_switcher.dart index 4c621b7..4a81217 100644 --- a/lib/widgets/language_switcher.dart +++ b/lib/widgets/language_switcher.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +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/string_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -51,18 +52,18 @@ class _LanguageSelectorState extends State { widget.onLanguageChanged(newLanguage); }, child: Container( - padding: EdgeInsets.all(8), + padding: EdgeInsets.all(8.h), decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)), child: Row( mainAxisSize: MainAxisSize.min, children: [ Utils.buildSvgWithAssets(icon: AppAssets.language), - const SizedBox(width: 6), + SizedBox(width: 6.h), Text( currentLangData['name']?.toUpperCase() ?? 'EN', style: context.dynamicTextStyle( fontWeight: FontWeight.w500, - fontSize: 14, + fontSize: 14.fSize, color: AppColors.primaryRedColor, letterSpacing: 0.1, isLanguageSwitcher: true, diff --git a/pubspec.lock b/pubspec.lock index c503e1b..679a57e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -29,10 +29,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" audio_session: dependency: transitive description: @@ -874,26 +874,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "11.0.1" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.10" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.1" lints: dependency: transitive description: @@ -1455,10 +1455,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.4" time: dependency: transitive description: @@ -1583,18 +1583,18 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "15.0.0" web: dependency: "direct main" description: @@ -1636,5 +1636,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.7.0 <4.0.0" flutter: ">=3.29.0"