import 'dart:developer'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/app_state.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/service_schedule_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_contact_info_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/service_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/view_models/appointments_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; class ReviewAppointment extends StatelessWidget { const ReviewAppointment({super.key}); Widget showItem(String title, String value) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ "$title: ".toText(color: MyColors.lightTextColor, letterSpacing: -0.48), 3.width, Flexible(child: value.toText(isBold: true, overflow: TextOverflow.ellipsis)), ], ); } Widget buildPersonalInformationCard({required BuildContext context}) { return Padding( padding: const EdgeInsets.only( bottom: 0, left: 21, right: 21, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ (LocaleKeys.personalInformation.tr()).toText(fontSize: 16, isBold: true), showItem(LocaleKeys.name.tr(), "${AppState().getUser.data!.userInfo!.firstName ?? ""} ${AppState().getUser.data!.userInfo!.lastName ?? ""}"), showItem(LocaleKeys.phoneNumber.tr(), AppState().getUser.data!.userInfo!.mobileNo ?? ""), showItem(LocaleKeys.email.tr(), AppState().getUser.data!.userInfo!.email ?? ""), ], ).toWhiteContainer(width: double.infinity, allPading: 12), ); } Widget buildBranchInfoCard({required BuildContext context}) { AppointmentsVM appointmentsVM = context.read(); return Padding( padding: const EdgeInsets.only( bottom: 0, left: 21, right: 21, ), child: Row( children: [ appointmentsVM.selectedBranchModel!.branchProfileImage.buildNetworkImage( width: 80, height: 60, fit: BoxFit.cover, ), 12.width, Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ (appointmentsVM.selectedBranchModel!.branchName ?? "").toText(fontSize: 16, isBold: true), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Flexible( child: (appointmentsVM.selectedBranchModel!.branchDescription ?? "").toText(fontSize: 12, color: MyColors.lightTextColor), ), ], ), if ((appointmentsVM.selectedBranchModel!.latitude != null && appointmentsVM.selectedBranchModel!.latitude!.isNotEmpty) && (appointmentsVM.selectedBranchModel!.longitude != null && appointmentsVM.selectedBranchModel!.longitude!.isNotEmpty)) ...[ Row( children: [ LocaleKeys.openMapLocation.tr().toText( fontSize: 12, isBold: true, color: MyColors.primaryColor, isUnderLine: true, ), 4.width, Image.asset( MyAssets.icRightUpPng, height: 6, width: 6, color: MyColors.primaryColor, ), ], ).onPress(() async { double latitude, longitude = 0.0; latitude = double.parse(appointmentsVM.selectedBranchModel!.latitude!); longitude = double.parse(appointmentsVM.selectedBranchModel!.longitude!); await Utils.openLocationInMaps(latitude: latitude, longitude: longitude); }), ] else ...[ const SizedBox(), ], ], ), ), if (appointmentsVM.selectedBranchModel!.branchRateAvg != null && appointmentsVM.selectedBranchModel!.branchRateAvg != 0.0) ...[ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ "${appointmentsVM.selectedBranchModel!.branchRateAvg}".toText( isUnderLine: true, isBold: true, fontSize: 12, ), 2.width, MyAssets.starIcon.buildSvg(width: 12), ], ), ] ], ), ], ), ), ], ).toWhiteContainer(width: double.infinity, allPading: 12)); } Widget buildServicesInfoCard({required BuildContext context}) { AppointmentsVM appointmentsVM = context.read(); return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: appointmentsVM.serviceAppointmentScheduleList.length, itemBuilder: (BuildContext context, int scheduleIndex) { ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex]; return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: LocaleKeys.services.tr().toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: scheduleData.servicesListInAppointment!.length, itemBuilder: (BuildContext context, int serviceIndex) { String selectedTimeSlot = ""; if (scheduleData.selectedCustomTimeDateSlotModel!.availableSlots != null) { selectedTimeSlot = scheduleData.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected).slot; } return Column( children: [ if (scheduleData.servicesListInAppointment!.isNotEmpty) ...[ Column( children: List.generate(scheduleData.servicesListInAppointment!.length, (serviceIndex) { ServiceModel serviceData = scheduleData.servicesListInAppointment![serviceIndex]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "${serviceData.providerServiceDescription}".toText(fontSize: 16, isBold: true), if (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ "${LocaleKeys.chargesPerKM.tr()}: ${serviceData.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)} ${LocaleKeys.sar.tr()}/km".toText( fontSize: 12, color: MyColors.lightTextColor, ), ], ], ), Column( children: List.generate(serviceData.serviceItems!.length, (itemIndex) { ItemData itemData = serviceData.serviceItems![itemIndex]; return Column( children: [ // Item Name and Price Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ ("${itemData.name}: ${itemData.price} ${LocaleKeys.sar.tr()}").toText(fontSize: 13, color: MyColors.lightTextColor), ], ), //Description // Row( // crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.start, // children: [ // ("${itemData.description}").toText(fontSize: 11, color: MyColors.lightTextColor), // ], // ), ], ); }), ).paddingOnly(bottom: 10), ], ); }), ).paddingOnly(bottom: 10), ], 5.height, SizedBox( width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.timeLocation.tr().toText(fontSize: 16, isBold: true), 3.height, Row(children: [ "${LocaleKeys.dateAndTime.tr()}: ".toText(fontSize: 12, color: MyColors.lightTextColor), "${scheduleData.selectedCustomTimeDateSlotModel!.date!.date} at $selectedTimeSlot".toText(fontSize: 12), ]), Row( children: [ ("${LocaleKeys.location.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.homeLocation.tr() : LocaleKeys.companyLocation.tr()).toText(fontSize: 12), if (appointmentsVM.currentLocationInfoModel != null && scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ " , ${appointmentsVM.currentLocationInfoModel!.distanceToBranch.toStringAsFixed(2)} KM".toText(fontSize: 12), ], ], ), if (appointmentsVM.currentLocationInfoModel != null && scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ("${LocaleKeys.address.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), Flexible(child: appointmentsVM.currentLocationInfoModel!.address.toText(fontSize: 12)), ], ), ], ], ), ), 10.height, const Divider(thickness: 0.7), Builder(builder: (BuildContext context) { double totalServicePrice = scheduleData.totalLocationCharges ?? 0.0; double totalKms = scheduleData.locationInfoModel!.distanceToBranch; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.amountVAR.tr().toText(fontSize: 16, isBold: true), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.serviceCharges.tr().toText(fontSize: 14, color: MyColors.lightTextColor), "${scheduleData.amountTotal.toString()} ${LocaleKeys.sar.tr()}".toText(fontSize: 16, isBold: true), ], ), if (scheduleData.appointmentTypeEnum == AppointmentTypeEnum.home) ...[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible(child: ("${LocaleKeys.locationCharges.tr()} (${totalKms.toStringAsFixed(2)}km away)").toText(fontSize: 14, color: MyColors.lightTextColor)), ("${totalServicePrice.toStringAsFixed(2)} ${LocaleKeys.sar.tr()}").toText(fontSize: 16, isBold: true), ], ), ], 10.height, ], ); }), ], ); }, separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 2), ).paddingOnly(bottom: 10), ], ), ], ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.fromLTRB(21, 0, 21, 12)); }, ); } Widget buildNextButtonFooter({required BuildContext context}) { AppointmentsVM appointmentsVM = context.read(); return Container( color: MyColors.white, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Divider(thickness: 0.8, height: 2), 8.height, if (appointmentsVM.amountToPayForAppointment > 0) ...[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.payableNow.tr().toText(fontSize: 14), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ appointmentsVM.amountToPayForAppointment.toString().toText(fontSize: 16, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 12, isBold: true).paddingOnly(bottom: 2), ], ) ], ).paddingOnly(left: 21, right: 21), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.remainingAmount.tr().toText(fontSize: 14), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ (appointmentsVM.totalAmount - appointmentsVM.amountToPayForAppointment).toStringAsFixed(2).toText(fontSize: 16, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 12, isBold: true).paddingOnly(bottom: 2), ], ) ], ).paddingOnly(left: 21, right: 21), ], Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.totalAmount.tr().toText(fontSize: 18, isBold: true), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ appointmentsVM.totalAmount.toStringAsFixed(2).toText(fontSize: 29, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), ], ) ], ).paddingOnly(left: 21, right: 21), 5.height, SizedBox( width: double.infinity, child: ShowFillButton( maxHeight: 55, backgroundColor: MyColors.darkPrimaryColor, title: LocaleKeys.bookAppointment.tr(), onPressed: () { appointmentsVM.onBookAppointmentPressed(context); }, ).paddingOnly(bottom: 12, left: 21, right: 21), ), ], ), ); } @override Widget build(BuildContext context) { log("state: ${AppState().getUser.data!.userInfo!.customerId}"); return Scaffold( appBar: CustomAppBar( title: LocaleKeys.reviewAppointment.tr(), isRemoveBackButton: false, isDrawerEnabled: false, onBackButtonTapped: () => Navigator.pop(context), actions: [ IconButton( onPressed: () async { final appointmentsVM = context.read(); ProviderContactInfoModel? contact = await appointmentsVM.getProvidersContactInfo(providerId: appointmentsVM.selectedBranchModel!.serviceProviderId ?? 0, context: context); if (contact != null) { Utils.buildProviderContactInfoBottomSheet(context: context, email: contact.email, mobileNo: contact.mobile); } }, icon: const Icon(Icons.help_outline_outlined).paddingOnly(right: 21), ), ], ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ListView( children: [ 10.height, buildBranchInfoCard(context: context), 10.height, buildServicesInfoCard(context: context), 10.height, buildPersonalInformationCard(context: context), 20.height, ], ).expand(), buildNextButtonFooter(context: context), ], ), ); } }