import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:easy_localization/easy_localization.dart'; class GeneralAppointmentWidget extends StatelessWidget { final AppointmentListModel appointmentListModel; final bool isNeedTotalPayment; final bool isNeedToShowItems; final bool isNeedToShowToMoreText; final bool isSelectable; final bool isFromUpdateAppointmentPage; final bool isNeedToShowAppointmentStatus; final bool isNeedToShowMergeStatus; final Function()? onTap; const GeneralAppointmentWidget({ required this.appointmentListModel, required this.onTap, this.isNeedTotalPayment = false, this.isNeedToShowItems = false, this.isNeedToShowToMoreText = true, this.isSelectable = false, this.isNeedToShowAppointmentStatus = false, this.isFromUpdateAppointmentPage = false, this.isNeedToShowMergeStatus = false, super.key, }); List buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) { if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) { return [const SizedBox()]; } if (appointmentListModel.appointmentServicesList!.length == 1) { List itemsList = []; if (isNeedToShowItems) { itemsList = List.generate( appointmentListModel.appointmentServicesList?.first.serviceItems?.length ?? 0, (mIndex) => showItems((appointmentListModel.appointmentServicesList?.first.serviceItems?[mIndex].name ?? "").toString(), MyAssets.modificationsIcon), ); } return [ Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ showServices( "${appointmentListModel.appointmentServicesList!.first.providerServiceName} ${appointmentListModel.appointmentServicesList!.first.serviceId != 0 ? '- ${appointmentListModel.appointmentServicesList!.first.serviceId}' : ""}", MyAssets.modificationsIcon, ), if (isNeedToShowItems) ...itemsList, ], ) ]; } List servicesList = List.generate( isNeedToShowToMoreText ? 2 : appointmentListModel.appointmentServicesList?.length ?? 0, (index) { List itemsList = []; if (isNeedToShowItems) { itemsList = List.generate( appointmentListModel.appointmentServicesList?[index].serviceItems?.length ?? 0, (mIndex) => showItems((appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? "").toString(), MyAssets.modificationsIcon), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ showServices( "${appointmentListModel.appointmentServicesList![index].providerServiceName} ${appointmentListModel.appointmentServicesList![index].serviceId != 0 ? '- ${appointmentListModel.appointmentServicesList![index].serviceId}' : ""}", MyAssets.modificationsIcon, ), if (isNeedToShowItems) ...itemsList, ], ).paddingOnly(bottom: 6); }, ); if (isNeedToShowToMoreText && appointmentListModel.appointmentServicesList!.length > 2) { servicesList.add( showServices( "+ ${appointmentListModel.appointmentServicesList!.length - 2} More", "", isMoreText: true, ), ); } return servicesList; } @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ if (isSelectable) SizedBox( child: const SizedBox( width: 14, height: 14, ).toContainer( borderRadius: 24, marginAll: 4, paddingAll: 0, backgroundColor: (appointmentListModel.isSelected ?? false) ? MyColors.primaryColor : MyColors.greyButtonColor, ), ).toContainer( borderRadius: 24, isEnabledBorder: true, paddingAll: 0, borderWidget: 3, borderColor: MyColors.primaryColor, ), if (isSelectable) 12.width, Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ if (isNeedToShowMergeStatus) LocaleKeys.merged.tr().toText(color: MyColors.white).toContainer( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), borderRadius: 12, backgroundColor: MyColors.greenColor, ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ (appointmentListModel.branchName ?? "").toText( fontSize: 12, color: MyColors.darkTextColor, isBold: true, ), (appointmentListModel.customerName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16), Row( children: [ "${LocaleKeys.phone.tr()}:".toText( color: MyColors.lightTextColor, ), 2.width, appointmentListModel.customerMobileNum.toString().toText( fontSize: 12, ), ], ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ "${LocaleKeys.time.tr()}:".toText( color: MyColors.lightTextColor, ), 4.width, Flexible(child: (appointmentListModel.duration ?? "").toText(fontSize: 8)) ], ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ "${LocaleKeys.date.tr()}:".toText( color: MyColors.lightTextColor, ), 4.width, Flexible(child: appointmentListModel.appointmentDate!.toFormattedDateWithoutTime().toText(fontSize: 8)) ], ), Row( children: [ "${LocaleKeys.serviceDeliveryType.tr()}: ".toText(color: MyColors.lightTextColor), 2.width, (appointmentListModel.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText( fontSize: 12, ), ], ), Row( children: [ "${LocaleKeys.createdOn.tr()}: ".toText(color: MyColors.lightTextColor), 2.width, Flexible(child: appointmentListModel.appointmentCreatedOn!.toFormattedDateWithoutTime().toText(fontSize: 8)) ], ), if (isFromUpdateAppointmentPage) ...[ if (appointmentListModel.appointmentAddress != null && appointmentListModel.appointmentAddress!.isNotEmpty) ...[ Row( children: [ "${LocaleKeys.address.tr()}: ".toText(color: MyColors.lightTextColor), 2.width, Flexible(child: (appointmentListModel.appointmentAddress ?? "").toText(fontSize: 8)) ], ), ], Row( children: [ "${LocaleKeys.paymentType.tr()}: ".toText(color: MyColors.lightTextColor), 2.width, (appointmentListModel.paymentType ?? "").toText(fontSize: 8), ], ), LocaleKeys.openMapLocation .tr() .toText( isUnderLine: true, color: MyColors.darkPrimaryColor, fontSize: 10, ) .onPress(() async { double latitude, longitude = 0.0; latitude = double.parse(appointmentListModel.appointmentLatitude!); longitude = double.parse(appointmentListModel.appointmentLongitude!); await Utils.openLocationInMaps(latitude: latitude, longitude: longitude); }), ] ], ), ), if (!isNeedTotalPayment) if (appointmentListModel.customerAppointmentList != null && appointmentListModel.customerAppointmentList!.length > 1) "${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments".toText(fontSize: 8).toContainer( borderRadius: 15, backgroundColor: MyColors.lightGreyEAColor, padding: const EdgeInsets.symmetric( vertical: 6, horizontal: 12, ), ), if (isNeedToShowAppointmentStatus) (appointmentListModel.appointmentStatusEnum!.getAppointmentNameFromEnum()).toText(color: MyColors.white).toContainer( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), borderRadius: 12, backgroundColor: MyColors.primaryColor, ), ], ), 8.height, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Column( children: [ ...buildServicesFromAppointment(appointmentListModel: appointmentListModel), if (isNeedTotalPayment) Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 18.height, LocaleKeys.totalAmount.tr().toText( fontSize: 12, color: MyColors.lightTextColor, ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ appointmentListModel.totalAmount.toString().toText(fontSize: 16, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor), ], ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 2.height, LocaleKeys.remainingAmount.tr().toText( fontSize: 12, color: MyColors.lightTextColor, ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ appointmentListModel.remainingAmount.toString().toText(fontSize: 16, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor), ], ), ], ), ], ) ], ), ), if (!isNeedToShowItems) const Icon(Icons.arrow_forward), ], ), ], ), ) ], ).toWhiteContainer(width: double.infinity, allPading: 12, onTap: onTap); } double calculateTotalPrice() { double totalServiceListPrice = 0; for (var servicesElement in appointmentListModel.appointmentServicesList!) { for (var itemsElement in servicesElement.serviceItems!) { totalServiceListPrice += double.parse(itemsElement.price ?? "0"); } } return totalServiceListPrice; } Widget showServices(String title, String icon, {bool isMoreText = false}) { return Row( children: [ if (icon != "") ...[ SvgPicture.asset(icon), 8.width, ], Flexible( child: title.toText( fontSize: 12, isBold: true, color: isMoreText ? MyColors.primaryColor : MyColors.black, ), ), ], ); } Widget showItems(String title, String icon) { return Row( children: [ SvgPicture.asset( icon, color: Colors.transparent, ), 8.width, Flexible( child: title.toText( fontSize: 10, color: MyColors.lightTextColor, ), ), ], ); } }