From 0b7b12180604d78b4120bfb1a7cb867b4d923e40 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 4 Sep 2023 16:30:15 +0300 Subject: [PATCH] Added select_ad_type_view.dart --- assets/icons/vehicle_type_buggy.svg | 9 + assets/icons/vehicle_type_car.svg | 7 + assets/icons/vehicle_type_golf_cart.svg | 5 + assets/icons/vehicle_type_motorcycle.svg | 11 ++ lib/classes/consts.dart | 5 + lib/extensions/string_extensions.dart | 17 ++ .../vehicle_details_models.dart | 15 +- lib/utils/enums.dart | 8 + .../vehicle_details_container.dart | 34 ++-- .../ad_duration_selection_sheet_content.dart | 89 +++++++++ .../advertisement/select_ad_type_view.dart | 177 +++++++++++------- lib/widgets/extensions/extensions_widget.dart | 17 +- 12 files changed, 302 insertions(+), 92 deletions(-) create mode 100644 assets/icons/vehicle_type_buggy.svg create mode 100644 assets/icons/vehicle_type_car.svg create mode 100644 assets/icons/vehicle_type_golf_cart.svg create mode 100644 assets/icons/vehicle_type_motorcycle.svg create mode 100644 lib/views/advertisement/ad_duration_selection_sheet_content.dart diff --git a/assets/icons/vehicle_type_buggy.svg b/assets/icons/vehicle_type_buggy.svg new file mode 100644 index 0000000..fa95ab0 --- /dev/null +++ b/assets/icons/vehicle_type_buggy.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/vehicle_type_car.svg b/assets/icons/vehicle_type_car.svg new file mode 100644 index 0000000..008545c --- /dev/null +++ b/assets/icons/vehicle_type_car.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/vehicle_type_golf_cart.svg b/assets/icons/vehicle_type_golf_cart.svg new file mode 100644 index 0000000..18a1fd9 --- /dev/null +++ b/assets/icons/vehicle_type_golf_cart.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/vehicle_type_motorcycle.svg b/assets/icons/vehicle_type_motorcycle.svg new file mode 100644 index 0000000..c63fffd --- /dev/null +++ b/assets/icons/vehicle_type_motorcycle.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b1727c9..039f461 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -196,6 +196,11 @@ class MyAssets { static String icPhoneNumber = "${assetPath}icons/ic_phone_number.svg"; static String icStar = "${assetPath}icons/ic_star.svg"; + static String vehicleTypeBuggy = "${assetPath}icons/vehicle_type_buggy.svg"; + static String vehicleTypeCar = "${assetPath}icons/vehicle_type_car.svg"; + static String vehicleTypeGolfCart = "${assetPath}icons/vehicle_type_golf_cart.svg"; + static String vehicleTypeMotorcycle = "${assetPath}icons/vehicle_type_motorcycle.svg"; + //PNG static String icWorldPng = "${assetPath}images/ic_world.png"; static String bnIntroPng = "${assetPath}images/bn_Intro.png"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index b72d532..7bbd3c8 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/utils/enums.dart'; extension EmailValidator on String { Widget toText( @@ -246,3 +247,19 @@ extension DateTimeConversions on DateTime { } } } + +extension VehicleAdTypeEnum on int { + VehicleTypeEnum getVehicleTypeEnum() { + if (this == 1) { + return VehicleTypeEnum.car; + } else if (this == 2) { + return VehicleTypeEnum.motorCycle; + } else if (this == 3) { + return VehicleTypeEnum.golfCart; + } else if (this == 4) { + return VehicleTypeEnum.buggy; + } else { + return VehicleTypeEnum.car; + } + } +} diff --git a/lib/models/advertisment_models/vehicle_details_models.dart b/lib/models/advertisment_models/vehicle_details_models.dart index 60ff707..905e43b 100644 --- a/lib/models/advertisment_models/vehicle_details_models.dart +++ b/lib/models/advertisment_models/vehicle_details_models.dart @@ -1,5 +1,8 @@ import 'dart:developer'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/utils/enums.dart'; + class VehicleDetailsModel { List? vehicleBrands; List? vehicleCategories; @@ -56,14 +59,22 @@ class VehicleTypeModel { String? vehicleTypeName; String? vehicleTypeNameN; bool? isActive; - - VehicleTypeModel({this.id, this.vehicleTypeName, this.vehicleTypeNameN, this.isActive}); + VehicleTypeEnum? vehicleTypeEnum; + + VehicleTypeModel({ + this.id, + this.vehicleTypeName, + this.vehicleTypeNameN, + this.isActive, + this.vehicleTypeEnum = VehicleTypeEnum.car, + }); VehicleTypeModel.fromJson(Map json) { id = json['id']; vehicleTypeName = json['vehicleTypeName']; vehicleTypeNameN = json['vehicleTypeNameN']; isActive = json['isActive']; + vehicleTypeEnum = (json['id'] as int).getVehicleTypeEnum(); } Map toJson() { diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index dc9e841..4b2e27c 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -5,6 +5,14 @@ // unverified, // } + +enum VehicleTypeEnum { + car, + motorCycle, + golfCart, + buggy, +} + enum AdPostStatus { pendingForReview, pendingForPayment, 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 173a777..4abb845 100644 --- a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart +++ b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart @@ -24,26 +24,26 @@ 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", - ); - }, - ), + // 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) ...[ if (adVM.isFetchingLists) ...[ - Row( + const Row( mainAxisAlignment: MainAxisAlignment.center, - children: const [ + children: [ CircularProgressIndicator(), ], ).paddingAll(10), diff --git a/lib/views/advertisement/ad_duration_selection_sheet_content.dart b/lib/views/advertisement/ad_duration_selection_sheet_content.dart new file mode 100644 index 0000000..5e2b576 --- /dev/null +++ b/lib/views/advertisement/ad_duration_selection_sheet_content.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.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/theme/colors.dart'; +import 'package:mc_common_app/widgets/extensions/extensions_widget.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}); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: MediaQuery.of(context).size.height / 1.2, + child: Column( + children: [ + Row( + children: [ + "Select Duration".toText(fontSize: 22, isBold: true).paddingOnly(top: 10, left: 21, right: 21), + ], + ), + Expanded( + child: ListView.separated( + shrinkWrap: true, + itemCount: 5, + itemBuilder: (BuildContext context, int index) { + return SizedBox( + width: double.infinity, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "7 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( + fontSize: 14, + color: MyColors.lightTextColor, + ), + 12.height, + "Ad Charges".toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "300".toText(fontSize: 22, isBold: true), + 2.width, + Padding( + padding: const EdgeInsets.only(bottom: 4), + child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + ), + ], + ), + ], + ), + ), + ], + ).toWhiteContainer(width: double.infinity, allPading: 12, isBorderRequired: index == 0 ? true : false), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return 12.height; + }, + padding: const EdgeInsets.all(20), + ), + ), + ], + ), + ); + } + + Widget showItem(String item, String value, {Color valueColor = Colors.black}) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + 4.width, + value.toText(fontSize: 12, color: valueColor, isBold: true), + ], + ); + } +} diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 93959f1..ddc205a 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -1,14 +1,18 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.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/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; +import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart'; +import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; -import 'package:sizer/sizer.dart'; class SelectAdTypeView extends StatelessWidget { final bool isProvider; @@ -18,6 +22,22 @@ class SelectAdTypeView extends StatelessWidget { this.isProvider = true, }) : super(key: key); + Widget getVehicleAdTypeIcon(VehicleTypeEnum vehicleTypeEnum) { + switch (vehicleTypeEnum) { + case VehicleTypeEnum.car: + return MyAssets.vehicleTypeCar.buildSvg(height: 22); + + case VehicleTypeEnum.motorCycle: + return MyAssets.vehicleTypeMotorcycle.buildSvg(height: 26); + + case VehicleTypeEnum.golfCart: + return MyAssets.vehicleTypeGolfCart.buildSvg(height: 26); + + case VehicleTypeEnum.buggy: + return MyAssets.vehicleTypeBuggy.buildSvg(height: 26); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -35,42 +55,73 @@ class SelectAdTypeView extends StatelessWidget { itemCount: adVM.vehicleTypes.length, itemBuilder: (BuildContext context, int index) { VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index]; - return SizedBox( - width: double.infinity, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - vehicleTypeModel.vehicleTypeName.toString().toText(fontSize: 16, isBold: true), - 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), + return InkWell( + onTap: () { + adVM.updateSelectionVehicleTypeId( + SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""), + ); + + Navigator.pushNamed(context, AppRoutes.createAdView); + }, + child: SizedBox( + width: double.infinity, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + vehicleTypeModel.vehicleTypeName.toString().toText(fontSize: 18, isBold: true), + getVehicleAdTypeIcon(vehicleTypeModel.vehicleTypeEnum!), + ], + ), + if (isProvider) ...[ + Row( + children: [ + "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + "Valid Until Subscription Expiration".toText(fontSize: 13, isBold: true), + ], + ).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), + ), ], - ).paddingOnly(top: 5, bottom: 5), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "1056".toText(fontSize: 22, isBold: true), - 2.width, - Padding( - padding: const EdgeInsets.only(bottom: 4), - child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + if (!isProvider) ...[ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "1056".toText(fontSize: 22, isBold: true), + 2.width, + Padding( + padding: const EdgeInsets.only(bottom: 4), + child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + ), + ], ), ], - ), - ], + ], + ), ), - ), - ], - ), - ).toWhiteContainer(width: double.infinity, allPading: 10); + ], + ), + ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.symmetric(horizontal: 20, vertical: 10)), + ); }, separatorBuilder: (BuildContext context, int index) { return 9.height; @@ -80,40 +131,38 @@ class SelectAdTypeView extends StatelessWidget { }), ), if (isProvider) ...[ - SizedBox( - height: 12.h, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + "5 of 10 ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1), + "Ads Remaining ".toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), + ], + ), + const Text.rich( + TextSpan( children: [ - "5 of 10 ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1), - "Ads Remaining ".toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), + TextSpan( + text: "You have left with 05 out of 50 ads given in the subscription. ", + style: TextStyle( + fontSize: 14, + color: MyColors.lightTextColor, + )), + TextSpan( + text: "Update Subscription", + style: TextStyle( + decoration: TextDecoration.underline, + fontSize: 14, + fontWeight: FontWeight.w600, + color: MyColors.darkPrimaryColor, + )) ], ), - const Text.rich( - TextSpan( - children: [ - TextSpan( - text: "You have left with 05 out of 50 ads given in the subscription. ", - style: TextStyle( - fontSize: 14, - color: MyColors.lightTextColor, - )), - TextSpan( - text: "Update Subscription", - style: TextStyle( - decoration: TextDecoration.underline, - fontSize: 14, - fontWeight: FontWeight.w600, - color: MyColors.darkPrimaryColor, - )) - ], - ), - ) - ], - ).toContainer(paddingAll: 20, backgroundColor: Colors.white), - ), + ), + 10.height, + ], + ).toContainer(paddingAll: 20, backgroundColor: Colors.white), ] ], ), diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart index ab7487b..31164a2 100644 --- a/lib/widgets/extensions/extensions_widget.dart +++ b/lib/widgets/extensions/extensions_widget.dart @@ -23,11 +23,12 @@ extension ExtendedText on Widget { } extension ContainerExt on Widget { - Widget toWhiteContainer({required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor}) { + Widget toWhiteContainer({required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false}) { return InkWell( onTap: onTap, child: Container( decoration: BoxDecoration( + border: isBorderRequired ? Border.all(color: MyColors.darkPrimaryColor, width: 2) : null, color: backgroundColor ?? MyColors.white, boxShadow: const [ BoxShadow( @@ -75,12 +76,12 @@ extension ContainerExt on Widget { boxShadow: !isShadowEnabled ? null : [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], ), padding: padding ?? EdgeInsets.all(paddingAll), margin: margin ?? EdgeInsets.all(marginAll), @@ -354,5 +355,3 @@ extension LocaleSetup on MultiProvider { extension WidgetExtensions on Widget { Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); } - -