From 64eb04011edb3bf05d355b710cd351f69f2c5f5c Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 22 Jun 2026 18:01:55 +0300 Subject: [PATCH] Clarity implementation updates --- lib/core/api/api_client.dart | 4 +- lib/core/utils/utils.dart | 2 + lib/presentation/authentication/login.dart | 152 +++++++++--------- .../immediate_livecare_payment_page.dart | 12 +- lib/presentation/home/landing_page.dart | 2 + lib/widgets/input_widget.dart | 115 ++++++------- 6 files changed, 150 insertions(+), 137 deletions(-) diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 9164d9cf..d2ea81f9 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -210,8 +210,8 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - body['TokenID'] = "@dm!n"; - // body['PatientID'] = 3648831; + // body['TokenID'] = "@dm!n"; + // body['PatientID'] = 4772993; // body['PatientID'] = 89754444; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 2d4cdfff..320bd1cf 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -4,12 +4,14 @@ import 'dart:io'; import 'dart:math' as dartMath; import 'dart:typed_data'; +import 'package:clarity_flutter/clarity_flutter.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:crypto/crypto.dart' as crypto; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get_it/get_it.dart'; import 'package:google_api_availability/google_api_availability.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index c38e9ad9..dee44de0 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -94,27 +94,29 @@ class LoginScreenState extends State { LocaleKeys.welcomeToDrSulaiman.tr(context: context).toText32(isBold: true, color: AppColors.textColor ), SizedBox(height: 32.h), Localizations.override(context: context, locale: Locale('en', 'US'), child: Container()), // Force English locale for this widget - TextInputWidget( - labelText: LocaleKeys.nationalIdFileNumber.tr(context: context), - hintText: "xxxxxxxxx", - controller: authVm.nationalIdController, - focusNode: _nationalIdFocusNode, - 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: authVm.nationalIdError, - hasError: authVm.nationalIdError != null, - fontFamily: "Poppins", - onChange: (value) { - // Clear error when user starts typing - authVm.clearNationalIdError(); - }, + ClarityUnmask( + child: TextInputWidget( + labelText: LocaleKeys.nationalIdFileNumber.tr(context: context), + hintText: "xxxxxxxxx", + controller: authVm.nationalIdController, + focusNode: _nationalIdFocusNode, + 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: authVm.nationalIdError, + hasError: authVm.nationalIdError != null, + fontFamily: "Poppins", + onChange: (value) { + // Clear error when user starts typing + authVm.clearNationalIdError(); + }, + ), ), SizedBox(height: 16.h), CustomButton( @@ -205,65 +207,67 @@ class LoginScreenState extends State { child: SingleChildScrollView( child: Consumer( builder: (context, authVm, child) { - return GenericBottomSheet( - countryCode: authVm.selectedCountrySignup.countryCode, - initialPhoneNumber: "", - textController: phoneNumberController, - isEnableCountryDropdown: true, - onCountryChange: (country) { - authVm.onCountryChange(country); - // Clear error when country changes - authVm.clearPhoneNumberError(); - }, - onChange: (value) { - authVm.onPhoneNumberChange(value); - // Clear error when user starts typing - authVm.clearPhoneNumberError(); - }, - phoneNumberError: authVm.phoneNumberError, - buttons: [ - if (authVm.selectedCountrySignup != CountryEnum.others) + return ClarityUnmask( + child: GenericBottomSheet( + countryCode: authVm.selectedCountrySignup.countryCode, + initialPhoneNumber: "", + textController: phoneNumberController, + isEnableCountryDropdown: true, + onCountryChange: (country) { + authVm.onCountryChange(country); + // Clear error when country changes + authVm.clearPhoneNumberError(); + }, + onChange: (value) { + authVm.onPhoneNumberChange(value); + // Clear error when user starts typing + authVm.clearPhoneNumberError(); + }, + phoneNumberError: authVm.phoneNumberError, + buttons: [ + if (authVm.selectedCountrySignup != CountryEnum.others) + Padding( + padding: EdgeInsets.only(bottom: 10.h), + child: CustomButton( + text: LocaleKeys.sendOTPSMS.tr(context: context), + onPressed: () async { + validatePhoneAndProceed(OTPTypeEnum.sms); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedBorderColor, + textColor: Colors.white, + iconColor: Colors.white, + icon: AppAssets.message, + ), + ), + if (authVm.selectedCountrySignup != CountryEnum.others) + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.h), + child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor), + ), + ], + ), Padding( - padding: EdgeInsets.only(bottom: 10.h), + padding: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(context: context), + text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), onPressed: () async { - validatePhoneAndProceed(OTPTypeEnum.sms); + validatePhoneAndProceed(OTPTypeEnum.whatsapp); }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedBorderColor, - textColor: Colors.white, - iconColor: Colors.white, - icon: AppAssets.message, + backgroundColor: AppColors.whiteColor, + borderColor: AppColors.textColor, + textColor: AppColors.textColor, + icon: AppAssets.whatsapp, + iconColor: null, + applyThemeColor: false, ), ), - if (authVm.selectedCountrySignup != CountryEnum.others) - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 8.h), - child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor), - ), - ], - ), - Padding( - padding: EdgeInsets.only(bottom: 10.h, top: 10.h), - child: CustomButton( - text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), - onPressed: () async { - validatePhoneAndProceed(OTPTypeEnum.whatsapp); - }, - backgroundColor: AppColors.whiteColor, - borderColor: AppColors.textColor, - textColor: AppColors.textColor, - icon: AppAssets.whatsapp, - iconColor: null, - applyThemeColor: false, - ), - ), - ], + ], + ), ); }, ), diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart index aa23fef8..04fd3073 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart @@ -63,11 +63,13 @@ class _ImmediateLiveCarePaymentPageState extends State= myAppointmentsViewModel.getTamaraInstallmentsDetailsResponseModel!.minLimit!.amount! && - num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!) <= myAppointmentsViewModel.getTamaraInstallmentsDetailsResponseModel!.maxLimit!.amount!) { - setState(() { - isShowTamara = true; - }); + if (myAppointmentsViewModel.getTamaraInstallmentsDetailsResponseModel != null) { + if (num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!) >= myAppointmentsViewModel.getTamaraInstallmentsDetailsResponseModel!.minLimit!.amount! && + num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!) <= myAppointmentsViewModel.getTamaraInstallmentsDetailsResponseModel!.maxLimit!.amount!) { + setState(() { + isShowTamara = true; + }); + } } }); }); diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index f3719666..531b310a 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -145,6 +145,8 @@ class _LandingPageState extends State { } if (appState.isAuthenticated) { + Clarity.setCustomUserId(appState.getAuthenticatedUser()!.patientId.toString()); + habibWalletVM.initHabibWalletProvider(); habibWalletVM.getPatientBalanceAmount(); habibWalletVM.getLakumAccountInformation(); diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 16a955c8..b7fe686f 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -1,5 +1,6 @@ import 'dart:ui' as ui; +import 'package:clarity_flutter/clarity_flutter.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -405,64 +406,66 @@ class TextInputWidget extends StatelessWidget { child: Localizations.override( context: context, locale: const Locale('en', 'US'), // Force English locale for TextField - child: TextField( - hintLocales: const [Locale('en', 'US')], - enabled: isEnable, - scrollPadding: EdgeInsets.zero, - keyboardType: isMultiline - ? TextInputType.multiline - : (isWalletAmountInput! ? const TextInputType.numberWithOptions(decimal: true) : keyboardType), - controller: controller, - readOnly: isReadOnly, - textAlignVertical: TextAlignVertical.top, - textAlign: isArabic ? TextAlign.right : TextAlign.left, - textDirection: ui.TextDirection.ltr, - onChanged: onChange, - focusNode: focusNode ?? _focusNode, - autofocus: autoFocus, - textInputAction: TextInputAction.done, - cursorHeight: isWalletAmountInput! ? 40.h : 20.h, - maxLength: isWalletAmountInput! ? 7 : 100, - inputFormatters: isWalletAmountInput! - ? [ - _ThousandSeparatorInputFormatter(), - ] - : null, - onTapOutside: (event) { - FocusManager.instance.primaryFocus?.unfocus(); - }, - onSubmitted: onSubmitted, - minLines: isMultiline ? minLines : 1, - maxLines: isMultiline ? maxLines : 1, - style: TextStyle( - fontSize: fontS, - height: isMultiline ? 1.2 : (isWalletAmountInput! ? 1 / 4 : 0), - fontWeight: FontWeight.w600, - color: AppColors.textColor, - letterSpacing: -1, - fontFamily: fontFamily, - locale: const Locale('en', 'US'), // Force English locale for text style - ), - decoration: InputDecoration( - counterText: "", - isDense: true, - hintText: hintText, - hintStyle: TextStyle( - fontFamily: isArabic ? 'CairoArabic' : 'Poppins', - fontSize: 14.f, - height: 21 / 16, + child: ClarityUnmask( + child: TextField( + hintLocales: const [Locale('en', 'US')], + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isMultiline + ? TextInputType.multiline + : (isWalletAmountInput! ? const TextInputType.numberWithOptions(decimal: true) : keyboardType), + controller: controller, + readOnly: isReadOnly, + textAlignVertical: TextAlignVertical.top, + textAlign: isArabic ? TextAlign.right : TextAlign.left, + textDirection: ui.TextDirection.ltr, + onChanged: onChange, + focusNode: focusNode ?? _focusNode, + autofocus: autoFocus, + textInputAction: TextInputAction.done, + cursorHeight: isWalletAmountInput! ? 40.h : 20.h, + maxLength: isWalletAmountInput! ? 7 : 100, + inputFormatters: isWalletAmountInput! + ? [ + _ThousandSeparatorInputFormatter(), + ] + : null, + onTapOutside: (event) { + FocusManager.instance.primaryFocus?.unfocus(); + }, + onSubmitted: onSubmitted, + minLines: isMultiline ? minLines : 1, + maxLines: isMultiline ? maxLines : 1, + style: TextStyle( + fontSize: fontS, + height: isMultiline ? 1.2 : (isWalletAmountInput! ? 1 / 4 : 0), fontWeight: FontWeight.w600, - color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), - letterSpacing: -0.75, + color: AppColors.textColor, + letterSpacing: -1, + fontFamily: fontFamily, + locale: const Locale('en', 'US'), // Force English locale for text style + ), + decoration: InputDecoration( + counterText: "", + isDense: true, + hintText: hintText, + hintStyle: TextStyle( + fontFamily: isArabic ? 'CairoArabic' : 'Poppins', + fontSize: 14.f, + height: 21 / 16, + fontWeight: FontWeight.w600, + color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), + letterSpacing: -0.75, + ), + prefixIconConstraints: BoxConstraints(minWidth: 30.h), + prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, isBold: true), + contentPadding: EdgeInsets.only(right: isArabic ? 10.w : 0), + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + // Show red border when field has error - but we handle this in the parent Container + // The parent Container in build() already shows red border based on hasError flag ), - prefixIconConstraints: BoxConstraints(minWidth: 30.h), - prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, isBold: true), - contentPadding: EdgeInsets.only(right: isArabic ? 10.w : 0), - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - // Show red border when field has error - but we handle this in the parent Container - // The parent Container in build() already shows red border based on hasError flag ), ), ), -- 2.30.2