You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
car_provider_app/lib/views/dashboard/widget/general_appointment_widget....

362 lines
15 KiB
Dart

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<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) {
if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) {
return [const SizedBox()];
}
if (appointmentListModel.appointmentServicesList!.length == 1) {
List<Widget> 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.providerServiceDescription} - ${appointmentListModel.appointmentServicesList!.first.serviceId}",
MyAssets.modificationsIcon,
),
if (isNeedToShowItems) ...itemsList,
],
)
];
}
List<Widget> servicesList = List.generate(
isNeedToShowToMoreText ? 2 : appointmentListModel.appointmentServicesList?.length ?? 0,
(index) {
List<Widget> 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].providerServiceDescription} - ${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,
),
),
],
);
}
}