From d93947152a46f88370fa91c9fc71f71f18f7aa14 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Tue, 12 Sep 2023 16:45:31 +0300 Subject: [PATCH] Ad Details Page Checls --- lib/classes/consts.dart | 2 + lib/config/routes.dart | 12 +- lib/extensions/string_extensions.dart | 32 +- .../advertisment_models/ad_details_model.dart | 13 +- lib/packages/cutom_country_code_picker.dart | 302 ++++++ lib/repositories/ads_repo.dart | 25 +- lib/utils/enums.dart | 14 +- lib/view_models/ad_view_model.dart | 136 ++- .../ad_duration_container.dart | 259 +++-- .../ad_review_containers.dart | 283 ++--- .../damage_parts_container.dart | 8 +- .../vehicle_details_container.dart | 55 +- .../ad_duration_selection_sheet_content.dart | 46 +- lib/views/advertisement/ads_detail_view.dart | 474 ++++++++- lib/views/advertisement/ads_list.dart | 16 +- .../advertisement/ads_search_filter_view.dart | 19 + .../advertisement/bottom_sheet_content.dart | 155 +-- .../create_ad_progress_steps.dart | 29 +- .../advertisement/custom_add_button.dart | 8 +- .../advertisement/select_ad_type_view.dart | 23 +- lib/widgets/txt_field.dart | 13 +- pubspec.lock | 975 ------------------ pubspec.yaml | 1 + 23 files changed, 1510 insertions(+), 1390 deletions(-) create mode 100644 lib/packages/cutom_country_code_picker.dart create mode 100644 lib/views/advertisement/ads_search_filter_view.dart delete mode 100644 pubspec.lock diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 039f461..8a063a9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -77,6 +77,7 @@ class ApiConsts { //Advertisement APIs static String vehicleTypeGet = "${baseUrlServices}api/ServiceProviders/VehicleType_Get"; static String vehicleModelGet = "${baseUrlServices}api/Master/VehicleModel_Get"; + static String vehicleBrandGet = "${baseUrlServices}api/Master/VehicleBrand_Get"; static String vehicleModelYearGet = "${baseUrlServices}api/Master/VehicleModelYear_Get"; static String vehicleColorGet = "${baseUrlServices}api/Master/VehicleColor_Get"; static String vehicleConditionGet = "${baseUrlServices}api/Master/VehicleCondition_Get"; @@ -125,6 +126,7 @@ class GlobalConsts { static String attachImageError = "You must add at least 3 images"; static String attachDamagePartImage = "Please add part image"; static String adDurationDateError = "Ad Duration start date cannot be empty"; + static String adDurationPhoneNumberError = "Phone number cannot be empty"; static String adReservablePriceErrorConst = "Ad Reservable price cannot be empty"; static String homeLocationEmptyError = "Home location cannot be empty"; static String reserveAdPriceInfo = diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 86e5b5f..c852ecc 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -25,7 +25,7 @@ class AppRoutes { static const String registerSelection = "/registerSelection"; static const String loginVerifyAccount = "/loginVerifyAccount"; static const String registerCustomer = "/registerCustomer"; - static const String registerProvider= "/registerProvider"; + static const String registerProvider = "/registerProvider"; static const String forgetPassword = "/forgetPassword"; static const String loginVerification = "/loginVerification"; static const String loginWithPassword = "/loginWithPassword"; @@ -45,13 +45,15 @@ class AppRoutes { static const String dashboard = "/dashboard"; static const String bookProviderAppView = "/bookProviderAppView"; static const String appointmentDetailView = "/appointmentDetailView"; - static const String selectAdTypeView = "/selectAdTypeView"; - static const String adsDetailView = "/adsDetailView"; - static const String createAdView = "/createAdView"; static const String bookAppointmenServicesView = "/bookAppointmenServicesView"; static const String bookAppointmentsItemView = "/bookAppointmentsItemView"; static const String reviewAppointmentView = "/reviewAppointmentView"; + //Advertisement + static const String selectAdTypeView = "/selectAdTypeView"; + static const String adsDetailView = "/adsDetailView"; + static const String createAdView = "/createAdView"; + static const String adsSearchFilterScreen = "/adsSearchFilterScreen"; // Payments static const String paymentMethodsView = "/paymentMethodsView"; @@ -60,7 +62,6 @@ class AppRoutes { static const String branchDetailPage = "/branchDetailPage"; static const String providerProfilePage = "/providerProfilePage"; - // Subscriptions static const String mySubscriptionsPage = "/mySubscriptionsPage"; static const String subscriptionsPage = "/subscriptionsPage"; @@ -86,6 +87,5 @@ class AppRoutes { changeMobilePage: (context) => ChangeMobilePage(), changeEmailPage: (context) => const ChangeEmailPage(), editAccountPage: (context) => const EditAccountPage(), - }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 7bbd3c8..02a0905 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -15,6 +15,7 @@ extension EmailValidator on String { TextDecoration? textDecoration, double letterSpacing = -0.4, TextAlign? textAlign, + FontWeight? fontWeight, double? height, int? maxLines}) => AutoSizeText( @@ -26,7 +27,7 @@ extension EmailValidator on String { height: height, decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none, fontSize: fontSize ?? 10, - fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: letterSpacing, ), @@ -181,6 +182,35 @@ extension AdPostEnum on int { } } +extension AdReserveStatusEnum on int { + AdReserveStatus toAdRserveStatusEnum() { + if (this == 0) { + return AdReserveStatus.defaultStatus; + } else if (this == 1) { + return AdReserveStatus.reserved; + } else if (this == 2) { + return AdReserveStatus.cancelledByOwner; + } else if (this == 3) { + return AdReserveStatus.cancelledByAdmin; + } else { + return AdReserveStatus.defaultStatus; + } + } +} + +extension AdOwnerEnum on int { + AdOwner toAdOwnerEnum() { + if (this == 0) { + return AdOwner.customer; + } else if (this == 1) { + return AdOwner.provider; + } else if (this == 2) { + return AdOwner.mowater; + } + return AdOwner.customer; + } +} + extension BranchsEnum on int { BranchStatusEnum toBranchStatusEnum() { if (this == 1) { diff --git a/lib/models/advertisment_models/ad_details_model.dart b/lib/models/advertisment_models/ad_details_model.dart index d27b578..c14f6e2 100644 --- a/lib/models/advertisment_models/ad_details_model.dart +++ b/lib/models/advertisment_models/ad_details_model.dart @@ -36,6 +36,9 @@ class AdDetailsModel { bool? isMCHandled; String? modifiedOn; AdPostStatus? adPostStatus; + AdReserveStatus? adReserveStatus; + bool? isMyAd; + AdOwner? adOwnerEnum; AdDetailsModel( {this.id, @@ -69,9 +72,12 @@ class AdDetailsModel { this.reservePrice, this.isMCHandled, this.adPostStatus, + this.adReserveStatus, + this.isMyAd, + this.adOwnerEnum, this.modifiedOn}); - AdDetailsModel.fromJson(Map json) { + AdDetailsModel.fromJson(Map json, bool isMyAds) { id = json['id']; startdate = json['startdate']; enddate = json['enddate']; @@ -114,6 +120,11 @@ class AdDetailsModel { isMCHandled = json['isMCHandled']; modifiedOn = json['modifiedOn']; adPostStatus = (json['statusID'] as int).toAdPostEnum(); + //TODO: THIS ID SHOULD BE UPDATED! + adReserveStatus = AdReserveStatus.defaultStatus; + // adReserveStatus = (json['adReserveStatusID'] as int).toAdRserveStatusEnum(); + adOwnerEnum = (json['statusID'] as int).toAdOwnerEnum(); + isMyAd = isMyAds; } Map toJson() { diff --git a/lib/packages/cutom_country_code_picker.dart b/lib/packages/cutom_country_code_picker.dart new file mode 100644 index 0000000..3e1aa11 --- /dev/null +++ b/lib/packages/cutom_country_code_picker.dart @@ -0,0 +1,302 @@ +import 'package:collection/collection.dart' show IterableExtension; +import 'package:country_code_picker/country_code_picker.dart'; +import 'package:flutter/material.dart'; + +class CustomCountryCodePicker extends StatefulWidget { + final bool isTextNeeded; + final ValueChanged? onChanged; + final ValueChanged? onInit; + final String? initialSelection; + final List favorite; + final TextStyle? textStyle; + final EdgeInsetsGeometry padding; + final bool showCountryOnly; + final InputDecoration searchDecoration; + final TextStyle? searchStyle; + final TextStyle? dialogTextStyle; + final WidgetBuilder? emptySearchBuilder; + final Function(CountryCode?)? builder; + final bool enabled; + final TextOverflow textOverflow; + final Icon closeIcon; + + /// Barrier color of ModalBottomSheet + final Color? barrierColor; + + /// Background color of ModalBottomSheet + final Color? backgroundColor; + + /// BoxDecoration for dialog + final BoxDecoration? boxDecoration; + + /// the size of the selection dialog + final Size? dialogSize; + + /// Background color of selection dialog + final Color? dialogBackgroundColor; + + /// used to customize the country list + final List? countryFilter; + + /// shows the name of the country instead of the dialcode + final bool showOnlyCountryWhenClosed; + + /// aligns the flag and the Text left + /// + /// additionally this option also fills the available space of the widget. + /// this is especially useful in combination with [showOnlyCountryWhenClosed], + /// because longer country names are displayed in one line + final bool alignLeft; + + /// shows the flag + final bool showFlag; + + final bool hideMainText; + + final bool? showFlagMain; + + final bool? showFlagDialog; + + /// Width of the flag images + final double flagWidth; + + /// Use this property to change the order of the options + final Comparator? comparator; + + /// Set to true if you want to hide the search part + final bool hideSearch; + + /// Set to true if you want to show drop down button + final bool showDropDownButton; + + /// [BoxDecoration] for the flag image + final Decoration? flagDecoration; + + /// An optional argument for injecting a list of countries + /// with customized codes. + final List> countryList; + + const CustomCountryCodePicker({ + this.isTextNeeded = true, + this.onChanged, + this.onInit, + this.initialSelection, + this.favorite = const [], + this.textStyle, + this.padding = const EdgeInsets.all(8.0), + this.showCountryOnly = false, + this.searchDecoration = const InputDecoration(), + this.searchStyle, + this.dialogTextStyle, + this.emptySearchBuilder, + this.showOnlyCountryWhenClosed = false, + this.alignLeft = false, + this.showFlag = true, + this.showFlagDialog, + this.hideMainText = false, + this.showFlagMain, + this.flagDecoration, + this.builder, + this.flagWidth = 32.0, + this.enabled = true, + this.textOverflow = TextOverflow.ellipsis, + this.barrierColor, + this.backgroundColor, + this.boxDecoration, + this.comparator, + this.countryFilter, + this.hideSearch = false, + this.showDropDownButton = false, + this.dialogSize, + this.dialogBackgroundColor, + this.closeIcon = const Icon(Icons.close), + this.countryList = codes, + Key? key, + }) : super(key: key); + + @override + // ignore: no_logic_in_create_state + State createState() { + List> jsonList = countryList; + + List elements = jsonList.map((json) => CountryCode.fromJson(json)).toList(); + + if (comparator != null) { + elements.sort(comparator); + } + + if (countryFilter != null && countryFilter!.isNotEmpty) { + final uppercaseCustomList = countryFilter!.map((criteria) => criteria.toUpperCase()).toList(); + elements = elements.where((criteria) => uppercaseCustomList.contains(criteria.code) || uppercaseCustomList.contains(criteria.name) || uppercaseCustomList.contains(criteria.dialCode)).toList(); + } + + return CustomCountryCodePickerState(elements); + } +} + +class CustomCountryCodePickerState extends State { + CountryCode? selectedItem; + List elements = []; + List favoriteElements = []; + + CustomCountryCodePickerState(this.elements); + + @override + Widget build(BuildContext context) { + Widget internalWidget; + if (widget.builder != null) { + internalWidget = InkWell( + onTap: showCountryCodePickerDialog, + child: widget.builder!(selectedItem), + ); + } else { + internalWidget = TextButton( + onPressed: widget.enabled ? showCountryCodePickerDialog : null, + child: Padding( + padding: widget.padding, + child: Flex( + direction: Axis.horizontal, + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.showFlagMain != null ? widget.showFlagMain! : widget.showFlag) + Flexible( + flex: widget.alignLeft ? 0 : 1, + fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, + child: Container( + clipBehavior: widget.flagDecoration == null ? Clip.none : Clip.hardEdge, + decoration: widget.flagDecoration, + margin: widget.alignLeft ? const EdgeInsets.only(right: 16.0, left: 8.0) : const EdgeInsets.only(right: 16.0), + child: Image.asset( + selectedItem!.flagUri!, + package: 'country_code_picker', + width: widget.flagWidth, + ), + ), + ), + if (!widget.hideMainText) + Flexible( + fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, + child: Text( + widget.showOnlyCountryWhenClosed ? selectedItem!.toCountryStringOnly() : selectedItem.toString(), + style: widget.textStyle ?? Theme.of(context).textTheme.labelLarge, + overflow: widget.textOverflow, + ), + ), + if (widget.showDropDownButton) + Flexible( + flex: widget.alignLeft ? 0 : 1, + fit: widget.alignLeft ? FlexFit.tight : FlexFit.loose, + child: Padding( + padding: widget.alignLeft ? const EdgeInsets.only(right: 16.0, left: 8.0) : const EdgeInsets.only(right: 16.0), + child: Icon( + Icons.arrow_drop_down, + color: Colors.grey, + size: widget.flagWidth, + )), + ), + ], + ), + ), + ); + } + return internalWidget; + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + + elements = elements.map((element) => element.localize(context)).toList(); + _onInit(selectedItem); + } + + @override + void didUpdateWidget(CustomCountryCodePicker oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.initialSelection != widget.initialSelection) { + if (widget.initialSelection != null) { + selectedItem = elements.firstWhere( + (criteria) => + (criteria.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (criteria.dialCode == widget.initialSelection) || + (criteria.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), + orElse: () => elements[0]); + } else { + selectedItem = elements[0]; + } + _onInit(selectedItem); + } + } + + @override + void initState() { + super.initState(); + + if (widget.initialSelection != null) { + selectedItem = elements.firstWhere( + (item) => + (item.code!.toUpperCase() == widget.initialSelection!.toUpperCase()) || + (item.dialCode == widget.initialSelection) || + (item.name!.toUpperCase() == widget.initialSelection!.toUpperCase()), + orElse: () => elements[0]); + } else { + selectedItem = elements[0]; + } + + favoriteElements = elements + .where((item) => + widget.favorite.firstWhereOrNull((criteria) => item.code!.toUpperCase() == criteria.toUpperCase() || item.dialCode == criteria || item.name!.toUpperCase() == criteria.toUpperCase()) != + null) + .toList(); + } + + void showCountryCodePickerDialog() async { + final item = await showDialog( + barrierColor: widget.barrierColor ?? Colors.grey.withOpacity(0.5), + context: context, + builder: (context) => Center( + child: Dialog( + child: SelectionDialog( + elements, + favoriteElements, + showCountryOnly: widget.showCountryOnly, + emptySearchBuilder: widget.emptySearchBuilder, + searchDecoration: widget.searchDecoration, + searchStyle: widget.searchStyle, + textStyle: widget.dialogTextStyle, + boxDecoration: widget.boxDecoration, + showFlag: widget.showFlagDialog ?? widget.showFlag, + flagWidth: widget.flagWidth, + size: widget.dialogSize, + backgroundColor: widget.dialogBackgroundColor, + barrierColor: widget.barrierColor, + hideSearch: widget.hideSearch, + closeIcon: widget.closeIcon, + flagDecoration: widget.flagDecoration, + ), + ), + ), + ); + + if (item != null) { + setState(() { + selectedItem = item; + }); + + _publishSelection(item); + } + } + + void _publishSelection(CountryCode countryCode) { + if (widget.onChanged != null) { + widget.onChanged!(countryCode); + } + } + + void _onInit(CountryCode? countryCode) { + if (widget.onInit != null) { + widget.onInit!(countryCode); + } + } +} diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 50bdb57..df78709 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -13,6 +13,8 @@ import 'package:mc_common_app/models/generic_resp_model.dart'; abstract class AdsRepo { Future> getVehicleTypes(); + Future> getVehicleBrands({required int vehicleTypeId}); + Future> getVehicleModels({required int vehicleTypeId}); Future> getVehicleModelYears({required int vehicleTypeId}); @@ -35,7 +37,7 @@ abstract class AdsRepo { Future> getVehicleDamageParts(); - Future getVehicleDetails({required int vehicleTypeId}); + Future getVehicleDetails({required int vehicleTypeId, required int vehicleBrandId}); Future> getAdsDuration(); @@ -147,6 +149,17 @@ class AdsRepoImp implements AdsRepo { return vehicleModels; } + @override + Future> getVehicleBrands({required int vehicleTypeId}) async { + var postParams = { + "VehicleType": vehicleTypeId.toString(), + }; + GenericRespModel adsGenericModel = + await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleBrandGet, queryParameters: postParams); + List vehicleBrands = List.generate(adsGenericModel.data.length, (index) => VehicleBrandsModel.fromJson(adsGenericModel.data[index])); + return vehicleBrands; + } + @override Future> getVehicleSellerTypes({required int vehicleTypeId}) async { var postParams = { @@ -170,11 +183,11 @@ class AdsRepoImp implements AdsRepo { } @override - Future getVehicleDetails({required int vehicleTypeId}) async { + Future getVehicleDetails({required int vehicleTypeId, required int vehicleBrandId}) async { var postParams = { "vehicleType": vehicleTypeId.toString(), "isVehicleBrand": "true", - "vehicleBrand": "0", + "vehicleBrand": vehicleBrandId.toString(), "isVehicleCategory": "true", "isVehicleColor": "true", "isVehicleCondition": "true", @@ -302,7 +315,7 @@ class AdsRepoImp implements AdsRepo { postParams, token: token, ); - log ("value: ${adsGenericModel}"); + log("value: ${adsGenericModel}"); return Future.value(adsGenericModel); } @@ -319,7 +332,7 @@ class AdsRepoImp implements AdsRepo { ApiConsts.vehicleAdsGet, queryParameters: isMyAds ? params : null, ); - List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index])); + List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], isMyAds)); return vehicleAdsDetails; } @@ -334,7 +347,7 @@ class AdsRepoImp implements AdsRepo { queryParameters: params, ApiConsts.vehicleAdsGet, ); - List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index])); + List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], true)); return vehicleAdsDetails; } } diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 4b2e27c..0cc7d6f 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -5,7 +5,6 @@ // unverified, // } - enum VehicleTypeEnum { car, motorCycle, @@ -13,6 +12,19 @@ enum VehicleTypeEnum { buggy, } +enum AdReserveStatus { + defaultStatus, + reserved, + cancelledByOwner, + cancelledByAdmin, +} + +enum AdOwner { + customer, + provider, + mowater, +} + enum AdPostStatus { pendingForReview, pendingForPayment, diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index ac49f95..e7cc19c 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -37,6 +37,7 @@ class AdVM extends BaseVM { VehicleDetailsModel? vehicleDetails; List vehicleTypes = []; + List vehicleBrands = []; List vehicleModels = []; List vehicleModelYears = []; List vehicleColors = []; @@ -64,6 +65,7 @@ class AdVM extends BaseVM { String adStartDateError = ""; String damagePartSearchValue = ""; String adReservePriceError = ""; + String adPhoneNumberError = ""; List exploreAds = []; List exploreAdsFilteredList = []; @@ -163,9 +165,9 @@ class AdVM extends BaseVM { FilterListModel(title: "Active", isSelected: false, id: 6), FilterListModel(title: "Pending For Review", isSelected: false, id: 1), FilterListModel(title: "Pending For Payment", isSelected: false, id: 2), + FilterListModel(title: "Reserved", isSelected: false, id: 9), FilterListModel(title: "Rejected", isSelected: false, id: 3), FilterListModel(title: "Pending For Post", isSelected: false, id: 5), - FilterListModel(title: "Reserved", isSelected: false, id: 9), ]; notifyListeners(); } @@ -236,31 +238,39 @@ class AdVM extends BaseVM { bool isFetchingLists = false; bool isCountryFetching = false; - Future getAllDataBasedOnVehicleTypeId() async { + // Future getAllDataBasedOnVehicleTypeId() async { + // if (vehicleTypeId.selectedId == -1) { + // return; + // } + // isFetchingLists = true; + // notifyListeners(); + // vehicleModels = await adsRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleColors = await adsRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleConditions = await adsRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleCategories = await adsRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleMileages = await adsRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleTransmissions = await adsRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId); + // vehicleCountries = await adsRepo.getVehicleCountries(); + // isFetchingLists = false; + // notifyListeners(); + // } + + getVehicleBrandsByVehicleTypeId() async { if (vehicleTypeId.selectedId == -1) { return; } - isFetchingLists = true; - notifyListeners(); - vehicleModels = await adsRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId); - vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId); - vehicleColors = await adsRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId); - vehicleConditions = await adsRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId); - vehicleCategories = await adsRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId); - vehicleMileages = await adsRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId); - vehicleTransmissions = await adsRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId); - vehicleCountries = await adsRepo.getVehicleCountries(); - isFetchingLists = false; + vehicleBrands = await adsRepo.getVehicleBrands(vehicleTypeId: vehicleTypeId.selectedId); notifyListeners(); } - Future getVehicleDetailsByVehicleId() async { - if (vehicleTypeId.selectedId == -1) { + Future getVehicleDetailsByVehicleBrandId() async { + if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) { return; } isFetchingLists = true; notifyListeners(); - vehicleDetails = await adsRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId); + vehicleDetails = await adsRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId, vehicleBrandId: vehicleBrandId.selectedId); if (vehicleDetails != null) { vehicleModels = vehicleDetails!.vehicleModels!; @@ -285,6 +295,21 @@ class AdVM extends BaseVM { notifyListeners(); } + String adPhoneNumber = ""; + + void updateAdPhoneNumber(String date) { + adPhoneNumber = date; + if (adPhoneNumber.isNotEmpty) adPhoneNumberError = ""; + notifyListeners(); + } + + String adPhoneNumberDialCode = "+966"; + + void updateAdPhoneNumberDialCode(String date) { + adPhoneNumberDialCode = date; + notifyListeners(); + } + String adReserveAmount = ""; void updateAdReservePriceAmount(String date) { @@ -307,7 +332,16 @@ class AdVM extends BaseVM { void updateSelectionVehicleTypeId(SelectionModel id) async { vehicleTypeId = id; - getVehicleDetailsByVehicleId(); + getVehicleBrandsByVehicleTypeId(); + notifyListeners(); + } + + SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleBrandId(SelectionModel id) { + vehicleBrandId = id; + getVehicleDetailsByVehicleBrandId(); + notifyListeners(); } @@ -444,18 +478,17 @@ class AdVM extends BaseVM { void updateVehicleAdsSpecialServicesId(SelectionModel id) async { vehicleAdsSpecialServicesId = id; - isFetchingLists = true; - adSSTimeSlots.clear(); - vehicleAdsPhotoServiceDate = SelectionModel(selectedId: -1, selectedOption: ""); - vehicleAdsCarCheckServicesDate = SelectionModel(selectedId: -1, selectedOption: ""); - notifyListeners(); - - if (id.selectedId == 1) { - ssPhotoScheduleModel = await commonRepo.getPhotographyServiceScheduleDetails(lat: 0.0, long: 0.0); - } else if (id.selectedId == 3) { - ssCarCheckScheduleModel = await commonRepo.getCarCheckServiceScheduleDetails(lat: 0.0, long: 0.0); - } else {} - isFetchingLists = false; + // isFetchingLists = true; + // adSSTimeSlots.clear(); + // vehicleAdsPhotoServiceDate = SelectionModel(selectedId: -1, selectedOption: ""); + // vehicleAdsCarCheckServicesDate = SelectionModel(selectedId: -1, selectedOption: ""); + // notifyListeners(); + // if (id.selectedId == 1) { + // ssPhotoScheduleModel = await commonRepo.getPhotographyServiceScheduleDetails(lat: 0.0, long: 0.0); + // } else if (id.selectedId == 3) { + // ssCarCheckScheduleModel = await commonRepo.getCarCheckServiceScheduleDetails(lat: 0.0, long: 0.0); + // } else {} + // isFetchingLists = false; notifyListeners(); } @@ -728,19 +761,26 @@ class AdVM extends BaseVM { adStartDateError = ""; } - if (vehicleAdReservableId.selectedId == -1) { - vehicleAdReservableId.errorValue = "Please select if the Ad is Reservable or not."; + if (isPhoneNumberShown && adPhoneNumber.isEmpty) { + adPhoneNumberError = GlobalConsts.adDurationPhoneNumberError; isValidated = false; } else { - vehicleAdReservableId.errorValue = ""; - } - - if (adReserveAmount.isEmpty) { - adReservePriceError = GlobalConsts.adReservablePriceErrorConst; - isValidated = false; - } else { - adStartDateError = ""; + adPhoneNumberError = ""; } + // + // if (vehicleAdReservableId.selectedId == -1) { + // vehicleAdReservableId.errorValue = "Please select if the Ad is Reservable or not."; + // isValidated = false; + // } else { + // vehicleAdReservableId.errorValue = ""; + // } + // + // if (adReserveAmount.isEmpty) { + // adReservePriceError = GlobalConsts.adReservablePriceErrorConst; + // isValidated = false; + // } else { + // adStartDateError = ""; + // } notifyListeners(); return isValidated; @@ -804,6 +844,7 @@ class AdVM extends BaseVM { currentProgressStep = AdCreationStepsEnum.vehicleDetails; resetValues(); updateIsExploreAds(false); + applyFilterOnMyAds(index: 1, selectedFilterId: 1); navigateReplaceWithName(context, AppRoutes.dashboard); } catch (e) { Utils.hideLoading(context); @@ -821,6 +862,20 @@ class AdVM extends BaseVM { notifyListeners(); } + bool isPhoneNumberShown = false; + + void updateIsPhoneNumberShownStatus(bool status) { + isPhoneNumberShown = status; + notifyListeners(); + } + + bool isNumberOnWhatsApp = false; + + void updateIsNumberOnWhatsAppStatus(bool status) { + isNumberOnWhatsApp = status; + notifyListeners(); + } + List pickedVehicleImages = []; void removeImageFromList(String filePath) { @@ -905,7 +960,8 @@ class AdVM extends BaseVM { specialServiceCards.clear(); currentProgressStep = AdCreationStepsEnum.vehicleDetails; vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); diff --git a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart index c2930d8..5d42ada 100644 --- a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart +++ b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart @@ -1,3 +1,5 @@ +import 'package:country_code_picker/country_code_picker.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; @@ -58,20 +60,34 @@ class AdDuration extends StatelessWidget { children: [ "Ad Duration".toText(fontSize: 18, isBold: true), 8.height, - Builder(builder: (context) { - List vehicleAdsDurationsDrop = []; - for (var element in adVM.vehicleAdsDurations) { - vehicleAdsDurationsDrop.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", "")); - } - return DropdownField( - (DropValue value) => adVM.updateVehicleAdDurationId(SelectionModel(selectedId: value.id, selectedOption: value.value)), - errorValue: adVM.vehicleAdDurationId.errorValue, - list: vehicleAdsDurationsDrop, - hint: "Select Duration", - dropdownValue: adVM.vehicleAdDurationId.selectedId != -1 ? DropValue(adVM.vehicleAdDurationId.selectedId, adVM.vehicleAdDurationId.selectedOption, "") : null, - ); - }), + TxtField( + isBackgroundEnabled: true, + isButtonEnable: false, + isNeedBorder: false, + hint: 'Ad Duration', + value: adVM.vehicleAdDurationId.selectedOption, + isNeedClickAll: true, + postFixDataColor: MyColors.darkTextColor, + onTap: () async { + final formattedDate = await Utils.pickDateFromDatePicker(context); + adVM.updateSelectionDurationStartDate(formattedDate); + }, + ), + // Builder(builder: (context) { + // List vehicleAdsDurationsDrop = []; + // for (var element in adVM.vehicleAdsDurations) { + // vehicleAdsDurationsDrop.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", "")); + // } + // return DropdownField( + // (DropValue value) => adVM.updateVehicleAdDurationId(SelectionModel(selectedId: value.id, selectedOption: value.value)), + // errorValue: adVM.vehicleAdDurationId.errorValue, + // list: vehicleAdsDurationsDrop, + // hint: "Select Duration", + // dropdownValue: adVM.vehicleAdDurationId.selectedId != -1 ? DropValue(adVM.vehicleAdDurationId.selectedId, adVM.vehicleAdDurationId.selectedOption, "") : null, + // ); + // }), 8.height, + TxtField( errorValue: adVM.adStartDateError, hint: 'Start Date', @@ -85,45 +101,134 @@ class AdDuration extends StatelessWidget { }, ), ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)), + ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // "Reservable Ad".toText(fontSize: 18, isBold: true), + // 8.height, + // Builder(builder: (context) { + // List adReservableOptions = []; + // adReservableOptions.add(DropValue(1, "Yes", "")); + // adReservableOptions.add(DropValue(0, "No", "")); + // return DropdownField( + // (DropValue value) => adVM.updateVehicleAdReservableId(SelectionModel(selectedId: value.id, selectedOption: value.value)), + // errorValue: adVM.vehicleAdReservableId.errorValue, + // list: adReservableOptions, + // hint: "Reservable", + // dropdownValue: adVM.vehicleAdReservableId.selectedId != -1 ? DropValue(adVM.vehicleAdReservableId.selectedId, adVM.vehicleAdReservableId.selectedOption, "") : null, + // ); + // }), + // if (adVM.vehicleAdReservableId.selectedId == 1) ...[ + // 8.height, + // TxtField( + // postfixData: Icons.info_outline_rounded, + // postFixDataColor: MyColors.grey77Color, + // onPostFixPressed: () => reservePriceInfoClicked(context), + // value: adVM.adReserveAmount, + // errorValue: adVM.adReservePriceError, + // keyboardType: TextInputType.number, + // hint: "Ad Reserve Price", + // onChanged: (v) => adVM.updateAdReservePriceAmount(v), + // ), + // ], + // ], + // ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Reservable Ad".toText(fontSize: 18, isBold: true), + "Contact Details".toText(fontSize: 18, isBold: true), 8.height, - Builder(builder: (context) { - List adReservableOptions = []; - adReservableOptions.add(DropValue(1, "Yes", "")); - adReservableOptions.add(DropValue(0, "No", "")); - return DropdownField( - (DropValue value) => adVM.updateVehicleAdReservableId(SelectionModel(selectedId: value.id, selectedOption: value.value)), - errorValue: adVM.vehicleAdReservableId.errorValue, - list: adReservableOptions, - hint: "Reservable", - dropdownValue: adVM.vehicleAdReservableId.selectedId != -1 ? DropValue(adVM.vehicleAdReservableId.selectedId, adVM.vehicleAdReservableId.selectedOption, "") : null, - ); - }), - if (adVM.vehicleAdReservableId.selectedId == 1) ...[ - 8.height, + Row( + children: [ + "Do you want to show your number to the buyers?".toText(fontSize: 14), + ], + ), + 6.height, + Container( + width: 38, + height: 25, + decoration: BoxDecoration( + color: adVM.isPhoneNumberShown ? MyColors.darkPrimaryColor : MyColors.white, + borderRadius: BorderRadius.circular(25.0), + border: Border.all(color: MyColors.black, width: 1), + ), + child: Transform.scale( + scale: 0.6, + child: CupertinoSwitch( + activeColor: MyColors.darkPrimaryColor, + trackColor: MyColors.white, + thumbColor: MyColors.grey98Color, + value: adVM.isPhoneNumberShown, + onChanged: (value) { + adVM.updateIsPhoneNumberShownStatus(value); + }, + ), + ), + ), + if (adVM.isPhoneNumberShown) ...[ + 10.height, TxtField( - postfixData: Icons.info_outline_rounded, - postFixDataColor: MyColors.grey77Color, - onPostFixPressed: () => reservePriceInfoClicked(context), - value: adVM.adReserveAmount, - errorValue: adVM.adReservePriceError, - keyboardType: TextInputType.number, - hint: "Ad Reserve Price", - onChanged: (v) => adVM.updateAdReservePriceAmount(v), + preFixWidget: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [adVM.adPhoneNumberDialCode.toText(fontSize: 14)], + ).paddingOnly(left: 15, right: 15), + postfixWidget: SizedBox( + width: 110, + child: Row( + children: [ + CountryCodePicker( + onChanged: (CountryCode code) => adVM.updateAdPhoneNumberDialCode(code.dialCode ?? ""), + hideMainText: true, + initialSelection: '+966', + showOnlyCountryWhenClosed: false, + alignLeft: false, + ), + const Icon( + Icons.arrow_forward_ios_outlined, + size: 18, + color: MyColors.darkTextColor, + ).paddingOnly(right: 5) + ], + ), + ), + errorValue: adVM.adPhoneNumberError, + hint: '123456789', + value: adVM.adPhoneNumber, + onChanged: (v) => adVM.updateAdPhoneNumber(v), + ), + 10.height, + Row( + children: [ + SizedBox( + height: 40.0, + width: 30.0, + child: Transform.scale( + scale: 1.3, + child: Checkbox( + value: adVM.isNumberOnWhatsApp, + activeColor: !adVM.isNumberOnWhatsApp ? MyColors.lightTextColor : MyColors.darkPrimaryColor, + onChanged: (value) { + adVM.updateIsNumberOnWhatsAppStatus(value ?? false); + }, + ), + ), + ), + const SizedBox(width: 10), + "Is this number registered on WhatsApp?".toString().toText(fontSize: 14) + ], ), ], ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)), + ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "Select Special Services".toText(fontSize: 18, isBold: true), 8.height, CustomAddButton( + needsBorder: true, + bgColor: MyColors.white, onTap: () { onAddServiceButtonTapped(context, adVM); }, @@ -175,44 +280,46 @@ class AdDuration extends StatelessWidget { // (specialServicesCard.duration ?? "").toText(fontSize: 12, isBold: true).expand(), // ], // ), - 8.height, - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Description: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - (specialServicesCard.description ?? "").toText(fontSize: 12, isBold: true).expand(), - ], - ), - ], - if (specialServicesCard.serviceSelectedId!.selectedId == 1 || specialServicesCard.serviceSelectedId!.selectedId == 3) ...[ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Icon( - weight: 2, - Icons.location_on_outlined, - color: MyColors.primaryColor, - size: 17, - ), - "${specialServicesCard.duration} km".toText(fontSize: 10, color: MyColors.primaryColor), - ], - ), - 8.height, - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Branch Address: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - (specialServicesCard.address ?? "").toText(fontSize: 12, isBold: true).expand(), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Appointment Time: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - "${specialServicesCard.serviceDate} - ${specialServicesCard.serviceTime}".toText(fontSize: 12, isBold: true).expand(), - ], - ), + if (specialServicesCard.description != null && specialServicesCard.description!.isNotEmpty) ...[ + 4.height, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Description: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + (specialServicesCard.description ?? "").toText(fontSize: 12, isBold: true).expand(), + ], + ), + ], ], + // if ((specialServicesCard.serviceSelectedId!.selectedId == 1 || specialServicesCard.serviceSelectedId!.selectedId == 3)) ...[ + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // const Icon( + // weight: 2, + // Icons.location_on_outlined, + // color: MyColors.primaryColor, + // size: 17, + // ), + // "${specialServicesCard.duration} km".toText(fontSize: 10, color: MyColors.primaryColor), + // ], + // ), + // 8.height, + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // "Branch Address: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + // (specialServicesCard.address ?? "").toText(fontSize: 12, isBold: true).expand(), + // ], + // ), + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // "Appointment Time: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + // "${specialServicesCard.serviceDate} - ${specialServicesCard.serviceTime}".toText(fontSize: 12, isBold: true).expand(), + // ], + // ), + // ], 6.height, Row( crossAxisAlignment: CrossAxisAlignment.end, @@ -235,7 +342,7 @@ class AdDuration extends StatelessWidget { }, ), ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)), + ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), ], ); }, diff --git a/lib/views/advertisement/ad_creation_steps/ad_review_containers.dart b/lib/views/advertisement/ad_creation_steps/ad_review_containers.dart index 4de0e27..193ab0c 100644 --- a/lib/views/advertisement/ad_creation_steps/ad_review_containers.dart +++ b/lib/views/advertisement/ad_creation_steps/ad_review_containers.dart @@ -14,10 +14,11 @@ class ReviewAd extends StatelessWidget { Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - VehicleDetailsReview(), - DamagePartsReview(), - AdDurationReview(), + children: [ + VehicleDetailsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), + DamagePartsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), + AdDurationReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), + AdContactDetailsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)), ], ); } @@ -46,81 +47,79 @@ class VehicleDetailsReview extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (BuildContext context, AdVM adVM, Widget? child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, + AdVM adVM = context.read(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Vehicle Details".toText(fontSize: 18, isBold: true), + 8.height, + Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ - "Vehicle Details".toText(fontSize: 18, isBold: true), - 8.height, - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - flex: 7, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleDetailWidget(text: adVM.vehicleTypeId.selectedOption, type: "Vehicle Type"), - 16.height, - SingleDetailWidget(text: adVM.vehicleModelYearId.selectedOption, type: "Vehicle Year"), - 16.height, - SingleDetailWidget(text: adVM.vehicleConditionId.selectedOption, type: "Vehicle Condition"), - 16.height, - SingleDetailWidget(text: adVM.vehicleMileageId.selectedOption, type: "Vehicle Mileage"), - 16.height, - SingleDetailWidget(text: adVM.vehicleSellerTypeId.selectedOption, type: "Seller Type"), - 16.height, - SingleDetailWidget(text: adVM.vehicleCityId.selectedOption, type: "Vehicle City"), - 16.height, - SingleDetailWidget(text: adVM.vehicleVin, type: "Vehicle VIN"), - 16.height, - SingleDetailWidget(text: "${adVM.warrantyDuration} Years", type: "Warranty Available"), - 16.height, - ], - ), - ), - Expanded( - flex: 5, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleDetailWidget(text: adVM.vehicleModelId.selectedOption, type: "Vehicle Model"), - 16.height, - SingleDetailWidget(text: adVM.vehicleColorId.selectedOption, type: "Vehicle Color"), - 16.height, - SingleDetailWidget(text: adVM.vehicleCategoryId.selectedOption, type: "Vehicle Category"), - 16.height, - SingleDetailWidget(text: adVM.vehicleTransmissionId.selectedOption, type: "Vehicle Transmission"), - 16.height, - SingleDetailWidget(text: adVM.vehicleCountryId.selectedOption, type: "Vehicle Country"), - 16.height, - SingleDetailWidget(text: adVM.vehicleDemandAmount, type: "Vehicle Amount"), - 16.height, - SingleDetailWidget(text: adVM.vehicleTitle, type: "Vehicle Title"), - 16.height, - SingleDetailWidget(text: adVM.financeAvailableStatus ? "Yes" : "No", type: "Finance Available"), - 16.height, - ], - ), - ), - ], + Expanded( + flex: 7, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SingleDetailWidget(text: adVM.vehicleTypeId.selectedOption, type: "Vehicle Type"), + 16.height, + SingleDetailWidget(text: adVM.vehicleModelYearId.selectedOption, type: "Vehicle Year"), + 16.height, + SingleDetailWidget(text: adVM.vehicleConditionId.selectedOption, type: "Vehicle Condition"), + 16.height, + SingleDetailWidget(text: adVM.vehicleMileageId.selectedOption, type: "Vehicle Mileage"), + 16.height, + SingleDetailWidget(text: adVM.vehicleSellerTypeId.selectedOption, type: "Seller Type"), + 16.height, + SingleDetailWidget(text: adVM.vehicleCityId.selectedOption, type: "Vehicle City"), + 16.height, + SingleDetailWidget(text: adVM.vehicleVin, type: "Vehicle VIN"), + 16.height, + SingleDetailWidget(text: "${adVM.warrantyDuration} Years", type: "Warranty Available"), + 16.height, + ], + ), ), - SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"), - 8.height, - "Vehicle Pictures:".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - if (adVM.pickedVehicleImages.isNotEmpty) ...[ - // 10.height, - PickedImagesContainer( - pickedImages: adVM.pickedVehicleImages, - onCrossPressedPrimary: adVM.removeImageFromList, - isReview: true, - onAddImagePressed: () {}, + Expanded( + flex: 5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SingleDetailWidget(text: adVM.vehicleModelId.selectedOption, type: "Vehicle Model"), + 16.height, + SingleDetailWidget(text: adVM.vehicleColorId.selectedOption, type: "Vehicle Color"), + 16.height, + SingleDetailWidget(text: adVM.vehicleCategoryId.selectedOption, type: "Vehicle Category"), + 16.height, + SingleDetailWidget(text: adVM.vehicleTransmissionId.selectedOption, type: "Vehicle Transmission"), + 16.height, + SingleDetailWidget(text: adVM.vehicleCountryId.selectedOption, type: "Vehicle Country"), + 16.height, + SingleDetailWidget(text: adVM.vehicleDemandAmount, type: "Vehicle Amount"), + 16.height, + SingleDetailWidget(text: adVM.vehicleTitle, type: "Vehicle Title"), + 16.height, + SingleDetailWidget(text: adVM.financeAvailableStatus ? "Yes" : "No", type: "Finance Available"), + 16.height, + ], ), - ], + ), ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); - }, + ), + SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"), + 8.height, + "Vehicle Pictures:".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + if (adVM.pickedVehicleImages.isNotEmpty) ...[ + // 10.height, + PickedImagesContainer( + pickedImages: adVM.pickedVehicleImages, + onCrossPressedPrimary: adVM.removeImageFromList, + isReview: true, + onAddImagePressed: () {}, + ), + ], + ], ); } } @@ -160,16 +159,14 @@ class DamagePartsReview extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (BuildContext context, AdVM adVM, Widget? child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Vehicle Damage Part".toText(fontSize: 18, isBold: true), - buildDamagePartList(adVM), - ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); - }, + AdVM adVM = context.read(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Vehicle Damage Part".toText(fontSize: 18, isBold: true), + buildDamagePartList(adVM), + ], ); } } @@ -198,23 +195,23 @@ class AdDurationReview extends StatelessWidget { ), ], ), - 15.height, - "Reservable Ad".toText(fontSize: 18, isBold: true), - 8.height, - Row( - children: [ - Expanded( - flex: 7, - child: SingleDetailWidget(type: "Reservable", text: adVM.vehicleAdReservableId.selectedId == 1 ? "Yes" : "No"), - ), - Expanded( - flex: 5, - child: adVM.vehicleAdReservableId.selectedId == 1 - ? SingleDetailWidget(type: "Reserve Price", text: adVM.adReserveAmount) - : const SizedBox(), - ), - ], - ), + // 15.height, + // "Reservable Ad".toText(fontSize: 18, isBold: true), + // 8.height, + // Row( + // children: [ + // Expanded( + // flex: 7, + // child: SingleDetailWidget(type: "Reservable", text: adVM.vehicleAdReservableId.selectedId == 1 ? "Yes" : "No"), + // ), + // Expanded( + // flex: 5, + // child: adVM.vehicleAdReservableId.selectedId == 1 + // ? SingleDetailWidget(type: "Reserve Price", text: adVM.adReserveAmount) + // : const SizedBox(), + // ), + // ], + // ), if (adVM.specialServiceCards.isNotEmpty) ...[ 15.height, "Special Services".toText(fontSize: 18, isBold: true), @@ -250,39 +247,69 @@ class AdDurationReview extends StatelessWidget { ), ], ), - if (adVM.specialServiceCards[index].serviceSelectedId!.selectedId == 1 || adVM.specialServiceCards[index].serviceSelectedId!.selectedId == 3) ...[ - Row( - children: [ - Expanded( - flex: 7, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 8.height, - SingleDetailWidget(type: "Branch Address", text: adVM.specialServiceCards[index].address ?? ""), - ], - ), - ), - Expanded( - flex: 5, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleDetailWidget(type: "Appointment Time", text: "${adVM.specialServiceCards[index].serviceDate ?? ""} - ${adVM.specialServiceCards[index].serviceTime}"), - ], - ), - ), - ], - ) - ], + // if (adVM.specialServiceCards[index].serviceSelectedId!.selectedId == 1 || adVM.specialServiceCards[index].serviceSelectedId!.selectedId == 3) ...[ + // Row( + // children: [ + // Expanded( + // flex: 7, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // 8.height, + // SingleDetailWidget(type: "Branch Address", text: adVM.specialServiceCards[index].address ?? ""), + // ], + // ), + // ), + // Expanded( + // flex: 5, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // SingleDetailWidget(type: "Appointment Time", text: "${adVM.specialServiceCards[index].serviceDate ?? ""} - ${adVM.specialServiceCards[index].serviceTime}"), + // ], + // ), + // ), + // ], + // ) + // ], ], ); }, ) ], ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); + ); }, ); } } + +class AdContactDetailsReview extends StatelessWidget { + const AdContactDetailsReview({super.key}); + + @override + Widget build(BuildContext context) { + AdVM adVM = context.read(); + return adVM.isPhoneNumberShown + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Ad Contact Details".toText(fontSize: 18, isBold: true), + 8.height, + Row( + children: [ + Expanded( + flex: 7, + child: SingleDetailWidget(type: "Phone Number", text: "${adVM.adPhoneNumberDialCode}${adVM.adPhoneNumber}"), + ), + Expanded( + flex: 5, + child: SingleDetailWidget(type: "On WhatsApp", text: adVM.isNumberOnWhatsApp ? "Yes" : "No"), + ), + ], + ), + ], + ) + : const SizedBox.shrink(); + } +} diff --git a/lib/views/advertisement/ad_creation_steps/damage_parts_container.dart b/lib/views/advertisement/ad_creation_steps/damage_parts_container.dart index ba53e82..4004158 100644 --- a/lib/views/advertisement/ad_creation_steps/damage_parts_container.dart +++ b/lib/views/advertisement/ad_creation_steps/damage_parts_container.dart @@ -33,8 +33,6 @@ class DamageParts extends StatelessWidget { }); } - - @override Widget build(BuildContext context) { return Consumer( @@ -43,6 +41,8 @@ class DamageParts extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ CustomAddButton( + needsBorder: true, + bgColor: MyColors.white, onTap: () { onAddButtonTapped(context, adVM); }, @@ -53,7 +53,7 @@ class DamageParts extends StatelessWidget { decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), child: const Icon(Icons.add, color: MyColors.white), )).horPaddingMain(), - 9.height, + 8.height, ListView.builder( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -129,7 +129,7 @@ class DamageParts extends StatelessWidget { ).paddingOnly(right: 10) ], ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); + ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)); }, ), // DottedRectContainer( diff --git a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart index 4abb845..b772ca5 100644 --- a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart +++ b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart @@ -24,22 +24,20 @@ class VehicleDetails extends StatelessWidget { children: [ "Vehicle Detail".toText(fontSize: 18, isBold: true), 8.height, - // Builder( - // builder: (BuildContext context) { - // List vehicleTypesDrop = []; - // for (var element in adVM.vehicleTypes) { - // vehicleTypesDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleTypeName ?? "", "")); - // } - // return DropdownField( - // (DropValue value) => adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value, errorValue: "")), - // list: vehicleTypesDrop, - // dropdownValue: adVM.vehicleTypeId.selectedId != -1 ? DropValue(adVM.vehicleTypeId.selectedId, adVM.vehicleTypeId.selectedOption, "") : null, - // errorValue: adVM.vehicleTypeId.errorValue, - // hint: "Vehicle Type", - // ); - // }, - // ), - if (adVM.vehicleTypeId.selectedId != -1) ...[ + Builder(builder: (context) { + List vehicleBrandsDrop = []; + for (var element in adVM.vehicleBrands) { + vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleBrandDescription ?? "", "")); + } + return DropdownField( + (DropValue value) => adVM.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value)), + list: vehicleBrandsDrop, + dropdownValue: adVM.vehicleBrandId.selectedId != -1 ? DropValue(adVM.vehicleBrandId.selectedId, adVM.vehicleBrandId.selectedOption, "") : null, + hint: "Vehicle Brand", + errorValue: adVM.vehicleBrandId.errorValue, + ); + }), + if (adVM.vehicleBrandId.selectedId != -1) ...[ if (adVM.isFetchingLists) ...[ const Row( mainAxisAlignment: MainAxisAlignment.center, @@ -240,21 +238,24 @@ class VehicleDetails extends StatelessWidget { "Finance Available".toText(fontSize: 16), 8.height, Container( - width: 65, - height: 37, + width: 50, + height: 30, decoration: BoxDecoration( color: adVM.financeAvailableStatus ? MyColors.darkPrimaryColor : MyColors.white, borderRadius: BorderRadius.circular(25.0), - border: Border.all(color: MyColors.black, width: 1.5), + border: Border.all(color: MyColors.black, width: 1), ), - child: CupertinoSwitch( - activeColor: MyColors.darkPrimaryColor, - trackColor: MyColors.white, - thumbColor: MyColors.grey98Color, - value: adVM.financeAvailableStatus, - onChanged: (value) { - adVM.updateFinanceAvailableStatus(value); - }, + child: Transform.scale( + scale: 0.8, + child: CupertinoSwitch( + activeColor: MyColors.darkPrimaryColor, + trackColor: MyColors.white, + thumbColor: MyColors.grey98Color, + value: adVM.financeAvailableStatus, + onChanged: (value) { + adVM.updateFinanceAvailableStatus(value); + }, + ), ), ), 28.height, diff --git a/lib/views/advertisement/ad_duration_selection_sheet_content.dart b/lib/views/advertisement/ad_duration_selection_sheet_content.dart index 5e2b576..6efc03e 100644 --- a/lib/views/advertisement/ad_duration_selection_sheet_content.dart +++ b/lib/views/advertisement/ad_duration_selection_sheet_content.dart @@ -1,18 +1,24 @@ import 'package:flutter/material.dart'; +import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; +import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; +import 'package:mc_common_app/models/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/view_models/ad_view_model.dart'; +import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; +import 'package:provider/provider.dart'; class AdDurationSelectionSheetContent extends StatelessWidget { - //TODO: This will be updated when there is an API for the duration - final VehicleTypeModel vehicleType; - - const AdDurationSelectionSheetContent({required this.vehicleType, super.key}); + const AdDurationSelectionSheetContent({super.key}); @override Widget build(BuildContext context) { + AdVM adVM = context.watch(); + + print("hello : ${adVM.vehicleAdDurationId.selectedId}"); return SizedBox( height: MediaQuery.of(context).size.height / 1.2, child: Column( @@ -25,8 +31,9 @@ class AdDurationSelectionSheetContent extends StatelessWidget { Expanded( child: ListView.separated( shrinkWrap: true, - itemCount: 5, + itemCount: adVM.vehicleAdsDurations.length, itemBuilder: (BuildContext context, int index) { + AdsDurationModel adDuration = adVM.vehicleAdsDurations[index]; return SizedBox( width: double.infinity, child: Row( @@ -38,9 +45,9 @@ class AdDurationSelectionSheetContent extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - "7 Days".toString().toText(fontSize: 16, isBold: true), + "${adDuration.days} Days".toString().toText(fontSize: 16, isBold: true), 4.height, - "Your Ad will be active for 7 days and then you will need to extend it to keep it active. ".toText( + "Your Ad will be active for ${adDuration.days} Days and then you will need to extend it to keep it active. ".toText( fontSize: 14, color: MyColors.lightTextColor, ), @@ -49,7 +56,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - "300".toText(fontSize: 22, isBold: true), + "${adDuration.price}".toText(fontSize: 22, isBold: true), 2.width, Padding( padding: const EdgeInsets.only(bottom: 4), @@ -61,8 +68,16 @@ class AdDurationSelectionSheetContent extends StatelessWidget { ), ), ], - ).toWhiteContainer(width: double.infinity, allPading: 12, isBorderRequired: index == 0 ? true : false), - ); + ).toWhiteContainer(width: double.infinity, allPading: 12, isBorderRequired: adDuration.id == adVM.vehicleAdDurationId.selectedId ? true : false), + ).onPress(() { + adVM.updateVehicleAdDurationId( + SelectionModel( + selectedId: adDuration.id ?? 0, + selectedOption: "${adDuration.days} Days", + itemPrice: adDuration.price!.toInt().toString(), + ), + ); + }); }, separatorBuilder: (BuildContext context, int index) { return 12.height; @@ -70,6 +85,15 @@ class AdDurationSelectionSheetContent extends StatelessWidget { padding: const EdgeInsets.all(20), ), ), + ShowFillButton( + title: "Select", + maxWidth: double.infinity, + margin: const EdgeInsets.all(21), + onPressed: () { + + navigateReplaceWithName(context, AppRoutes.createAdView); + }, + ).toContainer(paddingAll: 0, backgroundColor: Colors.white), ], ), ); diff --git a/lib/views/advertisement/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view.dart index 614fab3..611a945 100644 --- a/lib/views/advertisement/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view.dart @@ -11,6 +11,7 @@ import 'package:mc_common_app/view_models/payment_view_model.dart'; import 'package:mc_common_app/views/advertisement/ads_images_slider.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/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; @@ -21,12 +22,17 @@ class AdsDetailView extends StatelessWidget { @override Widget build(BuildContext context) { + print("adId: ${adDetails.isMyAd}"); return Scaffold( appBar: CustomAppBar( title: "Ads", profileImageUrl: MyAssets.bnCar, isRemoveBackButton: false, isDrawerEnabled: false, + actions: [Icon(Icons.chat_outlined).paddingOnly(right: 21)], + onTap: () { + print("heyyyy"); + }, ), body: Container( padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21), @@ -106,11 +112,13 @@ class AdsDetailView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, isBold: true), - "SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor), + " SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), ], ), 14.height, - BuildAdDetailsActionButton(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!), + adDetails.isMyAd ?? false + ? BuildAdDetailsActionButtonForMyAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!) + : BuildAdDetailsActionButtonForExploreAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!), ], ), ) @@ -121,11 +129,11 @@ class AdsDetailView extends StatelessWidget { } } -class BuildAdDetailsActionButton extends StatelessWidget { +class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { final AdPostStatus adPostStatus; final int adId; - const BuildAdDetailsActionButton({Key? key, required this.adPostStatus, required this.adId}) : super(key: key); + const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key); Widget pendingForPaymentAction(BuildContext context, {required int adID}) { return Column( @@ -210,6 +218,150 @@ class BuildAdDetailsActionButton extends StatelessWidget { } Widget defaultAction(BuildContext context) { + void reserveAdPriceBreakDownClicked(BuildContext context) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return InfoBottomSheet( + title: "Reserve Ad", + description: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Reservation Amounts".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "500".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + const Divider(), + "Below Amount that you will pay later".toText(fontSize: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "Car Price".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "30,000".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "4,500".toText(fontSize: 16, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0), + ], + ) + ], + ), + const Divider(), + "Special Services".toText(fontSize: 16, isBold: true), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 12.height, + "Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12), + 30.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Total Amount ".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "34,500".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + "Estimated".toText(fontSize: 10, isBold: true), + ], + ), + 44.height, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const Icon( + Icons.warning, + color: MyColors.adPendingStatusColor, + size: 19, + ).paddingOnly(bottom: 2), + 3.width, + "Some services are mandatory while reserving the Ad.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ], + ), + 15.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Complete Reservation", + onPressed: () { + Navigator.pop(context); + navigateWithName(context, AppRoutes.paymentMethodsView); + }, + ), + ), + ], + ), + 19.height, + ], + )); + }); + } + return Row( children: [ Expanded( @@ -217,16 +369,26 @@ class BuildAdDetailsActionButton extends StatelessWidget { maxHeight: 55, title: "Reserve Ad", onPressed: () { - navigateWithName(context, AppRoutes.paymentMethodsView); + reserveAdPriceBreakDownClicked(context); + // navigateWithName(context, AppRoutes.paymentMethodsView); }, ), ), - 12.width, + 8.width, + Container( + height: 55, + width: 55, + alignment: Alignment.center, + decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), + //TODO: It Will be replaced by a WhatsApp Icon + child: const Icon(Icons.message, color: MyColors.black), + ).onPress(() {}), + 8.width, Container( height: 55, width: 55, alignment: Alignment.center, - decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 3)), + decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), child: const Icon(Icons.phone, color: MyColors.black), ).onPress(() {}), ], @@ -251,6 +413,10 @@ class BuildAdDetailsActionButton extends StatelessWidget { case AdPostStatus.pendingForPost: case AdPostStatus.pendingForReview: return pendingForPaymentAction(context, adID: adId); + + return defaultAction(context); + + return pendingForPaymentAction(context, adID: adId); case AdPostStatus.sold: case AdPostStatus.expired: break; @@ -258,3 +424,297 @@ class BuildAdDetailsActionButton extends StatelessWidget { return defaultAction(context); } } + +class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { + final AdPostStatus adPostStatus; + final int adId; + + const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key); + + Widget pendingForPaymentAction(BuildContext context, {required int adID}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Pay Now", + onPressed: () { + navigateWithName(context, AppRoutes.paymentMethodsView); + }, + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: "Delete Ad".toText(fontSize: 15, isBold: true, color: MyColors.redColor), + ), + ), + ], + ) + ], + ); + } + + Widget markAsSoldAction(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Mark As Sold", + onPressed: () {}, + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: "Delete Ad".toText(fontSize: 15, isBold: true, color: MyColors.redColor), + ), + ), + ], + ) + ], + ); + } + + Widget cancelReservationAction(BuildContext context) { + return Row( + children: [ + Expanded( + child: ShowFillButton( + borderColor: MyColors.redColor, + txtColor: MyColors.redColor, + isFilled: false, + fontSize: 16, + maxHeight: 55, + title: "Cancel Reservation", + onPressed: () {}, + ), + ), + ], + ); + } + + Widget defaultAction(BuildContext context) { + void reserveAdPriceBreakDownClicked(BuildContext context) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return InfoBottomSheet( + title: "Reserve Ad", + description: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Reservation Amounts".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "500".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + const Divider(), + "Below Amount that you will pay later".toText(fontSize: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "Car Price".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "30,000".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "4,500".toText(fontSize: 16, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0), + ], + ) + ], + ), + const Divider(), + "Special Services".toText(fontSize: 16, isBold: true), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 5.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + "To be Decided".toText(fontSize: 12, isBold: true), + ], + ), + 12.height, + "Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12), + 30.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Total Amount ".toText(fontSize: 16, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "34,500".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3), + ], + ) + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + "Estimated".toText(fontSize: 10, isBold: true), + ], + ), + 44.height, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const Icon( + Icons.warning, + color: MyColors.adPendingStatusColor, + size: 19, + ).paddingOnly(bottom: 2), + 3.width, + "Some services are mandatory while reserving the Ad.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ], + ), + 15.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Complete Reservation", + onPressed: () { + Navigator.pop(context); + navigateWithName(context, AppRoutes.paymentMethodsView); + }, + ), + ), + ], + ), + 19.height, + ], + )); + }); + } + + return Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Reserve Ad", + onPressed: () { + reserveAdPriceBreakDownClicked(context); + // navigateWithName(context, AppRoutes.paymentMethodsView); + }, + ), + ), + 8.width, + Container( + height: 55, + width: 55, + alignment: Alignment.center, + decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), + //TODO: It Will be replaced by a WhatsApp Icon + child: const Icon(Icons.message, color: MyColors.black), + ).onPress(() {}), + 8.width, + Container( + height: 55, + width: 55, + alignment: Alignment.center, + decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), + child: const Icon(Icons.phone, color: MyColors.black), + ).onPress(() {}), + ], + ); + } + + @override + Widget build(BuildContext context) { + context.read().updateCurrentAdId(id: adId); + switch (adPostStatus) { + case AdPostStatus.pendingForPayment: + return pendingForPaymentAction(context, adID: adId); + case AdPostStatus.active: + return markAsSoldAction(context); + case AdPostStatus.reserved: + break; + case AdPostStatus.buyingService: + case AdPostStatus.reserveCancel: + case AdPostStatus.rejected: + case AdPostStatus.cancelled: + case AdPostStatus.pendingForPost: + case AdPostStatus.pendingForReview: + break; + return defaultAction(context); + + return pendingForPaymentAction(context, adID: adId); + case AdPostStatus.sold: + case AdPostStatus.expired: + break; + } + return const SizedBox.shrink(); + } +} diff --git a/lib/views/advertisement/ads_list.dart b/lib/views/advertisement/ads_list.dart index 0ae4ecf..c5e0e26 100644 --- a/lib/views/advertisement/ads_list.dart +++ b/lib/views/advertisement/ads_list.dart @@ -10,7 +10,6 @@ import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; -import 'package:sizer/sizer.dart'; class BuildAdsList extends StatelessWidget { final List adsList; @@ -46,7 +45,7 @@ class BuildAdsList extends StatelessWidget { isAdsFragment: isAdsFragment, shouldShowAdStatus: shouldShowAdStatus, ).onPress( - () { + () { navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]); }, ); @@ -100,9 +99,7 @@ class AdCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - if (isAdsFragment && context - .read() - .isExploreAdsTapped) ...[ + if (isAdsFragment && context.read().isExploreAdsTapped) ...[ Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), ], if (shouldShowAdStatus) ...[ @@ -139,8 +136,8 @@ class AdCard extends StatelessWidget { ), adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText( - color: MyColors.lightTextColor, - ) + color: MyColors.lightTextColor, + ) : const SizedBox(), ], ), @@ -191,6 +188,9 @@ class AdCard extends StatelessWidget { else const SizedBox(), ], - ).toWhiteContainer(width: double.infinity, allPading: 12,); + ).toWhiteContainer( + width: double.infinity, + allPading: 12, + ); } } diff --git a/lib/views/advertisement/ads_search_filter_view.dart b/lib/views/advertisement/ads_search_filter_view.dart new file mode 100644 index 0000000..313f7db --- /dev/null +++ b/lib/views/advertisement/ads_search_filter_view.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/consts.dart'; +import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; + +class AdsSearchFilterView extends StatelessWidget { + const AdsSearchFilterView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + title: "Filter Ads", + profileImageUrl: MyAssets.bnCar, + isRemoveBackButton: false, + isDrawerEnabled: false, + ), + ); + } +} diff --git a/lib/views/advertisement/bottom_sheet_content.dart b/lib/views/advertisement/bottom_sheet_content.dart index 61d74f9..6698f63 100644 --- a/lib/views/advertisement/bottom_sheet_content.dart +++ b/lib/views/advertisement/bottom_sheet_content.dart @@ -11,6 +11,7 @@ import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:provider/provider.dart'; +import 'package:sizer/sizer.dart'; class BottomSheetListContent extends StatefulWidget { const BottomSheetListContent({Key? key}) : super(key: key); @@ -147,7 +148,7 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { const BottomSheetAdSpecialServiceContent({Key? key}) : super(key: key); bool isButtonTappable(AdVM adVM) { - bool status = (adVM.vehicleAdsSpecialServicesId.selectedId != -1) && (adVM.vehicleAdsSpecialServicesId.selectedOption != "" && adVM.slotSelectedIndex != null); + bool status = (adVM.vehicleAdsSpecialServicesId.selectedId != -1) && (adVM.vehicleAdsSpecialServicesId.selectedOption != ""); if (status) { return true; } @@ -164,7 +165,6 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { Flexible( child: description.toText( fontSize: 15, - isBold: true, color: MyColors.lightTextColor, ), ), @@ -217,55 +217,56 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { ] else ...[ 8.height, if ((adVM.vehicleAdsSpecialServicesId.selectedId == 1 && adVM.ssPhotoScheduleModel != null)) ...[ - Builder( - builder: (context) { - List vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdPhotoService(); - - return DropdownField( - (DropValue value) => adVM.updateVehicleVehicleAdsPhotoServiceDate(SelectionModel( - selectedId: value.id, - selectedOption: value.value, - )), - list: vehicleAdsSpecialServiceDates, - hint: "Select Date", - dropdownValue: adVM.vehicleAdsPhotoServiceDate.selectedId != -1 - ? DropValue( - adVM.vehicleAdsPhotoServiceDate.selectedId, - adVM.vehicleAdsPhotoServiceDate.selectedOption, - "", - ) - : null, - ); - }, - ), - 22.height, + // Builder( + // builder: (context) { + // List vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdPhotoService(); + // + // return DropdownField( + // (DropValue value) => adVM.updateVehicleVehicleAdsPhotoServiceDate(SelectionModel( + // selectedId: value.id, + // selectedOption: value.value, + // )), + // list: vehicleAdsSpecialServiceDates, + // hint: "Select Date", + // dropdownValue: adVM.vehicleAdsPhotoServiceDate.selectedId != -1 + // ? DropValue( + // adVM.vehicleAdsPhotoServiceDate.selectedId, + // adVM.vehicleAdsPhotoServiceDate.selectedOption, + // "", + // ) + // : null, + // ); + // }, + // ), + // 22.height, ] else if ((adVM.vehicleAdsSpecialServicesId.selectedId == 3 && adVM.ssCarCheckScheduleModel != null)) ...[ - Builder( - builder: (context) { - List vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdCarCheckService(); - - return DropdownField( - (DropValue value) => adVM.updateVehicleAdsCarCheckServicesDate(SelectionModel( - selectedId: value.id, - selectedOption: value.value, - )), - list: vehicleAdsSpecialServiceDates, - hint: "Select Date", - dropdownValue: adVM.vehicleAdsCarCheckServicesDate.selectedId != -1 - ? DropValue( - adVM.vehicleAdsCarCheckServicesDate.selectedId, - adVM.vehicleAdsCarCheckServicesDate.selectedOption, - "", - ) - : null, - ); - }, - ), - 22.height, + // Builder( + // builder: (context) { + // List vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdCarCheckService(); + // + // return DropdownField( + // (DropValue value) => adVM.updateVehicleAdsCarCheckServicesDate(SelectionModel( + // selectedId: value.id, + // selectedOption: value.value, + // )), + // list: vehicleAdsSpecialServiceDates, + // hint: "Select Date", + // dropdownValue: adVM.vehicleAdsCarCheckServicesDate.selectedId != -1 + // ? DropValue( + // adVM.vehicleAdsCarCheckServicesDate.selectedId, + // adVM.vehicleAdsCarCheckServicesDate.selectedOption, + // "", + // ) + // : null, + // ); + // }, + // ), + // 22.height, ], if (adVM.vehicleAdsSpecialServicesId.selectedId != 3 && adVM.vehicleAdsSpecialServicesId.selectedId != 1) ...[ descriptionCard( - description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "", + description: + adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "Some Dummy Service Description!!", ), ], if (adVM.adSSTimeSlots.isNotEmpty) ...[ @@ -273,14 +274,19 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { 8.height, BuildTimeSlots( timeSlots: adVM.adSSTimeSlots, - onPressed: (index) => adVM.updateIsSelectedInSlots(index), ), ], 22.height, "Service Amount".toText(fontSize: 16, isBold: true, color: MyColors.lightTextColor), - adVM.vehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true), - "SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + adVM.vehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true), + SizedBox(width: 1.w), + "SAR".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 2), + ], + ), ], ], ], @@ -299,28 +305,41 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { adVM.addNewSpecialServiceCard( specialServiceCard: SpecialServiceCard( - serviceDate: adVM.vehicleAdsSpecialServicesId.selectedId == 1 - ? adVM.vehicleAdsPhotoServiceDate.selectedOption - : adVM.vehicleAdsSpecialServicesId.selectedId == 3 - ? adVM.vehicleAdsCarCheckServicesDate.selectedOption - : "", - serviceDateError: "", serviceSelectedId: adVM.vehicleAdsSpecialServicesId, - serviceTimeError: "", description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "", - duration: adVM.vehicleAdsSpecialServicesId.selectedId == 1 - ? adVM.ssPhotoScheduleModel!.distanceKM.toString() - : adVM.vehicleAdsSpecialServicesId.selectedId == 3 - ? adVM.ssCarCheckScheduleModel!.distanceKM.toString() - : "", - address: adVM.vehicleAdsSpecialServicesId.selectedId == 1 - ? "${adVM.ssPhotoScheduleModel!.photoOfficeName} - ${adVM.ssPhotoScheduleModel!.areaName}" - : adVM.vehicleAdsSpecialServicesId.selectedId == 3 - ? adVM.ssCarCheckScheduleModel!.address - : "", - serviceTime: adVM.slotSelectedIndex == null || adVM.adSSTimeSlots.isEmpty ? "" : adVM.adSSTimeSlots[adVM.slotSelectedIndex!].slot, + duration: "", + serviceDate: "", + serviceDateError: "", + serviceTimeError: "", + address: "", + serviceTime: "", ), ); + + // adVM.addNewSpecialServiceCard( + // specialServiceCard: SpecialServiceCard( + // serviceDate: adVM.vehicleAdsSpecialServicesId.selectedId == 1 + // ? adVM.vehicleAdsPhotoServiceDate.selectedOption + // : adVM.vehicleAdsSpecialServicesId.selectedId == 3 + // ? adVM.vehicleAdsCarCheckServicesDate.selectedOption + // : "", + // serviceDateError: "", + // serviceSelectedId: adVM.vehicleAdsSpecialServicesId, + // serviceTimeError: "", + // description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "", + // duration: adVM.vehicleAdsSpecialServicesId.selectedId == 1 + // ? adVM.ssPhotoScheduleModel!.distanceKM.toString() + // : adVM.vehicleAdsSpecialServicesId.selectedId == 3 + // ? adVM.ssCarCheckScheduleModel!.distanceKM.toString() + // : "", + // address: adVM.vehicleAdsSpecialServicesId.selectedId == 1 + // ? "${adVM.ssPhotoScheduleModel!.photoOfficeName} - ${adVM.ssPhotoScheduleModel!.areaName}" + // : adVM.vehicleAdsSpecialServicesId.selectedId == 3 + // ? adVM.ssCarCheckScheduleModel!.address + // : "", + // serviceTime: adVM.slotSelectedIndex == null || adVM.adSSTimeSlots.isEmpty ? "" : adVM.adSSTimeSlots[adVM.slotSelectedIndex!].slot, + // ), + // ); }, ).paddingOnly(bottom: 10), ), diff --git a/lib/views/advertisement/create_ad_progress_steps.dart b/lib/views/advertisement/create_ad_progress_steps.dart index c1b26cc..6033ed2 100644 --- a/lib/views/advertisement/create_ad_progress_steps.dart +++ b/lib/views/advertisement/create_ad_progress_steps.dart @@ -23,11 +23,10 @@ class CreateAdProgressSteps extends StatelessWidget { color: isSelected ? MyColors.darkPrimaryColor : MyColors.white, border: Border.all( color: isSelected ? MyColors.darkPrimaryColor : MyColors.lightIconColor, + width: 0.3, ), ), - child: icon.buildSvg( - color: isSelected ? MyColors.white : MyColors.lightIconColor, - ), + child: icon.buildSvg(color: isSelected ? MyColors.white : MyColors.lightIconColor).paddingAll(3), ), 5.height, title.toText( @@ -41,24 +40,36 @@ class CreateAdProgressSteps extends StatelessWidget { } bool isStepCompleted({required AdCreationStepsEnum currentStep}) { - return true; } + int getProgressStepNumber({required AdCreationStepsEnum currentStep}) { + switch (currentStep) { + case AdCreationStepsEnum.vehicleDetails: + return 1; + case AdCreationStepsEnum.damageParts: + return 2; + case AdCreationStepsEnum.adDuration: + return 3; + case AdCreationStepsEnum.reviewAd: + return 4; + } + } + @override Widget build(BuildContext context) { AdVM adVM = context.watch(); return Stack( // alignment: Alignment.center, children: [ - const Divider(thickness: 2).paddingOnly(left: 21, right: 21, top: 15), + const Divider(thickness: 1).paddingOnly(left: 21, right: 21, top: 15), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - buildStep(MyAssets.carIcon, "Vehicle \n Details", adVM.currentProgressStep == AdCreationStepsEnum.vehicleDetails), - buildStep(MyAssets.carHitIcon, "Damage \n Parts", adVM.currentProgressStep == AdCreationStepsEnum.damageParts), - buildStep(MyAssets.clockIcon, "Ad \n Duration", adVM.currentProgressStep == AdCreationStepsEnum.adDuration), - buildStep(MyAssets.reviewIcon, "Review \n Ad", adVM.currentProgressStep == AdCreationStepsEnum.reviewAd), + buildStep(MyAssets.carIcon, "Vehicle \n Details", getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 1), + buildStep(MyAssets.carHitIcon, "Damage \n Parts", getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 2), + buildStep(MyAssets.clockIcon, "Additional \n Details", getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 3), + buildStep(MyAssets.reviewIcon, "Review \n Ad", getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 4), ], ), ], diff --git a/lib/views/advertisement/custom_add_button.dart b/lib/views/advertisement/custom_add_button.dart index 9947022..5cb5b5a 100644 --- a/lib/views/advertisement/custom_add_button.dart +++ b/lib/views/advertisement/custom_add_button.dart @@ -5,17 +5,19 @@ import 'package:mc_common_app/theme/colors.dart'; class CustomAddButton extends StatelessWidget { final Widget icon; final String text; + final Color bgColor; + final bool needsBorder; final Function() onTap; - const CustomAddButton({Key? key, required this.text, required this.onTap, required this.icon}) : super(key: key); + const CustomAddButton({Key? key, required this.text, required this.onTap, required this.icon, required this.bgColor, required this.needsBorder}) : super(key: key); @override Widget build(BuildContext context) { return InkWell( onTap: onTap, child: Container( - height: 110, - decoration: BoxDecoration(color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)), + height: 80, + decoration: BoxDecoration(color: bgColor, border: needsBorder ? Border.all(width: 2, color: MyColors.darkPrimaryColor) : null), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index ddc205a..fa2654b 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -61,7 +61,7 @@ class SelectAdTypeView extends StatelessWidget { SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""), ); - Navigator.pushNamed(context, AppRoutes.createAdView); + showMyBottomSheet(context, child: const AdDurationSelectionSheetContent()); }, child: SizedBox( width: double.infinity, @@ -89,24 +89,19 @@ class SelectAdTypeView extends StatelessWidget { ], ).paddingOnly(top: 5, bottom: 5), ] else ...[ - InkWell( - onTap: () { - showMyBottomSheet(context, child: AdDurationSelectionSheetContent(vehicleType: vehicleTypeModel)); - }, - child: Row( - children: [ - "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - "7 Days".toText(fontSize: 13, isBold: true), - const Icon(Icons.keyboard_arrow_down_sharp, color: MyColors.darkPrimaryColor, size: 20), - ], - ).paddingOnly(top: 5, bottom: 5), - ), + Row( + children: [ + "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + adVM.vehicleAdDurationId.selectedOption.toText(fontSize: 13, isBold: true), + const Icon(Icons.keyboard_arrow_down_sharp, color: MyColors.darkPrimaryColor, size: 20), + ], + ).paddingOnly(top: 5, bottom: 5), ], if (!isProvider) ...[ Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - "1056".toText(fontSize: 22, isBold: true), + adVM.vehicleAdDurationId.itemPrice.toText(fontSize: 22, isBold: true), 2.width, Padding( padding: const EdgeInsets.only(bottom: 4), diff --git a/lib/widgets/txt_field.dart b/lib/widgets/txt_field.dart index 21537e9..37304a7 100644 --- a/lib/widgets/txt_field.dart +++ b/lib/widgets/txt_field.dart @@ -32,6 +32,7 @@ class TxtField extends StatelessWidget { TextInputType? keyboardType; bool isBackgroundEnabled = false; Widget? postfixWidget; + Widget? preFixWidget; TxtField({ Key? key, @@ -58,6 +59,7 @@ class TxtField extends StatelessWidget { this.keyboardType, this.isBackgroundEnabled = false, this.postfixWidget, + this.preFixWidget, this.onPostFixPressed, }) : super(key: key); @@ -84,6 +86,7 @@ class TxtField extends StatelessWidget { borderRadius: const BorderRadius.all(Radius.circular(0)), ), child: TextField( + style: const TextStyle(color: MyColors.darkTextColor), textInputAction: isSearchBar ? TextInputAction.search : null, keyboardType: keyboardType, autofocus: false, @@ -99,17 +102,17 @@ class TxtField extends StatelessWidget { alignLabelWithHint: true, fillColor: Colors.white, focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: MyColors.darkPrimaryColor, width: isNeedBorder ? 2.0 : 0), + borderSide: BorderSide(color: isNeedBorder ? MyColors.darkPrimaryColor : Colors.transparent, width: isNeedBorder ? 2.0 : 0), borderRadius: BorderRadius.circular(0.0), ), enabledBorder: OutlineInputBorder( // borderSide: BorderSide(color: MyColors.textFieldColor, width: isNeedBorder ? 1.0 : 0), - borderSide: BorderSide(color: MyColors.darkPrimaryColor, width: isNeedBorder ? 2.0 : 0), + borderSide: BorderSide(color: isNeedBorder ? MyColors.darkPrimaryColor : Colors.transparent, width: isNeedBorder ? 2.0 : 0), borderRadius: BorderRadius.circular(0.0), ), disabledBorder: OutlineInputBorder( // borderSide: BorderSide(color: MyColors.textFieldColor, width: isNeedBorder ? 1.0 : 0), - borderSide: BorderSide(color: MyColors.darkPrimaryColor, width: isNeedBorder ? 2.0 : 0), + borderSide: BorderSide(color: isNeedBorder ? MyColors.darkPrimaryColor : Colors.transparent, width: isNeedBorder ? 2.0 : 0), borderRadius: BorderRadius.circular(0.0), ), suffixIcon: postfixData != null @@ -117,8 +120,8 @@ class TxtField extends StatelessWidget { onTap: onPostFixPressed, child: Icon(postfixData, color: postFixDataColor), ) - : postfixWidget ?? null, - prefixIcon: prefixData != null ? const Icon(Icons.search, color: borderColor) : null, + : postfixWidget, + prefixIcon: prefixData != null ? Icon(prefixData, color: borderColor) : preFixWidget, labelStyle: TextStyle(color: borderColor, fontSize: 13.sp), hintStyle: TextStyle(color: borderColor, fontSize: 10.sp), hintText: hint ?? "", diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index e95be15..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,975 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - args: - dependency: transitive - description: - name: args - sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a - url: "https://pub.dev" - source: hosted - version: "2.4.1" - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - badges: - dependency: "direct main" - description: - name: badges - sha256: "6e7f3ec561ec08f47f912cfe349d4a1707afdc8dda271e17b046aa6d42c89e77" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 - url: "https://pub.dev" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 - url: "https://pub.dev" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 - url: "https://pub.dev" - source: hosted - version: "1.0.2" - carousel_slider: - dependency: "direct main" - description: - name: carousel_slider - sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" - url: "https://pub.dev" - source: hosted - version: "4.2.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" - url: "https://pub.dev" - source: hosted - version: "1.17.1" - cross_file: - dependency: transitive - description: - name: cross_file - sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" - url: "https://pub.dev" - source: hosted - version: "0.3.3+4" - crypto: - dependency: transitive - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.dev" - source: hosted - version: "1.0.5" - dropdown_button2: - dependency: "direct main" - description: - name: dropdown_button2 - sha256: "374f2390161bf782b4896f0b1b24cbb2b5daaa1cfb11047c3307461dcdf44e07" - url: "https://pub.dev" - source: hosted - version: "2.1.3" - easy_localization: - dependency: "direct main" - description: - name: easy_localization - sha256: "30ebf25448ffe169e0bd9bc4b5da94faa8398967a2ad2ca09f438be8b6953645" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - easy_logger: - dependency: transitive - description: - name: easy_logger - sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7 - url: "https://pub.dev" - source: hosted - version: "0.0.2" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 - url: "https://pub.dev" - source: hosted - version: "2.0.5" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18" - url: "https://pub.dev" - source: hosted - version: "1.2.1" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - file_picker: - dependency: "direct main" - description: - name: file_picker - sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f" - url: "https://pub.dev" - source: hosted - version: "4.6.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" - url: "https://pub.dev" - source: hosted - version: "3.3.0" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf - url: "https://pub.dev" - source: hosted - version: "5.7.2+3" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.dev" - source: hosted - version: "2.0.1" - flutter_localizations: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" - url: "https://pub.dev" - source: hosted - version: "1.1.6" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - sha256: "474f7d506230897a3cd28c965ec21c5328ae5605fc9c400cd330e9e9d6ac175c" - url: "https://pub.dev" - source: hosted - version: "8.2.2" - geolocator: - dependency: "direct main" - description: - name: geolocator - sha256: "5c23f3613f50586c0bbb2b8f970240ae66b3bd992088cf60dd5ee2e6f7dde3a8" - url: "https://pub.dev" - source: hosted - version: "9.0.2" - geolocator_android: - dependency: transitive - description: - name: geolocator_android - sha256: "6cd3c622df085a79fd61f5c14fa024c3ba593aa6b1df2ee809ac59f45e6a9861" - url: "https://pub.dev" - source: hosted - version: "4.1.8" - geolocator_apple: - dependency: transitive - description: - name: geolocator_apple - sha256: "22b60ca3b8c0f58e6a9688ff855ee39ab813ca3f0c0609a48d282f6631266f2e" - url: "https://pub.dev" - source: hosted - version: "2.2.5" - geolocator_platform_interface: - dependency: transitive - description: - name: geolocator_platform_interface - sha256: af4d69231452f9620718588f41acc4cb58312368716bfff2e92e770b46ce6386 - url: "https://pub.dev" - source: hosted - version: "4.0.7" - geolocator_web: - dependency: transitive - description: - name: geolocator_web - sha256: f68a122da48fcfff68bbc9846bb0b74ef651afe84a1b1f6ec20939de4d6860e1 - url: "https://pub.dev" - source: hosted - version: "2.1.6" - geolocator_windows: - dependency: transitive - description: - name: geolocator_windows - sha256: f5911c88e23f48b598dd506c7c19eff0e001645bdc03bb6fecb9f4549208354d - url: "https://pub.dev" - source: hosted - version: "0.1.1" - google_maps_flutter: - dependency: "direct main" - description: - name: google_maps_flutter - sha256: abefcb1e5e5c96bdd8084939dda555257af272c7972902ca46d5631092c1df68 - url: "https://pub.dev" - source: hosted - version: "2.2.8" - google_maps_flutter_android: - dependency: transitive - description: - name: google_maps_flutter_android - sha256: "9512c862df77c1f0fa5f445513dd3c57f5996f0a809dccb74e54b690ee4e3a0f" - url: "https://pub.dev" - source: hosted - version: "2.4.15" - google_maps_flutter_ios: - dependency: transitive - description: - name: google_maps_flutter_ios - sha256: a9462a433bf3ebe60aadcf4906d2d6341a270d69d3e0fcaa8eb2b64699fcfb4f - url: "https://pub.dev" - source: hosted - version: "2.2.3" - google_maps_flutter_platform_interface: - dependency: transitive - description: - name: google_maps_flutter_platform_interface - sha256: "308f0af138fa78e8224d598d46ca182673874d0ef4d754b7157c073b5b4b8e0d" - url: "https://pub.dev" - source: hosted - version: "2.2.7" - hexcolor: - dependency: "direct main" - description: - name: hexcolor - sha256: c07f4bbb9095df87eeca87e7c69e8c3d60f70c66102d7b8d61c4af0453add3f6 - url: "https://pub.dev" - source: hosted - version: "3.0.1" - http: - dependency: "direct main" - description: - name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.dev" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - image_picker: - dependency: "direct main" - description: - name: image_picker - sha256: "9978d3510af4e6a902e545ce19229b926e6de6a1828d6134d3aab2e129a4d270" - url: "https://pub.dev" - source: hosted - version: "0.8.7+5" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - sha256: c2f3c66400649bd132f721c88218945d6406f693092b2f741b79ae9cdb046e59 - url: "https://pub.dev" - source: hosted - version: "0.8.6+16" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c" - url: "https://pub.dev" - source: hosted - version: "2.1.12" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - sha256: d779210bda268a03b57e923fb1e410f32f5c5e708ad256348bcbf1f44f558fd0 - url: "https://pub.dev" - source: hosted - version: "0.8.7+4" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8" - url: "https://pub.dev" - source: hosted - version: "2.6.3" - injector: - dependency: "direct main" - description: - name: injector - sha256: "2a683124c716e93b45521794f55bfe770e069cb3d871fc4fbc65b5acef78e832" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - intl: - dependency: transitive - description: - name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 - url: "https://pub.dev" - source: hosted - version: "0.18.0" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - local_auth: - dependency: "direct main" - description: - name: local_auth - sha256: "0cf238be2bfa51a6c9e7e9cfc11c05ea39f2a3a4d3e5bb255d0ebc917da24401" - url: "https://pub.dev" - source: hosted - version: "2.1.6" - local_auth_android: - dependency: transitive - description: - name: local_auth_android - sha256: c5e48c4a67fc0e5dd9b5725cc8766b67e2da9a54155c82c6e2ea4a0d1cf9ef93 - url: "https://pub.dev" - source: hosted - version: "1.0.28" - local_auth_ios: - dependency: transitive - description: - name: local_auth_ios - sha256: edc2977c5145492f3451db9507a2f2f284ee4f408950b3e16670838726761940 - url: "https://pub.dev" - source: hosted - version: "1.1.3" - local_auth_platform_interface: - dependency: transitive - description: - name: local_auth_platform_interface - sha256: "9e160d59ef0743e35f1b50f4fb84dc64f55676b1b8071e319ef35e7f3bc13367" - url: "https://pub.dev" - source: hosted - version: "1.0.7" - local_auth_windows: - dependency: transitive - description: - name: local_auth_windows - sha256: "19323b75ab781d5362dbb15dcb7e0916d2431c7a6dbdda016ec9708689877f73" - url: "https://pub.dev" - source: hosted - version: "1.0.8" - logger: - dependency: "direct main" - description: - name: logger - sha256: db2ff852ed77090ba9f62d3611e4208a3d11dfa35991a81ae724c113fcb3e3f7 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" - url: "https://pub.dev" - source: hosted - version: "0.12.15" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - octo_image: - dependency: transitive - description: - name: octo_image - sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - path: - dependency: transitive - description: - name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" - url: "https://pub.dev" - source: hosted - version: "1.8.3" - path_drawing: - dependency: transitive - description: - name: path_drawing - sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 - url: "https://pub.dev" - source: hosted - version: "1.0.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf - url: "https://pub.dev" - source: hosted - version: "1.0.1" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" - url: "https://pub.dev" - source: hosted - version: "2.0.27" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" - url: "https://pub.dev" - source: hosted - version: "2.2.3" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 - url: "https://pub.dev" - source: hosted - version: "2.1.11" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905 - url: "https://pub.dev" - source: hosted - version: "2.0.7" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" - url: "https://pub.dev" - source: hosted - version: "10.2.0" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: d8cc6a62ded6d0f49c6eac337e080b066ee3bce4d405bd9439a61e1f1927bfe8 - url: "https://pub.dev" - source: hosted - version: "10.2.1" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85 - url: "https://pub.dev" - source: hosted - version: "9.0.8" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" - url: "https://pub.dev" - source: hosted - version: "3.9.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b - url: "https://pub.dev" - source: hosted - version: "0.1.2" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.dev" - source: hosted - version: "6.0.5" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.dev" - source: hosted - version: "0.27.7" - shared_preferences: - dependency: "direct main" - description: - name: shared_preferences - sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - shared_preferences_foundation: - dependency: transitive - description: - name: shared_preferences_foundation - sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb - url: "https://pub.dev" - source: hosted - version: "2.2.2" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" - url: "https://pub.dev" - source: hosted - version: "2.2.0" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d - url: "https://pub.dev" - source: hosted - version: "2.2.0" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" - url: "https://pub.dev" - source: hosted - version: "2.2.0" - shimmer: - dependency: "direct main" - description: - name: shimmer - sha256: "1f1009b5845a1f88f1c5630212279540486f97409e9fc3f63883e71070d107bf" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - sizer: - dependency: "direct main" - description: - name: sizer - sha256: d2b3cb6cbc4a637f508dacd786bae55df31e5fc088044248a43e4fd1e050c117 - url: "https://pub.dev" - source: hosted - version: "2.0.15" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9 - url: "https://pub.dev" - source: hosted - version: "2.2.8+4" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555 - url: "https://pub.dev" - source: hosted - version: "2.4.5" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb - url: "https://pub.dev" - source: hosted - version: "0.5.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" - universal_io: - dependency: transitive - description: - name: universal_io - sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" - url: "https://pub.dev" - source: hosted - version: "2.2.0" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3 - url: "https://pub.dev" - source: hosted - version: "6.1.11" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: eed4e6a1164aa9794409325c3b707ff424d4d1c2a785e7db67f8bbda00e36e51 - url: "https://pub.dev" - source: hosted - version: "6.0.35" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab" - url: "https://pub.dev" - source: hosted - version: "2.0.17" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - uuid: - dependency: transitive - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - win32: - dependency: transitive - description: - name: win32 - sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef - url: "https://pub.dev" - source: hosted - version: "2.6.1" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 - url: "https://pub.dev" - source: hosted - version: "1.0.0" - xml: - dependency: transitive - description: - name: xml - sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb - url: "https://pub.dev" - source: hosted - version: "6.1.0" -sdks: - dart: ">=3.0.0-0 <4.0.0" - flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index e328d29..ef7b31d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,7 @@ dependencies: carousel_slider: ^4.2.1 dropdown_button2: ^2.0.0 flutter_inappwebview: ^5.7.2+3 + country_code_picker: ^3.0.0 # google google_maps_flutter: ^2.1.1