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.
362 lines
15 KiB
Dart
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,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|