haroon_dev
haroon amjad 19 hours ago
parent 9986729ba5
commit 469479d7cb

@ -1848,5 +1848,7 @@
"submitEReferral": "تقديم الطلب", "submitEReferral": "تقديم الطلب",
"redeem": "استبدال", "redeem": "استبدال",
"points": "نقاط", "points": "نقاط",
"transactions": "المعاملات" "transactions": "المعاملات",
"pharmacy": "الصيدلية",
"visitsOrders": "الزيارات/الطلبات"
} }

@ -1838,7 +1838,9 @@
"submitEReferral": "Submit", "submitEReferral": "Submit",
"redeem": "Redeem", "redeem": "Redeem",
"points": "Points", "points": "Points",
"transactions": "Transactions" "transactions": "Transactions",
"pharmacy": "Pharmacy",
"visitsOrders": "Visits/Orders"
} }

@ -99,7 +99,11 @@ class Utils {
static bool isArabicText(String inputText) { static bool isArabicText(String inputText) {
bool isArabicText = false; bool isArabicText = false;
final arabic = RegExp(r'^[\u0621-\u064A]+'); // Updated regex to include:
// - Arabic letters: \u0621-\u064A
// - Arabic numerals: \u0660-\u0669 (٠-٩)
// - Persian numerals: \u06F0-\u06F9 (۰-۹)
final arabic = RegExp(r'[\u0621-\u064A\u0660-\u0669\u06F0-\u06F9]');
if (arabic.hasMatch(inputText)) { if (arabic.hasMatch(inputText)) {
isArabicText = true; isArabicText = true;
} else { } else {

@ -1479,6 +1479,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
result.fold( result.fold(
(failure) async { (failure) async {
if(onError != null) {
onError(failure.message);
}
onError!(LocaleKeys.noDoctorFound.tr()); onError!(LocaleKeys.noDoctorFound.tr());
}, },
(apiResponse) { (apiResponse) {

@ -30,6 +30,8 @@ class MyInvoicesViewModel extends ChangeNotifier {
String? downloadInvoicePDFBase64 = ""; String? downloadInvoicePDFBase64 = "";
int selectedTabIndex = 0;
MyInvoicesViewModel({required this.myInvoicesRepo, required this.errorHandlerService, required this.navServices}); MyInvoicesViewModel({required this.myInvoicesRepo, required this.errorHandlerService, required this.navServices});
setInvoicesListLoading() { setInvoicesListLoading() {
@ -45,6 +47,11 @@ class MyInvoicesViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void onTabChanged(int index) {
selectedTabIndex = index;
notifyListeners();
}
Future<void> getAllInvoicesList({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getAllInvoicesList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myInvoicesRepo.getAllInvoicesList(); final result = await myInvoicesRepo.getAllInvoicesList();

@ -1841,5 +1841,7 @@ abstract class LocaleKeys {
static const redeem = 'redeem'; static const redeem = 'redeem';
static const points = 'points'; static const points = 'points';
static const transactions = 'transactions'; static const transactions = 'transactions';
static const pharmacy = 'pharmacy';
static const visitsOrders = 'visitsOrders';
} }

@ -186,7 +186,6 @@ class LoginScreenState extends State<LoginScreen> {
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width), constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
backgroundColor: AppColors.transparent, backgroundColor: AppColors.transparent,
child: StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) { child: StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) {
// Helper function to validate phone number with error handling // Helper function to validate phone number with error handling
void validatePhoneAndProceed(OTPTypeEnum otpType) { void validatePhoneAndProceed(OTPTypeEnum otpType) {
// Use ViewModel validation method // Use ViewModel validation method

@ -22,6 +22,14 @@ class ClinicCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>(); AppState appState = getIt.get<AppState>();
// Get clinic icon path with fallback
String getClinicIconPath() {
final clinicId = clinicsListResponseModel.clinicID ?? 1;
// Try to use specific clinic icon, fallback to default if not found
return "assets/images/clinicIcons/$clinicId.svg";
}
return Container( return Container(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -32,7 +40,19 @@ class ClinicCard extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Utils.buildSvgWithAssets(icon: "assets/images/clinicIcons/${clinicsListResponseModel.clinicID ?? 1}.svg", width: 24.w, height: 24.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading), // Use Image.asset with error builder for fallback
SizedBox(
width: 24.w,
height: 24.h,
child: Utils.buildSvgWithAssets(
icon: getClinicIconPath(),
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
// Note: Add error handling in the Utils.buildSvgWithAssets if possible
// or use a try-catch wrapper
),
).toShimmer2(isShow: isLoading),
(clinicsListResponseModel.isLiveCareClinicAndOnline ?? true) (clinicsListResponseModel.isLiveCareClinicAndOnline ?? true)
? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.w, height: 32.h, fit: BoxFit.contain, applyThemeColor: false).toShimmer2(isShow: isLoading) ? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.w, height: 32.h, fit: BoxFit.contain, applyThemeColor: false).toShimmer2(isShow: isLoading)
: SizedBox.shrink(), : SizedBox.shrink(),

@ -18,6 +18,7 @@ import 'package:hmg_patient_app_new/presentation/my_invoices/widgets/invoice_lis
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:open_filex/open_filex.dart'; import 'package:open_filex/open_filex.dart';
@ -124,194 +125,211 @@ class _MyInvoicesListState extends State<MyInvoicesList> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( CustomTabBar(
children: [ activeTextColor: Color(0xffED1C2B),
CustomButton( activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
text: LocaleKeys.allInvoices.tr(context: context), initialIndex: 0,
onPressed: () { tabs: [
myInvoicesViewModel.filterInvoices(InvoiceFilterType.all); CustomTabBarModel(null, LocaleKeys.visitsOrders.tr(context: context)),
}, CustomTabBarModel(null, LocaleKeys.pharmacy.tr(context: context)),
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.bgRedLightColor : AppColors.whiteColor,
borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
textColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.primaryRedColor : AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w600,
borderRadius: 10,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
SizedBox(width: 8.h),
CustomButton(
text: LocaleKeys.hospitals.tr(context: context),
onPressed: () {
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showHospitalFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.bgRedLightColor : AppColors.whiteColor,
borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
textColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.primaryRedColor : AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w600,
borderRadius: 10,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
SizedBox(width: 8.h),
CustomButton(
text: LocaleKeys.clinics.tr(context: context),
onPressed: () {
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showClinicFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
textColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.primaryRedColor : AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w600,
borderRadius: 10,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
SizedBox(width: 8.h),
CustomButton(
text: LocaleKeys.doctors.tr(context: context),
onPressed: () {
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showDoctorFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.bgRedLightColor : AppColors.whiteColor,
borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
textColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.primaryRedColor : AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w600,
borderRadius: 10,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
], ],
onTabChange: (index) {
myInvoicesVM.onTabChanged(index);
},
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h), myInvoicesVM.selectedTabIndex == 0 ? Column(
ListView.builder( children: [
itemCount: myInvoicesVM.isInvoicesListLoading SizedBox(height: 16.h),
? 4 Row(
: myInvoicesVM.allInvoicesList.isEmpty children: [
? 1 CustomButton(
: myInvoicesVM.allInvoicesList.length, text: LocaleKeys.allInvoices.tr(context: context),
physics: NeverScrollableScrollPhysics(), onPressed: () {
shrinkWrap: true, myInvoicesViewModel.filterInvoices(InvoiceFilterType.all);
padding: EdgeInsetsGeometry.zero, },
itemBuilder: (context, index) { backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.bgRedLightColor : AppColors.whiteColor,
return myInvoicesVM.isInvoicesListLoading borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
? LabResultItemView(onTap: () {}, labOrder: null, index: index, isLoading: true) textColor: myInvoicesVM.currentFilter == InvoiceFilterType.all ? AppColors.primaryRedColor : AppColors.blackColor,
: myInvoicesVM.allInvoicesList.isNotEmpty fontSize: 12,
? AnimationConfiguration.staggeredList( fontWeight: FontWeight.w600,
position: index, borderRadius: 10,
duration: const Duration(milliseconds: 500), padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: SlideAnimation( height: 40.h,
verticalOffset: 100.0, ),
child: FadeInAnimation( SizedBox(width: 8.h),
child: AnimatedContainer( CustomButton(
duration: Duration(milliseconds: 300), text: LocaleKeys.hospitals.tr(context: context),
curve: Curves.easeInOut, onPressed: () {
child: InvoiceListCard( if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
getInvoicesListResponseModel: myInvoicesVM.allInvoicesList[index], _showHospitalFilterBottomSheet(context);
onTap: () async { },
if (Utils.isVidaPlusProject(myInvoicesVM.allInvoicesList[index].projectId ?? 0)) { backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.bgRedLightColor : AppColors.whiteColor,
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.sendingEmailPleaseWait.tr(context: context)); borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
await myInvoicesViewModel.sendInvoiceEmail( textColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.primaryRedColor : AppColors.blackColor,
appointmentNo: myInvoicesVM.allInvoicesList[index].appointmentNo!, fontSize: 12,
projectID: myInvoicesVM.allInvoicesList[index].projectId!, fontWeight: FontWeight.w600,
onSuccess: (val) { borderRadius: 10,
LoaderBottomSheet.hideLoader(); padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
showCommonBottomSheetWithoutHeight(context, height: 40.h,
child: Utils.getSuccessWidget(loadingText: LocaleKeys.emailSentSuccessfullyMessage.tr(context: context)), ),
callBackFunc: () {}, SizedBox(width: 8.h),
isFullScreen: false, CustomButton(
isCloseButtonVisible: true, text: LocaleKeys.clinics.tr(context: context),
isAutoDismiss: true); onPressed: () {
}, if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
onError: (err) { _showClinicFilterBottomSheet(context);
LoaderBottomSheet.hideLoader(); },
showCommonBottomSheetWithoutHeight( backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
context, borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
child: Utils.getErrorWidget(loadingText: err), textColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.primaryRedColor : AppColors.blackColor,
callBackFunc: () {}, fontSize: 12,
isFullScreen: false, fontWeight: FontWeight.w600,
isCloseButtonVisible: true, borderRadius: 10,
); padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
}); height: 40.h,
} else { ),
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context)); SizedBox(width: 8.h),
myInvoicesViewModel.downloadInvoicePDF( CustomButton(
setupId: myInvoicesVM.allInvoicesList[index].setupId!, text: LocaleKeys.doctors.tr(context: context),
invoiceNo: myInvoicesVM.allInvoicesList[index].invoiceNo!, onPressed: () {
projectID: myInvoicesVM.allInvoicesList[index].projectId!, if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
onError: (err) { _showDoctorFilterBottomSheet(context);
LoaderBottomSheet.hideLoader(); },
showCommonBottomSheetWithoutHeight( backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.bgRedLightColor : AppColors.whiteColor,
context, borderColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
child: Utils.getErrorWidget(loadingText: err), textColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.primaryRedColor : AppColors.blackColor,
callBackFunc: () {}, fontSize: 12,
isFullScreen: false, fontWeight: FontWeight.w600,
isCloseButtonVisible: true, borderRadius: 10,
); padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
}, height: 40.h,
onSuccess: (value) async { ),
LoaderBottomSheet.hideLoader(); ],
if (myInvoicesViewModel.downloadInvoicePDFBase64!.isNotEmpty) { ).paddingSymmetrical(24.h, 0.h),
String path = await Utils.createFileFromString(myInvoicesViewModel.downloadInvoicePDFBase64!, "pdf"); SizedBox(height: 16.h),
try { ListView.builder(
OpenFilex.open(path); itemCount: myInvoicesVM.isInvoicesListLoading
} catch (ex) { ? 4
: myInvoicesVM.allInvoicesList.isEmpty
? 1
: myInvoicesVM.allInvoicesList.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsetsGeometry.zero,
itemBuilder: (context, index) {
return myInvoicesVM.isInvoicesListLoading
? LabResultItemView(onTap: () {}, labOrder: null, index: index, isLoading: true)
: myInvoicesVM.allInvoicesList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: InvoiceListCard(
getInvoicesListResponseModel: myInvoicesVM.allInvoicesList[index],
onTap: () async {
if (Utils.isVidaPlusProject(myInvoicesVM.allInvoicesList[index].projectId ?? 0)) {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.sendingEmailPleaseWait.tr(context: context));
await myInvoicesViewModel.sendInvoiceEmail(
appointmentNo: myInvoicesVM.allInvoicesList[index].appointmentNo!,
projectID: myInvoicesVM.allInvoicesList[index].projectId!,
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(context,
child: Utils.getSuccessWidget(loadingText: LocaleKeys.emailSentSuccessfullyMessage.tr(context: context)),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
isAutoDismiss: true);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
} else {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context));
myInvoicesViewModel.downloadInvoicePDF(
setupId: myInvoicesVM.allInvoicesList[index].setupId!,
invoiceNo: myInvoicesVM.allInvoicesList[index].invoiceNo!,
projectID: myInvoicesVM.allInvoicesList[index].projectId!,
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: "Cannot open file"), child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
); );
} },
} onSuccess: (value) async {
}, LoaderBottomSheet.hideLoader();
); if (myInvoicesViewModel.downloadInvoicePDFBase64!.isNotEmpty) {
} String path = await Utils.createFileFromString(myInvoicesViewModel.downloadInvoicePDFBase64!, "pdf");
}, try {
// onTap: () async { OpenFilex.open(path);
// myInvoicesVM.setInvoiceDetailLoading(); } catch (ex) {
// LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingInvoiceDetails.tr(context: context)); showCommonBottomSheetWithoutHeight(
// await myInvoicesVM.getInvoiceDetails( context,
// appointmentNo: myInvoicesVM.allInvoicesList[index].appointmentNo!, child: Utils.getErrorWidget(loadingText: "Cannot open file"),
// invoiceNo: myInvoicesVM.allInvoicesList[index].invoiceNo!, callBackFunc: () {},
// projectID: myInvoicesVM.allInvoicesList[index].projectId!, isFullScreen: false,
// onSuccess: (val) { isCloseButtonVisible: true,
// LoaderBottomSheet.hideLoader(); );
// Navigator.of(context).push( }
// CustomPageRoute( }
// page: MyInvoicesDetailsPage( },
// getInvoiceDetailsResponseModel: myInvoicesVM.invoiceDetailsResponseModel, );
// getInvoicesListResponseModel: myInvoicesVM.allInvoicesList[index], }
// ), },
// ), // onTap: () async {
// ); // myInvoicesVM.setInvoiceDetailLoading();
// }, // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingInvoiceDetails.tr(context: context));
// onError: (err) { // await myInvoicesVM.getInvoiceDetails(
// LoaderBottomSheet.hideLoader(); // appointmentNo: myInvoicesVM.allInvoicesList[index].appointmentNo!,
// showCommonBottomSheetWithoutHeight( // invoiceNo: myInvoicesVM.allInvoicesList[index].invoiceNo!,
// context, // projectID: myInvoicesVM.allInvoicesList[index].projectId!,
// child: Utils.getErrorWidget(loadingText: err), // onSuccess: (val) {
// callBackFunc: () {}, // LoaderBottomSheet.hideLoader();
// isFullScreen: false, // Navigator.of(context).push(
// isCloseButtonVisible: true, // CustomPageRoute(
// ); // page: MyInvoicesDetailsPage(
// }); // getInvoiceDetailsResponseModel: myInvoicesVM.invoiceDetailsResponseModel,
// }, // getInvoicesListResponseModel: myInvoicesVM.allInvoicesList[index],
// ),
// ),
// );
// },
// onError: (err) {
// LoaderBottomSheet.hideLoader();
// showCommonBottomSheetWithoutHeight(
// context,
// child: Utils.getErrorWidget(loadingText: err),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
// });
// },
),
),
), ),
), ),
), )
), : Utils.getNoDataWidget(context);
) }).paddingSymmetrical(24.w, 0.h),
: Utils.getNoDataWidget(context); ],
}).paddingSymmetrical(24.w, 0.h), ) : Container(),
], ],
); );
}), }),

@ -150,6 +150,9 @@ class GenericBottomSheetState extends State<GenericBottomSheet> {
keyboardType: widget.isForEmail ? TextInputType.emailAddress : TextInputType.number, keyboardType: widget.isForEmail ? TextInputType.emailAddress : TextInputType.number,
onChange: (value) { onChange: (value) {
if (widget.onChange != null) { if (widget.onChange != null) {
if (Utils.isArabicText(value!)) {
value = Utils.toEnglishNumbers(value);
}
widget.onChange!(value); widget.onChange!(value);
} }
}, },

Loading…
Cancel
Save