From 6d82a6058826d24a3a911306e79143e9fef7f276 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Wed, 14 Jun 2023 14:41:31 +0300 Subject: [PATCH 01/12] Updated Minor changes! --- lib/classes/consts.dart | 1 + lib/config/routes.dart | 7 ++++++- lib/views/advertisement/bottom_sheet_content.dart | 1 + lib/views/user/login_with_password_page.dart | 3 ++- lib/widgets/checkbox_with_title_desc.dart | 8 ++++---- lib/widgets/common_widgets/time_slots.dart | 2 ++ 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index dfcd6c6..1884e63 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -119,6 +119,7 @@ class GlobalConsts { static String attachDamagePartImage = "Please add part image"; static String adDurationDateError = "Ad Duration start date cannot be empty"; static String adReservablePriceErrorConst = "Ad Reservable price cannot be empty"; + static String homeLocationEmptyError = "Home location cannot be empty"; static String reserveAdPriceInfo = "Some dummy description to explain the following concept. This price will be for 24 hours and if a user cancels the reservations before 24 hours then the amount will be automatically refunded to the buyer."; } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index a32a7b2..ba6f03b 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -56,10 +56,14 @@ class AppRoutes { static const String adsDetailView = "/adsDetailView"; static const String createAdView = "/createAdView"; static const String bookAppointmenServicesView = "/bookAppointmenServicesView"; + static const String bookAppointmentsItemView = "/bookAppointmentsItemView"; + + + // Payments static const String paymentMethodsView = "/paymentMethodsView"; - //Subcriptions + // Subcriptions static final String mySubscriptionsPage = "/mySubscriptionsPage"; static final String subscriptionsPage = "/subscriptionsPage"; @@ -84,5 +88,6 @@ class AppRoutes { changeMobilePage: (context) => ChangeMobilePage(), changeEmailPage: (context) => const ChangeEmailPage(), editAccountPage: (context) => EditAccountPage(), + }; } diff --git a/lib/views/advertisement/bottom_sheet_content.dart b/lib/views/advertisement/bottom_sheet_content.dart index f3eade5..61d74f9 100644 --- a/lib/views/advertisement/bottom_sheet_content.dart +++ b/lib/views/advertisement/bottom_sheet_content.dart @@ -273,6 +273,7 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget { 8.height, BuildTimeSlots( timeSlots: adVM.adSSTimeSlots, + onPressed: (index) => adVM.updateIsSelectedInSlots(index), ), ], diff --git a/lib/views/user/login_with_password_page.dart b/lib/views/user/login_with_password_page.dart index 16204a9..c3d4005 100644 --- a/lib/views/user/login_with_password_page.dart +++ b/lib/views/user/login_with_password_page.dart @@ -28,7 +28,8 @@ class _LoginWithPasswordState extends State { int otpType = 1; ClassType type = ClassType.EMAIL; - String phoneNum = "580816976", password = "123@Shf"; + //TODO: ONLY FOR DEVELOPMENT PURPOSE + String phoneNum = "966504278212", password = "Fa@123"; String email = ""; String countryCode = ""; Country? _country; diff --git a/lib/widgets/checkbox_with_title_desc.dart b/lib/widgets/checkbox_with_title_desc.dart index 99088aa..5419254 100644 --- a/lib/widgets/checkbox_with_title_desc.dart +++ b/lib/widgets/checkbox_with_title_desc.dart @@ -3,11 +3,11 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/theme/colors.dart'; class CheckBoxWithTitleDescription extends StatelessWidget { - bool isSelected; - String title, description; - Function(bool) onSelection; + final bool isSelected; + final String title, description; + final Function(bool) onSelection; - CheckBoxWithTitleDescription({required this.isSelected, required this.title, required this.description, required this.onSelection, Key? key}) : super(key: key); + const CheckBoxWithTitleDescription({required this.isSelected, required this.title, required this.description, required this.onSelection, Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/widgets/common_widgets/time_slots.dart b/lib/widgets/common_widgets/time_slots.dart index 0514d69..9e56974 100644 --- a/lib/widgets/common_widgets/time_slots.dart +++ b/lib/widgets/common_widgets/time_slots.dart @@ -15,8 +15,10 @@ class BuildTimeSlots extends StatelessWidget { height: 37, width: double.infinity, child: ListView.builder( + physics: const BouncingScrollPhysics(), itemCount: timeSlots.length, scrollDirection: Axis.horizontal, + shrinkWrap: true, itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () { From b14e0020dc9d76fd3426d317f547b6c8056077bc Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Wed, 14 Jun 2023 15:18:11 +0300 Subject: [PATCH 02/12] Updated Minor changes! --- lib/main.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index f2d9ecf..7ea71be 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,6 +9,8 @@ import 'package:provider/provider.dart'; import 'package:provider/single_child_widget.dart'; import 'package:sizer/sizer.dart'; + +//testing push final navigatorKey = GlobalKey(); Logger logger = Logger( From 967c522f60f211508756096bb9bc7978817dc329 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Sun, 18 Jun 2023 17:08:54 +0300 Subject: [PATCH 03/12] Updated Minor changes! --- lib/config/routes.dart | 1 + .../ad_creation_steps/ad_duration_container.dart | 16 +++++++++++----- .../common_widgets/info_bottom_sheet.dart | 14 ++++---------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/config/routes.dart b/lib/config/routes.dart index ba6f03b..f5a2876 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -57,6 +57,7 @@ class AppRoutes { static const String createAdView = "/createAdView"; static const String bookAppointmenServicesView = "/bookAppointmenServicesView"; static const String bookAppointmentsItemView = "/bookAppointmentsItemView"; + static const String reviewAppointmentView = "/reviewAppointmentView"; // Payments 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 b8a733e..c2930d8 100644 --- a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart +++ b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart @@ -33,7 +33,16 @@ class AdDuration extends StatelessWidget { isScrollControlled: true, enableDrag: true, builder: (BuildContext context) { - return InfoBottomSheet(title: "Reserve Ad Price Info", description: GlobalConsts.reserveAdPriceInfo); + return InfoBottomSheet( + title: "Reserve Ad Price Info", + description: Flexible( + child: GlobalConsts.reserveAdPriceInfo.toText( + textAlign: TextAlign.justify, + fontSize: 16, + color: MyColors.lightTextColor, + isBold: false, + )), + ); }); } @@ -75,7 +84,6 @@ class AdDuration extends StatelessWidget { adVM.updateSelectionDurationStartDate(formattedDate); }, ), - ], ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)), Column( @@ -100,9 +108,7 @@ class AdDuration extends StatelessWidget { TxtField( postfixData: Icons.info_outline_rounded, postFixDataColor: MyColors.grey77Color, - onPostFixPressed: () { - reservePriceInfoClicked(context); - }, + onPostFixPressed: () => reservePriceInfoClicked(context), value: adVM.adReserveAmount, errorValue: adVM.adReservePriceError, keyboardType: TextInputType.number, diff --git a/lib/widgets/common_widgets/info_bottom_sheet.dart b/lib/widgets/common_widgets/info_bottom_sheet.dart index 26b81a4..5c0d6c4 100644 --- a/lib/widgets/common_widgets/info_bottom_sheet.dart +++ b/lib/widgets/common_widgets/info_bottom_sheet.dart @@ -6,14 +6,14 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; class InfoBottomSheet extends StatelessWidget { final String title; - final String description; + final Widget description; const InfoBottomSheet({Key? key, required this.title, required this.description}) : super(key: key); @override Widget build(BuildContext context) { - return SizedBox( - height: MediaQuery.of(context).size.height * 0.4, + return SingleChildScrollView( + // height: MediaQuery.of(context).size.height * 0.35, child: Column( children: [ Container( @@ -30,13 +30,7 @@ class InfoBottomSheet extends StatelessWidget { ], ), 8.height, - Flexible( - child: description.toText( - textAlign: TextAlign.justify, - fontSize: 16, - color: MyColors.lightTextColor, - isBold: true, - )), + description, ], ).horPaddingMain()); } From 6acbcc7e1d5dbef92a70488bc6ba34b0e3efe0f8 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Wed, 21 Jun 2023 11:00:12 +0300 Subject: [PATCH 04/12] Merged Code --- lib/models/model/provider_model.dart | 87 ------------------- .../branch_detail_model.dart} | 8 +- .../profile/branch.dart | 0 .../profile/categroy.dart | 2 +- .../profile/document.dart | 0 .../profile/services.dart | 34 ++++---- .../provider_profile_model.dart | 53 +++++++++++ lib/models/services/near_branch_model.dart | 39 --------- 8 files changed, 75 insertions(+), 148 deletions(-) delete mode 100644 lib/models/model/provider_model.dart rename lib/models/{services/branch_model.dart => provider_branches_models/branch_detail_model.dart} (91%) rename lib/models/{ => provider_branches_models}/profile/branch.dart (100%) rename lib/models/{ => provider_branches_models}/profile/categroy.dart (96%) rename lib/models/{ => provider_branches_models}/profile/document.dart (100%) rename lib/models/{ => provider_branches_models}/profile/services.dart (52%) create mode 100644 lib/models/provider_branches_models/provider_profile_model.dart delete mode 100644 lib/models/services/near_branch_model.dart diff --git a/lib/models/model/provider_model.dart b/lib/models/model/provider_model.dart deleted file mode 100644 index a406509..0000000 --- a/lib/models/model/provider_model.dart +++ /dev/null @@ -1,87 +0,0 @@ -// To parse this JSON data, do -// -// final branch2 = branch2FromJson(jsonString); - -import 'dart:convert'; - -import 'package:mc_common_app/models/profile/categroy.dart'; -import 'package:mc_common_app/models/services/branch_model.dart'; - -ProviderModel branch2FromJson(String str) => ProviderModel.fromJson(json.decode(str)); - -String branch2ToJson(ProviderModel data) => json.encode(data.toJson()); - -class ProviderModel { - ProviderModel({ - this.messageStatus, - this.totalItemsCount, - this.data, - this.message, - }); - - final int? messageStatus; - final int? totalItemsCount; - final ProviderModelData? data; - final String? message; - - factory ProviderModel.fromJson(Map json) => ProviderModel( - messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], - totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], - data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]), - message: json["message"] == null ? null : json["message"], - ); - - Map toJson() => { - "messageStatus": messageStatus == null ? null : messageStatus, - "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, - "data": data == null ? null : data!.toJson(), - "message": message == null ? null : message, - }; -} - -class ProviderModelData { - ProviderModelData({ - this.id, - this.companyName, - this.countryName, - this.companyDescription, - this.allDocStatus, - this.isValidSubscription, - this.userId, - this.serviceProviderBranch, - this.countryID, - }); - - final int? id; - final String? companyName; - final String? countryName; - int? countryID; - final String? companyDescription; - final int? allDocStatus; - final bool? isValidSubscription; - final String? userId; - final List? serviceProviderBranch; - - factory ProviderModelData.fromJson(Map json) => ProviderModelData( - id: json["id"] == null ? null : json["id"], - companyName: json["companyName"] == null ? null : json["companyName"], - countryName: json["countryName"] == null ? null : json["countryName"], - countryID: json["countryID"] == null ? null : json["countryID"], - companyDescription: json["companyDescription"] == null ? null : json["companyDescription"], - allDocStatus: json["allDocStatus"] == null ? null : json["allDocStatus"], - isValidSubscription: json["isValidSubscription"] == null ? null : json["isValidSubscription"], - userId: json["userID"] == null ? null : json["userID"], - serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List.from(json["serviceProviderBranch"].map((x) => BranchModel.fromJson(x))), - ); - - Map toJson() => { - "id": id == null ? null : id, - "companyName": companyName == null ? null : companyName, - "companyDescription": companyDescription == null ? null : companyDescription, - "allDocStatus": allDocStatus == null ? null : allDocStatus, - "isValidSubscription": isValidSubscription == null ? null : isValidSubscription, - "userID": userId == null ? null : userId, - "serviceProviderBranch": serviceProviderBranch == null ? null : List.from(serviceProviderBranch!.map((x) => x.toJson())), - }; -} - diff --git a/lib/models/services/branch_model.dart b/lib/models/provider_branches_models/branch_detail_model.dart similarity index 91% rename from lib/models/services/branch_model.dart rename to lib/models/provider_branches_models/branch_detail_model.dart index df56c35..8b93ec2 100644 --- a/lib/models/services/branch_model.dart +++ b/lib/models/provider_branches_models/branch_detail_model.dart @@ -1,7 +1,7 @@ -import 'package:mc_common_app/models/profile/categroy.dart'; +import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/services/service_model.dart'; -class BranchModel { +class BranchDetailModel { final int? id; final int? serviceProviderId; final String? serviceProviderName; @@ -20,7 +20,7 @@ class BranchModel { List? categories; bool isExpanded; - BranchModel({ + BranchDetailModel({ this.id, this.serviceProviderId, this.serviceProviderName, @@ -40,7 +40,7 @@ class BranchModel { required this.isExpanded, }); - factory BranchModel.fromJson(Map json) => BranchModel( + factory BranchDetailModel.fromJson(Map json) => BranchDetailModel( id: json["id"], serviceProviderId: json["serviceProviderID"], serviceProviderName: json["serviceProviderName"], diff --git a/lib/models/profile/branch.dart b/lib/models/provider_branches_models/profile/branch.dart similarity index 100% rename from lib/models/profile/branch.dart rename to lib/models/provider_branches_models/profile/branch.dart diff --git a/lib/models/profile/categroy.dart b/lib/models/provider_branches_models/profile/categroy.dart similarity index 96% rename from lib/models/profile/categroy.dart rename to lib/models/provider_branches_models/profile/categroy.dart index 0c7bf26..33feaae 100644 --- a/lib/models/profile/categroy.dart +++ b/lib/models/provider_branches_models/profile/categroy.dart @@ -5,7 +5,7 @@ import 'dart:convert'; import 'package:equatable/equatable.dart'; -import 'package:mc_common_app/models/model/provider_model.dart'; +import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/services/service_model.dart'; Category categoryFromJson(String str) => Category.fromJson(json.decode(str)); diff --git a/lib/models/profile/document.dart b/lib/models/provider_branches_models/profile/document.dart similarity index 100% rename from lib/models/profile/document.dart rename to lib/models/provider_branches_models/profile/document.dart diff --git a/lib/models/profile/services.dart b/lib/models/provider_branches_models/profile/services.dart similarity index 52% rename from lib/models/profile/services.dart rename to lib/models/provider_branches_models/profile/services.dart index 1d3d7ec..d457b4d 100644 --- a/lib/models/profile/services.dart +++ b/lib/models/provider_branches_models/profile/services.dart @@ -23,18 +23,18 @@ class Services { factory Services.fromJson(Map json) => Services( - totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + totalItemsCount: json["totalItemsCount"], data: json["data"] == null ? null : List.from(json["data"].map((x) => ServicesData.fromJson(x))), - messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], - message: json["message"] == null ? null : json["message"], + messageStatus: json["messageStatus"], + message: json["message"], ); Map toJson() => { - "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "totalItemsCount": totalItemsCount, "data": data == null ? null : List.from(data!.map((x) => x.toJson())), - "messageStatus": messageStatus == null ? null : messageStatus, - "message": message == null ? null : message, + "messageStatus": messageStatus, + "message": message, }; } @@ -61,24 +61,24 @@ class ServicesData { factory ServicesData.fromJson(Map json) => ServicesData( - id: json["id"] == null ? null : json["id"], - description: json["description"] == null ? (json["serviceDescription"] == null ? null : json["serviceDescription"]) : json["description"], - descriptionN: json["descriptionN"] == null ? (json["serviceDescriptionN"] == null ? null : json["serviceDescriptionN"]) : json["descriptionN"], - serviceIconUrl: json["serviceIconUrl"] == null ? null : json["serviceIconUrl"], - serviceImageUrl: json["serviceImageUrl"] == null ? null : json["serviceImageUrl"], - serviceCategoryId: json["serviceCategoryID"] == null ? null : json["serviceCategoryID"], - categoryName: json["categoryName"] == null ? null : json["categoryName"], + id: json["id"], + description: json["description"] ?? (json["serviceDescription"]), + descriptionN: json["descriptionN"] ?? (json["serviceDescriptionN"]), + serviceIconUrl: json["serviceIconUrl"], + serviceImageUrl: json["serviceImageUrl"], + serviceCategoryId: json["serviceCategoryID"], + categoryName: json["categoryName"], isSelected: false, ); Map toJson() => { - "id": id == null ? null : id, - "description": description == null ? null : description, - "descriptionN": descriptionN == null ? null : descriptionN, + "id": id, + "description": description, + "descriptionN": descriptionN, "serviceIconUrl": serviceIconUrl, "serviceImageUrl": serviceImageUrl, - "serviceCategoryID": serviceCategoryId == null ? null : serviceCategoryId, + "serviceCategoryID": serviceCategoryId, "categoryName": categoryName, }; } diff --git a/lib/models/provider_branches_models/provider_profile_model.dart b/lib/models/provider_branches_models/provider_profile_model.dart new file mode 100644 index 0000000..10a845f --- /dev/null +++ b/lib/models/provider_branches_models/provider_profile_model.dart @@ -0,0 +1,53 @@ +// To parse this JSON data, do +// +// final branch2 = branch2FromJson(jsonString); + +import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; + + +class ProviderProfileModel { + ProviderProfileModel({ + this.id, + this.companyName, + this.countryName, + this.companyDescription, + this.allDocStatus, + this.isValidSubscription, + this.userId, + this.serviceProviderBranch, + this.countryID, + }); + + final int? id; + final String? companyName; + final String? countryName; + int? countryID; + final String? companyDescription; + final int? allDocStatus; + final bool? isValidSubscription; + final String? userId; + final List? serviceProviderBranch; + + factory ProviderProfileModel.fromJson(Map json) => ProviderProfileModel( + id: json["id"], + companyName: json["companyName"], + countryName: json["countryName"], + countryID: json["countryID"], + companyDescription: json["companyDescription"], + allDocStatus: json["allDocStatus"], + isValidSubscription: json["isValidSubscription"], + userId: json["userID"], + serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))), + ); + + Map toJson() => { + "id": id, + "companyName": companyName, + "companyDescription": companyDescription, + "allDocStatus": allDocStatus, + "isValidSubscription": isValidSubscription, + "userID": userId, + "serviceProviderBranch": serviceProviderBranch == null ? null : List.from(serviceProviderBranch!.map((x) => x.toJson())), + }; +} + diff --git a/lib/models/services/near_branch_model.dart b/lib/models/services/near_branch_model.dart deleted file mode 100644 index 93d9cd6..0000000 --- a/lib/models/services/near_branch_model.dart +++ /dev/null @@ -1,39 +0,0 @@ -// To parse this JSON data, do -// -// final nearBrancheModel = nearBrancheModelFromJson(jsonString); - -import 'dart:convert'; - -import 'branch_model.dart'; - -NearBrancheModel nearBrancheModelFromJson(String str) => NearBrancheModel.fromJson(json.decode(str)); - -String nearBrancheModelToJson(NearBrancheModel data) => json.encode(data.toJson()); - -class NearBrancheModel { - final int? messageStatus; - final int? totalItemsCount; - final List? data; - final String? message; - - NearBrancheModel({ - this.messageStatus, - this.totalItemsCount, - this.data, - this.message, - }); - - factory NearBrancheModel.fromJson(Map json) => NearBrancheModel( - messageStatus: json["messageStatus"], - totalItemsCount: json["totalItemsCount"], - data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => BranchModel.fromJson(x))), - message: json["message"], - ); - - Map toJson() => { - "messageStatus": messageStatus, - "totalItemsCount": totalItemsCount, - "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), - "message": message, - }; -} From 23ebbcb74bb2b596b7d176871447ae3f790c56b8 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Sun, 16 Jul 2023 09:40:46 +0300 Subject: [PATCH 05/12] Updated Code --- .../branch_detail_model.dart | 6 +- .../profile/categroy.dart | 4 +- lib/models/provider_category_model.dart | 64 ++++----- lib/models/provider_service_model.dart | 130 +++++++++--------- ...e_model.dart => branch_service_model.dart} | 6 +- lib/models/services/item_model.dart | 42 +----- lib/repositories/common_repo.dart | 48 +++---- .../common_widgets/provider_details_card.dart | 4 +- 8 files changed, 130 insertions(+), 174 deletions(-) rename lib/models/services/{service_model.dart => branch_service_model.dart} (94%) diff --git a/lib/models/provider_branches_models/branch_detail_model.dart b/lib/models/provider_branches_models/branch_detail_model.dart index 8b93ec2..1c08508 100644 --- a/lib/models/provider_branches_models/branch_detail_model.dart +++ b/lib/models/provider_branches_models/branch_detail_model.dart @@ -1,5 +1,5 @@ import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services/branch_service_model.dart'; class BranchDetailModel { final int? id; @@ -16,7 +16,7 @@ class BranchDetailModel { final String? closeTime; final int? status; final dynamic statusText; - final List? branchServices; + final List? branchServices; List? categories; bool isExpanded; @@ -55,7 +55,7 @@ class BranchDetailModel { closeTime: json["closeTime"], status: json["status"], statusText: json["statusText"], - branchServices: json["serviceProviderServices"] == null ? [] : List.from(json["serviceProviderServices"]!.map((x) => ServiceModel.fromJson(x))), + branchServices: json["serviceProviderServices"] == null ? [] : List.from(json["serviceProviderServices"]!.map((x) => BranchServiceModel.fromJson(x))), categories: [], isExpanded: false, ); diff --git a/lib/models/provider_branches_models/profile/categroy.dart b/lib/models/provider_branches_models/profile/categroy.dart index 33feaae..c62cd9b 100644 --- a/lib/models/provider_branches_models/profile/categroy.dart +++ b/lib/models/provider_branches_models/profile/categroy.dart @@ -6,7 +6,7 @@ import 'dart:convert'; import 'package:equatable/equatable.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services/branch_service_model.dart'; Category categoryFromJson(String str) => Category.fromJson(json.decode(str)); @@ -60,7 +60,7 @@ class CategoryData extends Equatable { dynamic? serviceCategoryImageUrl; String? branchId; String? branchName; - List? services; + List? services; factory CategoryData.fromJson(Map json) => CategoryData( id: json["id"] == null ? null : json["id"], diff --git a/lib/models/provider_category_model.dart b/lib/models/provider_category_model.dart index 2c6ae13..18c8dda 100644 --- a/lib/models/provider_category_model.dart +++ b/lib/models/provider_category_model.dart @@ -1,32 +1,32 @@ -class ProviderCategoryModel { - int? id; - String? categoryName; - String? categoryNameN; - String? serviceCategoryIconUrl; - String? serviceCategoryImageUrl; - bool? isActive; - bool? isSelected; - - ProviderCategoryModel({this.id, this.categoryName, this.categoryNameN, this.serviceCategoryIconUrl, this.serviceCategoryImageUrl, this.isActive, this.isSelected = false}); - - ProviderCategoryModel.fromJson(Map json) { - id = json['id']; - categoryName = json['categoryName']; - categoryNameN = json['categoryNameN']; - serviceCategoryIconUrl = json['serviceCategoryIconUrl']; - serviceCategoryImageUrl = json['serviceCategoryImageUrl']; - isActive = json['isActive']; - isSelected = false; - } - - Map toJson() { - final Map data = {}; - data['id'] = id; - data['categoryName'] = categoryName; - data['categoryNameN'] = categoryNameN; - data['serviceCategoryIconUrl'] = serviceCategoryIconUrl; - data['serviceCategoryImageUrl'] = serviceCategoryImageUrl; - data['isActive'] = isActive; - return data; - } -} +// class ProviderCategoryModel { +// int? id; +// String? categoryName; +// String? categoryNameN; +// String? serviceCategoryIconUrl; +// String? serviceCategoryImageUrl; +// bool? isActive; +// bool? isSelected; +// +// ProviderCategoryModel({this.id, this.categoryName, this.categoryNameN, this.serviceCategoryIconUrl, this.serviceCategoryImageUrl, this.isActive, this.isSelected = false}); +// +// ProviderCategoryModel.fromJson(Map json) { +// id = json['id']; +// categoryName = json['categoryName']; +// categoryNameN = json['categoryNameN']; +// serviceCategoryIconUrl = json['serviceCategoryIconUrl']; +// serviceCategoryImageUrl = json['serviceCategoryImageUrl']; +// isActive = json['isActive']; +// isSelected = false; +// } +// +// Map toJson() { +// final Map data = {}; +// data['id'] = id; +// data['categoryName'] = categoryName; +// data['categoryNameN'] = categoryNameN; +// data['serviceCategoryIconUrl'] = serviceCategoryIconUrl; +// data['serviceCategoryImageUrl'] = serviceCategoryImageUrl; +// data['isActive'] = isActive; +// return data; +// } +// } diff --git a/lib/models/provider_service_model.dart b/lib/models/provider_service_model.dart index 4875675..914ce65 100644 --- a/lib/models/provider_service_model.dart +++ b/lib/models/provider_service_model.dart @@ -1,65 +1,65 @@ -class ProviderServiceModel { - int? id; - String? description; - String? descriptionN; - String? serviceIconUrl; - String? serviceImageUrl; - int? serviceCategoryID; - bool? isActive; - String? categoryName; - bool? ispartial; - int? appointmentPricePercentage; - int? refundAmountPercentage; - bool? isSelected; - - ProviderServiceModel( - {this.id, - this.description, - this.descriptionN, - this.serviceIconUrl, - this.serviceImageUrl, - this.serviceCategoryID, - this.isActive, - this.categoryName, - this.ispartial, - this.appointmentPricePercentage, - this.refundAmountPercentage, - this.isSelected = false, - }); - - ProviderServiceModel.fromJson(Map json) { - id = json['id']; - description = json['description']; - descriptionN = json['descriptionN']; - serviceIconUrl = json['serviceIconUrl']; - serviceImageUrl = json['serviceImageUrl']; - serviceCategoryID = json['serviceCategoryID']; - isActive = json['isActive']; - categoryName = json['categoryName']; - ispartial = json['ispartial']; - appointmentPricePercentage = json['appointmentPricePercentage']; - refundAmountPercentage = json['refundAmountPercentage']; - isSelected = false; - } - - Map toJson() { - final Map data = {}; - data['id'] = id; - data['description'] = description; - data['descriptionN'] = descriptionN; - data['serviceIconUrl'] = serviceIconUrl; - data['serviceImageUrl'] = serviceImageUrl; - data['serviceCategoryID'] = serviceCategoryID; - data['isActive'] = isActive; - data['categoryName'] = categoryName; - data['ispartial'] = ispartial; - data['appointmentPricePercentage'] = appointmentPricePercentage; - data['refundAmountPercentage'] = refundAmountPercentage; - return data; - } - - @override - String toString() { - return 'ProviderServiceModel{id: $id, description: $description, descriptionN: $descriptionN, serviceIconUrl: $serviceIconUrl, serviceImageUrl: $serviceImageUrl, serviceCategoryID: $serviceCategoryID, isActive: $isActive, categoryName: $categoryName, ispartial: $ispartial, appointmentPricePercentage: $appointmentPricePercentage, refundAmountPercentage: $refundAmountPercentage, isSelected: $isSelected}'; - } -} +// class ProviderServiceModel { +// int? id; +// String? description; +// String? descriptionN; +// String? serviceIconUrl; +// String? serviceImageUrl; +// int? serviceCategoryID; +// bool? isActive; +// String? categoryName; +// bool? ispartial; +// int? appointmentPricePercentage; +// int? refundAmountPercentage; +// bool? isSelected; +// +// ProviderServiceModel( +// {this.id, +// this.description, +// this.descriptionN, +// this.serviceIconUrl, +// this.serviceImageUrl, +// this.serviceCategoryID, +// this.isActive, +// this.categoryName, +// this.ispartial, +// this.appointmentPricePercentage, +// this.refundAmountPercentage, +// this.isSelected = false, +// }); +// +// ProviderServiceModel.fromJson(Map json) { +// id = json['id']; +// description = json['description']; +// descriptionN = json['descriptionN']; +// serviceIconUrl = json['serviceIconUrl']; +// serviceImageUrl = json['serviceImageUrl']; +// serviceCategoryID = json['serviceCategoryID']; +// isActive = json['isActive']; +// categoryName = json['categoryName']; +// ispartial = json['ispartial']; +// appointmentPricePercentage = json['appointmentPricePercentage']; +// refundAmountPercentage = json['refundAmountPercentage']; +// isSelected = false; +// } +// +// Map toJson() { +// final Map data = {}; +// data['id'] = id; +// data['description'] = description; +// data['descriptionN'] = descriptionN; +// data['serviceIconUrl'] = serviceIconUrl; +// data['serviceImageUrl'] = serviceImageUrl; +// data['serviceCategoryID'] = serviceCategoryID; +// data['isActive'] = isActive; +// data['categoryName'] = categoryName; +// data['ispartial'] = ispartial; +// data['appointmentPricePercentage'] = appointmentPricePercentage; +// data['refundAmountPercentage'] = refundAmountPercentage; +// return data; +// } +// +// @override +// String toString() { +// return 'ProviderServiceModel{id: $id, description: $description, descriptionN: $descriptionN, serviceIconUrl: $serviceIconUrl, serviceImageUrl: $serviceImageUrl, serviceCategoryID: $serviceCategoryID, isActive: $isActive, categoryName: $categoryName, ispartial: $ispartial, appointmentPricePercentage: $appointmentPricePercentage, refundAmountPercentage: $refundAmountPercentage, isSelected: $isSelected}'; +// } +// } diff --git a/lib/models/services/service_model.dart b/lib/models/services/branch_service_model.dart similarity index 94% rename from lib/models/services/service_model.dart rename to lib/models/services/branch_service_model.dart index b11918c..44cf8d4 100644 --- a/lib/models/services/service_model.dart +++ b/lib/models/services/branch_service_model.dart @@ -1,4 +1,4 @@ -class ServiceModel { +class BranchServiceModel { final int? serviceProviderServiceId; final dynamic providerServiceDescription; final int? categoryId; @@ -15,7 +15,7 @@ class ServiceModel { final int? itemsCount; bool isExpanded; - ServiceModel({ + BranchServiceModel({ this.serviceProviderServiceId, this.providerServiceDescription, this.categoryId, @@ -33,7 +33,7 @@ class ServiceModel { required this.isExpanded, }); - factory ServiceModel.fromJson(Map json) => ServiceModel( + factory BranchServiceModel.fromJson(Map json) => BranchServiceModel( serviceProviderServiceId: json["serviceProviderServiceID"], providerServiceDescription: json["providerServiceDescription"], categoryId: json["categoryID"], diff --git a/lib/models/services/item_model.dart b/lib/models/services/item_model.dart index 6bfd075..8d37bbe 100644 --- a/lib/models/services/item_model.dart +++ b/lib/models/services/item_model.dart @@ -1,42 +1,6 @@ -// To parse this JSON data, do -// -// final itemModel = itemModelFromJson(jsonString); -import 'dart:convert'; -ItemModel itemModelFromJson(String str) => ItemModel.fromJson(json.decode(str)); - -String itemModelToJson(ItemModel data) => json.encode(data.toJson()); - -class ItemModel { - final int? messageStatus; - final int? totalItemsCount; - final List? data; - final String? message; - - ItemModel({ - this.messageStatus, - this.totalItemsCount, - this.data, - this.message, - }); - - factory ItemModel.fromJson(Map json) => ItemModel( - messageStatus: json["messageStatus"], - totalItemsCount: json["totalItemsCount"], - data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => ItemData.fromJson(x))), - message: json["message"], - ); - - Map toJson() => { - "messageStatus": messageStatus, - "totalItemsCount": totalItemsCount, - "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), - "message": message, - }; -} - -class ItemData { +class ServiceItemModel { final int? id; final String? name; final String? price; @@ -51,7 +15,7 @@ class ItemData { final bool? isAppointmentCustomerLoc; bool? isUpdate; - ItemData({ + ServiceItemModel({ this.id, this.name, this.price, @@ -67,7 +31,7 @@ class ItemData { this.isUpdate, }); - factory ItemData.fromJson(Map json) => ItemData( + factory ServiceItemModel.fromJson(Map json) => ServiceItemModel( id: json["id"], name: json["name"], price: json["price"].toString(), diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index 7101638..13caa08 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -2,16 +2,10 @@ import 'package:mc_common_app/api/api_client.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; -import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; -import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; -import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; -import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/generic_resp_model.dart'; -import 'package:mc_common_app/models/provider_category_model.dart'; -import 'package:mc_common_app/models/provider_service_model.dart'; import 'package:mc_common_app/models/user/cities.dart'; import 'package:mc_common_app/models/user/country.dart'; import 'package:mc_common_app/models/user/role.dart'; @@ -23,16 +17,15 @@ abstract class CommonRepo { Future getRoles(); - Future> getMyAppointments(); Future getCarCheckServiceScheduleDetails({required double lat, required double long}); Future getPhotographyServiceScheduleDetails({required double lat, required double long}); - Future> getProviderServiceCategories(); + // Future> getProviderServiceCategories(); - Future> getProviderServices({required int categoryId}); +// Future> getProviderServices({required int categoryId}); } class CommonRepoImp implements CommonRepo { @@ -57,7 +50,6 @@ class CommonRepoImp implements CommonRepo { return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles); } - @override Future> getMyAppointments() async { var params = { @@ -104,22 +96,22 @@ class CommonRepoImp implements CommonRepo { SSPhotoScheduleModel ssPhotoScheduleModel = SSPhotoScheduleModel.fromJson(genericRespModel.data[0]); return ssPhotoScheduleModel; } - - @override - Future> getProviderServiceCategories() async { - GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet); - List providerCategories = List.generate(adsGenericModel.data.length, (index) => ProviderCategoryModel.fromJson(adsGenericModel.data[index])); - return providerCategories; - } - - @override - Future> getProviderServices({required int categoryId}) async { - var postParams = { - "ServiceCategoryID": categoryId.toString(), - }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet, queryParameters: postParams); - List providerServices = List.generate(adsGenericModel.data.length, (index) => ProviderServiceModel.fromJson(adsGenericModel.data[index])); - return providerServices; - } + // +// @override +// Future> getProviderServiceCategories() async { +// GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet); +// List providerCategories = List.generate(adsGenericModel.data.length, (index) => ProviderCategoryModel.fromJson(adsGenericModel.data[index])); +// return providerCategories; +// } + +// @override +// Future> getProviderServices({required int categoryId}) async { +// var postParams = { +// "ServiceCategoryID": categoryId.toString(), +// }; +// GenericRespModel adsGenericModel = +// await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet, queryParameters: postParams); +// List providerServices = List.generate(adsGenericModel.data.length, (index) => ProviderServiceModel.fromJson(adsGenericModel.data[index])); +// return providerServices; +// } } diff --git a/lib/widgets/common_widgets/provider_details_card.dart b/lib/widgets/common_widgets/provider_details_card.dart index 69c3048..0d56eef 100644 --- a/lib/widgets/common_widgets/provider_details_card.dart +++ b/lib/widgets/common_widgets/provider_details_card.dart @@ -4,7 +4,7 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services/branch_service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; @@ -16,7 +16,7 @@ class ProviderDetailsCard extends StatelessWidget { final String providerRatings; //TODO: items can be make a generaic, so we can add services/items in the future - final List? items; + final List? items; final Function() onCardTapped; const ProviderDetailsCard({ From 026090b9624de096b6301f3e53e7242a890de1e8 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Mon, 17 Jul 2023 11:43:25 +0300 Subject: [PATCH 06/12] Reverted Code --- lib/models/model/provider_model.dart | 47 +++++---- .../branch_detail_model.dart | 8 +- .../profile/categroy.dart | 4 +- lib/models/services/item_model.dart | 96 +++++++++++++------ ..._service_model.dart => service_model.dart} | 6 ++ .../common_widgets/provider_details_card.dart | 14 +-- 6 files changed, 108 insertions(+), 67 deletions(-) rename lib/models/services/{branch_service_model.dart => service_model.dart} (81%) diff --git a/lib/models/model/provider_model.dart b/lib/models/model/provider_model.dart index 97ce37e..256b281 100644 --- a/lib/models/model/provider_model.dart +++ b/lib/models/model/provider_model.dart @@ -4,8 +4,7 @@ import 'dart:convert'; -import 'package:mc_common_app/models/profile/categroy.dart'; -import 'package:mc_common_app/models/services/branch_model.dart'; +import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; ProviderModel branch2FromJson(String str) => ProviderModel.fromJson(json.decode(str)); @@ -26,18 +25,18 @@ class ProviderModel { factory ProviderModel.fromJson(Map json) => ProviderModel( - messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], - totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + messageStatus: json["messageStatus"], + totalItemsCount: json["totalItemsCount"], data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]), - message: json["message"] == null ? null : json["message"], + message: json["message"], ); Map toJson() => { - "messageStatus": messageStatus == null ? null : messageStatus, - "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "messageStatus": messageStatus, + "totalItemsCount": totalItemsCount, "data": data == null ? null : data!.toJson(), - "message": message == null ? null : message, + "message": message, }; } @@ -62,29 +61,29 @@ class ProviderModelData { final int? allDocStatus; final bool? isValidSubscription; final String? userId; - final List? serviceProviderBranch; + final List? serviceProviderBranch; factory ProviderModelData.fromJson(Map json) => ProviderModelData( - id: json["id"] == null ? null : json["id"], - companyName: json["companyName"] == null ? null : json["companyName"], - countryName: json["countryName"] == null ? null : json["countryName"], - countryID: json["countryID"] == null ? null : json["countryID"], - companyDescription: json["companyDescription"] == null ? null : json["companyDescription"], - allDocStatus: json["allDocStatus"] == null ? null : json["allDocStatus"], - isValidSubscription: json["isValidSubscription"] == null ? null : json["isValidSubscription"], - userId: json["userID"] == null ? null : json["userID"], - serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List.from(json["serviceProviderBranch"].map((x) => BranchModel.fromJson(x))), + id: json["id"], + companyName: json["companyName"], + countryName: json["countryName"], + countryID: json["countryID"], + companyDescription: json["companyDescription"], + allDocStatus: json["allDocStatus"], + isValidSubscription: json["isValidSubscription"], + userId: json["userID"], + serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))), ); Map toJson() => { - "id": id == null ? null : id, - "companyName": companyName == null ? null : companyName, - "companyDescription": companyDescription == null ? null : companyDescription, - "allDocStatus": allDocStatus == null ? null : allDocStatus, - "isValidSubscription": isValidSubscription == null ? null : isValidSubscription, - "userID": userId == null ? null : userId, + "id": id, + "companyName": companyName, + "companyDescription": companyDescription, + "allDocStatus": allDocStatus, + "isValidSubscription": isValidSubscription, + "userID": userId, "serviceProviderBranch": serviceProviderBranch == null ? null : List.from(serviceProviderBranch!.map((x) => x.toJson())), }; } diff --git a/lib/models/provider_branches_models/branch_detail_model.dart b/lib/models/provider_branches_models/branch_detail_model.dart index dfc56ca..70768c3 100644 --- a/lib/models/provider_branches_models/branch_detail_model.dart +++ b/lib/models/provider_branches_models/branch_detail_model.dart @@ -1,9 +1,9 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/profile/categroy.dart'; +import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/services/service_model.dart'; import 'package:mc_common_app/utils/enums.dart'; -class BranchModel { +class BranchDetailModel { final int? id; final int? serviceProviderId; final String? serviceProviderName; @@ -25,7 +25,7 @@ class BranchModel { String? countryName; bool isExpanded; - BranchModel({ + BranchDetailModel({ this.id, this.serviceProviderId, this.serviceProviderName, @@ -48,7 +48,7 @@ class BranchModel { required this.isExpanded, }); - factory BranchModel.fromJson(Map json) => BranchModel( + factory BranchDetailModel.fromJson(Map json) => BranchDetailModel( id: json["id"], serviceProviderId: json["serviceProviderID"], serviceProviderName: json["serviceProviderName"], diff --git a/lib/models/provider_branches_models/profile/categroy.dart b/lib/models/provider_branches_models/profile/categroy.dart index c62cd9b..33feaae 100644 --- a/lib/models/provider_branches_models/profile/categroy.dart +++ b/lib/models/provider_branches_models/profile/categroy.dart @@ -6,7 +6,7 @@ import 'dart:convert'; import 'package:equatable/equatable.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; -import 'package:mc_common_app/models/services/branch_service_model.dart'; +import 'package:mc_common_app/models/services/service_model.dart'; Category categoryFromJson(String str) => Category.fromJson(json.decode(str)); @@ -60,7 +60,7 @@ class CategoryData extends Equatable { dynamic? serviceCategoryImageUrl; String? branchId; String? branchName; - List? services; + List? services; factory CategoryData.fromJson(Map json) => CategoryData( id: json["id"] == null ? null : json["id"], diff --git a/lib/models/services/item_model.dart b/lib/models/services/item_model.dart index 4cd35cf..11c88c2 100644 --- a/lib/models/services/item_model.dart +++ b/lib/models/services/item_model.dart @@ -1,6 +1,42 @@ +// To parse this JSON data, do +// +// final itemModel = itemModelFromJson(jsonString); +import 'dart:convert'; -class ServiceItemModel { +ItemModel itemModelFromJson(String str) => ItemModel.fromJson(json.decode(str)); + +String itemModelToJson(ItemModel data) => json.encode(data.toJson()); + +class ItemModel { + final int? messageStatus; + final int? totalItemsCount; + final List? data; + final String? message; + + ItemModel({ + this.messageStatus, + this.totalItemsCount, + this.data, + this.message, + }); + + factory ItemModel.fromJson(Map json) => ItemModel( + messageStatus: json["messageStatus"], + totalItemsCount: json["totalItemsCount"], + data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => ItemData.fromJson(x))), + message: json["message"], + ); + + Map toJson() => { + "messageStatus": messageStatus, + "totalItemsCount": totalItemsCount, + "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), + "message": message, + }; +} + +class ItemData { final int? id; final String? name; final String? price; @@ -15,7 +51,7 @@ class ServiceItemModel { final bool? isAppointmentCustomerLoc; bool? isUpdateOrSelected; - ServiceItemModel({ + ItemData({ this.id, this.name, this.price, @@ -31,34 +67,34 @@ class ServiceItemModel { this.isUpdateOrSelected, }); - factory ServiceItemModel.fromJson(Map json) => ServiceItemModel( - id: json["id"], - name: json["name"], - price: json["price"].toString(), - manufactureDate: json["manufactureDate"], - description: json["description"], - pictureUrl: json["pictureUrl"], - companyId: json["companyID"], - serviceProviderServiceId: json["serviceProviderServiceID"], - isActive: json["isActive"], - isAllowAppointment: json["isAllowAppointment"], - isAppointmentCompanyLoc: json["isAppointmentCompanyLoc"], - isAppointmentCustomerLoc: json["isAppointmentCustomerLoc"], + factory ItemData.fromJson(Map json) => ItemData( + id: json["id"], + name: json["name"], + price: json["price"].toString(), + manufactureDate: json["manufactureDate"], + description: json["description"], + pictureUrl: json["pictureUrl"], + companyId: json["companyID"], + serviceProviderServiceId: json["serviceProviderServiceID"], + isActive: json["isActive"], + isAllowAppointment: json["isAllowAppointment"], + isAppointmentCompanyLoc: json["isAppointmentCompanyLoc"], + isAppointmentCustomerLoc: json["isAppointmentCustomerLoc"], isUpdateOrSelected: false, - ); + ); Map toJson() => { - "id": id, - "name": name, - "price": price, - "manufactureDate": manufactureDate, - "description": description, - "pictureUrl": pictureUrl, - "companyID": companyId, - "serviceProviderServiceID": serviceProviderServiceId, - "isActive": isActive, - "isAllowAppointment": isAllowAppointment, - "isAppointmentCompanyLoc": isAppointmentCompanyLoc, - "isAppointmentCustomerLoc": isAppointmentCustomerLoc, - }; -} + "id": id, + "name": name, + "price": price, + "manufactureDate": manufactureDate, + "description": description, + "pictureUrl": pictureUrl, + "companyID": companyId, + "serviceProviderServiceID": serviceProviderServiceId, + "isActive": isActive, + "isAllowAppointment": isAllowAppointment, + "isAppointmentCompanyLoc": isAppointmentCompanyLoc, + "isAppointmentCustomerLoc": isAppointmentCustomerLoc, + }; +} \ No newline at end of file diff --git a/lib/models/services/branch_service_model.dart b/lib/models/services/service_model.dart similarity index 81% rename from lib/models/services/branch_service_model.dart rename to lib/models/services/service_model.dart index 3d04657..5306dd5 100644 --- a/lib/models/services/branch_service_model.dart +++ b/lib/models/services/service_model.dart @@ -1,3 +1,4 @@ + import 'package:mc_common_app/models/services/item_model.dart'; class ServiceModel { @@ -75,4 +76,9 @@ class ServiceModel { "itemsCount": itemsCount, "branchServiceItems": serviceItems == null ? [] : List.from(serviceItems!.map((x) => x.toJson())), }; + + @override + String toString() { + return 'ServiceModel{serviceProviderServiceId: $serviceProviderServiceId, providerServiceDescription: $providerServiceDescription, categoryId: $categoryId, categoryName: $categoryName, serviceId: $serviceId, serviceDescription: $serviceDescription, serviceDescriptionN: $serviceDescriptionN, serviceStatus: $serviceStatus, statusText: $statusText, isAllowAppointment: $isAllowAppointment, isAllowAppointmentHome: $isAllowAppointmentHome, customerLocationRange: $customerLocationRange, rangePricePerKm: $rangePricePerKm, itemsCount: $itemsCount, serviceItems: $serviceItems, isExpandedOrSelected: $isExpandedOrSelected}'; + } } diff --git a/lib/widgets/common_widgets/provider_details_card.dart b/lib/widgets/common_widgets/provider_details_card.dart index 0d56eef..f8106fa 100644 --- a/lib/widgets/common_widgets/provider_details_card.dart +++ b/lib/widgets/common_widgets/provider_details_card.dart @@ -4,7 +4,7 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/services/branch_service_model.dart'; +import 'package:mc_common_app/models/services/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; @@ -16,7 +16,7 @@ class ProviderDetailsCard extends StatelessWidget { final String providerRatings; //TODO: items can be make a generaic, so we can add services/items in the future - final List? items; + final List? services; final Function() onCardTapped; const ProviderDetailsCard({ @@ -26,7 +26,7 @@ class ProviderDetailsCard extends StatelessWidget { this.providerName, required this.providerRatings, required this.providerLocation, - this.items, + this.services, required this.onCardTapped, }) : super(key: key); @@ -97,9 +97,9 @@ class ProviderDetailsCard extends StatelessWidget { ], ), 8.height, - if (items != null) + if (services != null) Column( - children: items! + children: services! .take(2) .map( (e) => @@ -117,8 +117,8 @@ class ProviderDetailsCard extends StatelessWidget { ) .toList(), ), - if (items != null && items!.length > 2) - ("+${items!.length - 2} more").toText( + if (services != null && services!.length > 2) + ("+${services!.length - 2} more").toText( color: MyColors.primaryColor, isUnderLine: true, isBold: true, From fb9db7fb0bea7b51810effdf6d673ed8122b1d84 Mon Sep 17 00:00:00 2001 From: FaizHashmiCS22 Date: Wed, 26 Jul 2023 07:53:13 +0300 Subject: [PATCH 07/12] Schedules in Appointments (In Progress) --- lib/classes/consts.dart | 1 + lib/models/schedule_model.dart | 38 ++-- lib/models/service_schedule_model.dart | 180 ++++++++++++++++++ lib/models/services/item_model.dart | 2 + .../common_widgets/provider_details_card.dart | 4 +- 5 files changed, 197 insertions(+), 28 deletions(-) create mode 100644 lib/models/service_schedule_model.dart diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 7ebeb78..b1727c9 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -50,6 +50,7 @@ class ApiConsts { static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get"; static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get"; static String GetAllNearBranches = "${baseUrlServices}api/ServiceProviders/ServiceProviderBranchDetail_Get"; + static String GetServiceItemAppointmentScheduleSlots = "${baseUrlServices}api/ServiceProviders/ServiceItemAppointmentScheduleSlots_Get"; //Appointment APIs static String serviceProvidersAppointmentGet = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointment_Get"; diff --git a/lib/models/schedule_model.dart b/lib/models/schedule_model.dart index 6676083..47c13e6 100644 --- a/lib/models/schedule_model.dart +++ b/lib/models/schedule_model.dart @@ -4,6 +4,8 @@ import 'dart:convert'; +import 'package:mc_common_app/models/services/service_model.dart'; + Schedule scheduleFromJson(String str) => Schedule.fromJson(json.decode(str)); String scheduleToJson(Schedule data) => json.encode(data.toJson()); @@ -53,7 +55,8 @@ class ScheduleData { final String? latitude; final String? longitude; final List? weeklyOffDays; - final List? scheduleServices; + final List? scheduleServices; + final List? selectedServices; String branchId; ScheduleData({ @@ -72,6 +75,7 @@ class ScheduleData { this.longitude, this.weeklyOffDays, this.scheduleServices, + this.selectedServices, this.branchId = "", }); @@ -91,7 +95,8 @@ class ScheduleData { latitude: json["latitude"], longitude: json["longitude"], weeklyOffDays: json["weeklyOffDays"] == null ? [] : List.from(json["weeklyOffDays"]!.map((x) => WeeklyOffDay.fromJson(x))), - scheduleServices: json["scheduleServices"] == null ? [] : List.from(json["scheduleServices"]!.map((x) => ScheduleService.fromJson(x))), + scheduleServices: json["scheduleServices"] == null ? [] : List.from(json["scheduleServices"]!.map((x) => ServiceModel.fromJson(x))), + selectedServices: [], ); Map toJson() => @@ -111,33 +116,14 @@ class ScheduleData { "longitude": longitude, "scheduleServices": scheduleServices == null ? [] : List.from(scheduleServices!.map((x) => x.toJson())), }; -} - -class ScheduleService { - final int? providerServiceId; - // final int? branchScheduleGroupServiceID; - final String? providerServiceName; - ScheduleService({ - this.providerServiceId, - // this.branchScheduleGroupServiceID, - this.providerServiceName, - }); - - factory ScheduleService.fromJson(Map json) => - ScheduleService( - providerServiceId: json["providerServiceID"], - // branchScheduleGroupServiceID: json["branchScheduleGroupServiceID"], - providerServiceName: json["providerServiceName"], - ); - - Map toJson() => - { - "providerServiceID": providerServiceId, - "providerServiceName": providerServiceName, - }; + @override + String toString() { + return 'ScheduleData{id: $id, scheduleName: $scheduleName, serviceProviderBranchId: $serviceProviderBranchId, fromDate: $fromDate, toDate: $toDate, startTime: $startTime, endTime: $endTime, slotDurationMinute: $slotDurationMinute, perSlotAppointment: $perSlotAppointment, branchName: $branchName, address: $address, latitude: $latitude, longitude: $longitude, weeklyOffDays: $weeklyOffDays, scheduleServices: $scheduleServices, branchId: $branchId}'; + } } + class WeeklyOffDay { final int? id; final int? dayNumber; diff --git a/lib/models/service_schedule_model.dart b/lib/models/service_schedule_model.dart new file mode 100644 index 0000000..b8081f5 --- /dev/null +++ b/lib/models/service_schedule_model.dart @@ -0,0 +1,180 @@ +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/models/services/item_model.dart'; +import 'package:mc_common_app/models/widgets_models.dart'; + +class ServiceAppointmentScheduleModel { + List? serviceSlotList; + List? serviceItemList; + String? selectedDate; + String? selectedTimeSlot; + List? availableDates; + List? availableTimeSlots; + double? amountToPay; + double? amountTotal; + double? amountRem; + + ServiceAppointmentScheduleModel({ + this.serviceSlotList, + this.serviceItemList, + this.selectedDate, + this.selectedTimeSlot, + this.availableDates, + this.availableTimeSlots, + this.amountToPay, + this.amountTotal, + this.amountRem, + }); + + List getFormattedSlotTimes() { + var seenSlots = {}; + + var slotTimeData = serviceSlotList! + .where((slot) => seenSlots.add(TimeSlotModel( + slot: slot.startTime!, + slotId: slot.id!, + isSelected: false, + ))) + .toList(); + List slotTime = []; + for (var element in slotTimeData) { + slotTime.add(TimeSlotModel(isSelected: false, slotId: element.id!, slot: element.slotDate ?? "")); + } + + return slotTime; + } + + List getFormattedSlotDates() { + var seenDates = {}; + + var slotDatesData = serviceSlotList! + .where((slot) => seenDates.add(TimeSlotModel( + slot: slot.slotDate!, + slotId: slot.id!, + isSelected: false, + ))) + .toList(); + List slotDates = []; + for (var element in slotDatesData) { + slotDates.add(TimeSlotModel(isSelected: false, slotId: element.id!, slot: element.slotDate!.toFormattedDateWithoutTime() ?? "")); + } + + return slotDates; + } + + //TODO: I WILL START FROM HERE; I NEED TO ONLY PICK THE DISTINCT DATES FROM THE RESPONSE AND THEN BASED ON THE DATE SELECTION I WILL PICK THEIR SLOTS. + //TODO: AFTER THAT, I WILL + + ServiceAppointmentScheduleModel.fromJson(Map json) { + if (json['serviceSlotList'] != null) { + serviceSlotList = []; + json['serviceSlotList'].forEach((v) { + serviceSlotList!.add(ServiceSlotList.fromJson(v)); + }); + } + if (json['serviceItemList'] != null) { + serviceItemList = []; + json['serviceItemList'].forEach((v) { + serviceItemList!.add(ItemData.fromJson(v)); + }); + } + + amountToPay = json['amountToPay']; + selectedDate = ''; + selectedTimeSlot = ''; + availableDates = getFormattedSlotDates(); + availableTimeSlots = getFormattedSlotTimes(); + amountTotal = json['amountTotal']; + amountRem = json['amountRem']; + } + + Map toJson() { + final Map data = {}; + if (serviceSlotList != null) { + data['serviceSlotList'] = serviceSlotList!.map((v) => v.toJson()).toList(); + } + if (serviceItemList != null) { + data['serviceItemList'] = serviceItemList!.map((v) => v.toJson()).toList(); + } + data['amountToPay'] = amountToPay; + data['amountTotal'] = amountTotal; + data['amountRem'] = amountRem; + return data; + } +} + +class ServiceSlotList { + int? id; + int? branchAppointmentScheduleID; + String? branchAppointmentSchedule; + int? serviceProviderID; + String? slotDate; + String? startTime; + String? endTime; + int? bookAppointment; + int? allowAppointment; + int? slotDurationMinute; + int? appointmentType; + bool? isActive; + int? createdBy; + String? createdOn; + int? modifiedBy; + String? modifiedOn; + + ServiceSlotList( + {this.id, + this.branchAppointmentScheduleID, + this.branchAppointmentSchedule, + this.serviceProviderID, + this.slotDate, + this.startTime, + this.endTime, + this.bookAppointment, + this.allowAppointment, + this.slotDurationMinute, + this.appointmentType, + this.isActive, + this.createdBy, + this.createdOn, + this.modifiedBy, + this.modifiedOn}); + + ServiceSlotList.fromJson(Map json) { + id = json['id']; + branchAppointmentScheduleID = json['branchAppointmentScheduleID']; + branchAppointmentSchedule = json['branchAppointmentSchedule']; + serviceProviderID = json['serviceProviderID']; + slotDate = json['slotDate']; + startTime = json['startTime']; + endTime = json['endTime']; + bookAppointment = json['bookAppointment']; + allowAppointment = json['allowAppointment']; + slotDurationMinute = json['slotDurationMinute']; + appointmentType = json['appointmentType']; + isActive = json['isActive']; + createdBy = json['createdBy']; + createdOn = json['createdOn']; + modifiedBy = json['modifiedBy']; + modifiedOn = json['modifiedOn']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['branchAppointmentScheduleID'] = branchAppointmentScheduleID; + data['branchAppointmentSchedule'] = branchAppointmentSchedule; + data['serviceProviderID'] = serviceProviderID; + data['slotDate'] = slotDate; + data['startTime'] = startTime; + data['endTime'] = endTime; + data['bookAppointment'] = bookAppointment; + data['allowAppointment'] = allowAppointment; + data['slotDurationMinute'] = slotDurationMinute; + data['appointmentType'] = appointmentType; + data['isActive'] = isActive; + data['createdBy'] = createdBy; + data['createdOn'] = createdOn; + data['modifiedBy'] = modifiedBy; + data['modifiedOn'] = modifiedOn; + return data; + } +} diff --git a/lib/models/services/item_model.dart b/lib/models/services/item_model.dart index 11c88c2..2ea572c 100644 --- a/lib/models/services/item_model.dart +++ b/lib/models/services/item_model.dart @@ -49,6 +49,7 @@ class ItemData { final bool? isAllowAppointment; final bool? isAppointmentCompanyLoc; final bool? isAppointmentCustomerLoc; + final double? appointmentPricePercentage; bool? isUpdateOrSelected; ItemData({ @@ -64,6 +65,7 @@ class ItemData { this.isAllowAppointment, this.isAppointmentCompanyLoc, this.isAppointmentCustomerLoc, + this.appointmentPricePercentage, this.isUpdateOrSelected, }); diff --git a/lib/widgets/common_widgets/provider_details_card.dart b/lib/widgets/common_widgets/provider_details_card.dart index f8106fa..169f1c2 100644 --- a/lib/widgets/common_widgets/provider_details_card.dart +++ b/lib/widgets/common_widgets/provider_details_card.dart @@ -66,7 +66,7 @@ class ProviderDetailsCard extends StatelessWidget { title.toText(fontSize: 16, isBold: true), Row( children: [ - (LocaleKeys.location.tr() + ":").toText(color: MyColors.lightTextColor, fontSize: 12), + ("${LocaleKeys.location.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), 4.width, providerLocation.toText(fontSize: 12, isBold: true), ], @@ -74,7 +74,7 @@ class ProviderDetailsCard extends StatelessWidget { if (providerName != null) Row( children: [ - (LocaleKeys.providers.tr() + ":").toText(color: MyColors.lightTextColor, fontSize: 12), + ("${LocaleKeys.providers.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), 4.width, providerName!.toText(fontSize: 12, isBold: true), ], From ba0b66d7e5d869b66066f78da2bc226829a6d9aa Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Sun, 3 Sep 2023 16:33:12 +0300 Subject: [PATCH 08/12] Added select_ad_type_view.dart --- lib/config/routes.dart | 29 ++--- lib/repositories/ads_repo.dart | 3 + .../advertisement/select_ad_type_view.dart | 122 ++++++++++++++++++ pubspec.lock | 36 +----- pubspec.yaml | 4 +- 5 files changed, 140 insertions(+), 54 deletions(-) create mode 100644 lib/views/advertisement/select_ad_type_view.dart diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 2f120cd..86e5b5f 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,9 +1,5 @@ import 'package:mc_common_app/models/user/register_user.dart'; -// import 'package:mc_common_app/views/settings/create_services_page.dart'; -// import 'package:mc_common_app/views/settings/dealership_page.dart'; -// import 'package:mc_common_app/views/settings/define_branch_page.dart'; -// import 'package:mc_common_app/views/settings/define_license_page.dart'; import 'package:mc_common_app/views/user/change_email_page.dart'; import 'package:mc_common_app/views/user/change_mobile_page.dart'; import 'package:mc_common_app/views/user/change_password_page.dart'; @@ -16,10 +12,6 @@ import 'package:mc_common_app/views/user/login_method_selection_page.dart'; import 'package:mc_common_app/views/user/login_verification_page.dart'; import 'package:mc_common_app/views/user/login_verify_account_page.dart'; import 'package:mc_common_app/views/user/login_with_password_page.dart'; - -// import 'package:mc_common_app/views/user/profile/profile_1_page.dart'; -// import 'package:mc_common_app/views/user/profile/profile_2_page.dart'; -// import 'package:mc_common_app/views/user/profile/profile_3_page.dart'; import 'package:mc_common_app/views/user/register_page.dart'; import 'package:mc_common_app/views/user/register_provider_page.dart'; import 'package:mc_common_app/views/user/register_selection_page.dart'; @@ -53,6 +45,7 @@ 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"; @@ -68,31 +61,31 @@ class AppRoutes { static const String providerProfilePage = "/providerProfilePage"; - // Subcriptions - static final String mySubscriptionsPage = "/mySubscriptionsPage"; - static final String subscriptionsPage = "/subscriptionsPage"; + // Subscriptions + static const String mySubscriptionsPage = "/mySubscriptionsPage"; + static const String subscriptionsPage = "/subscriptionsPage"; static const String initialRoute = splash; static final Map routes = { //User splash: (context) => const SplashPage(), - registerSelection: (context) => RegisterSelectionPage(), + registerSelection: (context) => const RegisterSelectionPage(), loginVerifyAccount: (context) => LoginVerifyAccountPage(), - registerCustomer: (context) => RegisterCustomerPage(), - registerProvider: (context) => RegisterProviderPage(), - forgetPassword: (context) => ForgetPasswordPage(), + registerCustomer: (context) => const RegisterCustomerPage(), + registerProvider: (context) => const RegisterProviderPage(), + forgetPassword: (context) => const ForgetPasswordPage(), loginVerification: (context) => const LoginVerificationPage(), - loginWithPassword: (context) => LoginWithPassword(), + loginWithPassword: (context) => const LoginWithPassword(), loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String), completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUserRespModel), verifyPassword: (context) => VerifyPasswordPage(), confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String), - changePassword: (context) => ChangePasswordPage(), + changePassword: (context) => const ChangePasswordPage(), forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String), changeMobilePage: (context) => ChangeMobilePage(), changeEmailPage: (context) => const ChangeEmailPage(), - editAccountPage: (context) => EditAccountPage(), + editAccountPage: (context) => const EditAccountPage(), }; } diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index f4d1520..50bdb57 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:mc_common_app/api/api_client.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -300,6 +302,7 @@ class AdsRepoImp implements AdsRepo { postParams, token: token, ); + log ("value: ${adsGenericModel}"); return Future.value(adsGenericModel); } diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart new file mode 100644 index 0000000..93959f1 --- /dev/null +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/consts.dart'; +import 'package:mc_common_app/extensions/int_extensions.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/view_models/ad_view_model.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; + + const SelectAdTypeView({ + Key? key, + this.isProvider = true, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + title: "Select Ad Type", + profileImageUrl: MyAssets.bnCar, + isRemoveBackButton: false, + isDrawerEnabled: false, + ), + body: Column( + children: [ + Expanded( + child: Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) { + return ListView.separated( + 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), + ], + ).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), + ), + ], + ), + ], + ), + ), + ], + ), + ).toWhiteContainer(width: double.infinity, allPading: 10); + }, + separatorBuilder: (BuildContext context, int index) { + return 9.height; + }, + padding: const EdgeInsets.all(20), + ); + }), + ), + if (isProvider) ...[ + SizedBox( + height: 12.h, + child: 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: [ + 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), + ), + ] + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index b41a13e..e95be15 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -261,38 +261,6 @@ packages: url: "https://pub.dev" source: hosted version: "8.2.2" - geocoding: - dependency: "direct main" - description: - name: geocoding - sha256: b34c0501bbbaf3190b85bef3078b27cf66c28a8915c6d3af50d67f356aa7da31 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - geocoding_android: - dependency: transitive - description: - name: geocoding_android - sha256: "5a1fc0cec9b0497b44ca31c1fa8d1c891f3aded1053e6bb2eac075d3bd1bf046" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - geocoding_ios: - dependency: transitive - description: - name: geocoding_ios - sha256: c85495ce8fb34e4fbd2dd8fc5f79263d622d9f88c4af948c965daf6b27a7f3a1 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - geocoding_platform_interface: - dependency: transitive - description: - name: geocoding_platform_interface - sha256: "8848605d307d844d89937cdb4b8ad7dfa880552078f310fa24d8a460f6dddab4" - url: "https://pub.dev" - source: hosted - version: "2.0.1" geolocator: dependency: "direct main" description: @@ -377,10 +345,10 @@ packages: dependency: "direct main" description: name: hexcolor - sha256: e572c3346f4b26422a281dc4c10f83022131f56f7364837671b50f53c7adc5e7 + sha256: c07f4bbb9095df87eeca87e7c69e8c3d60f70c66102d7b8d61c4af0453add3f6 url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "3.0.1" http: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 3e04e24..e328d29 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,7 +29,7 @@ dependencies: auto_size_text: any shimmer: ^2.0.0 local_auth: any - hexcolor: ^2.0.4 + hexcolor: ^3.0.1 cached_network_image: any url_launcher: ^6.1.7 badges: ^3.0.2 @@ -40,7 +40,7 @@ dependencies: # google google_maps_flutter: ^2.1.1 geolocator: any - geocoding: any +# geocoding: ^2.1.0 dev_dependencies: From 0b7b12180604d78b4120bfb1a7cb867b4d923e40 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 4 Sep 2023 16:30:15 +0300 Subject: [PATCH 09/12] 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); } - - From d93947152a46f88370fa91c9fc71f71f18f7aa14 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Tue, 12 Sep 2023 16:45:31 +0300 Subject: [PATCH 10/12] 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 From a841c232de09dda316289af39d36a443ca136cd4 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Sun, 17 Sep 2023 15:03:59 +0300 Subject: [PATCH 11/12] Ad Module Commit --- lib/classes/consts.dart | 1 + lib/extensions/string_extensions.dart | 71 +- .../advertisment_models/ad_details_model.dart | 28 +- .../reserved_ads_models.dart | 36 + lib/models/generic_resp_model.dart | 123 +-- .../pay_order_detail_resp_model.dart | 5 + lib/repositories/ads_repo.dart | 30 +- lib/services/payments_service.dart | 3 +- lib/utils/enums.dart | 6 +- lib/utils/utils.dart | 19 +- lib/view_models/ad_view_model.dart | 52 +- lib/view_models/payment_view_model.dart | 41 +- lib/views/advertisement/ads_detail_view.dart | 842 +++++++++--------- lib/views/advertisement/ads_list.dart | 7 +- .../advertisement/bottom_sheet_content.dart | 1 - lib/views/payments/payment_methods_view.dart | 6 +- lib/views/user/login_with_password_page.dart | 2 +- lib/widgets/button/show_fill_button.dart | 37 +- 18 files changed, 735 insertions(+), 575 deletions(-) create mode 100644 lib/models/advertisment_models/reserved_ads_models.dart diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 8a063a9..707b7cc 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -93,6 +93,7 @@ class ApiConsts { static String vehicleAdsSpecialServicesGet = "${baseUrlServices}api/Common/SpecialService_Get"; static String vehicleAdsSingleStepCreate = "${baseUrlServices}api/Advertisement/AdsSingleStep_Create"; static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get"; + static String myAdsReserveGet = "${baseUrlServices}api/Advertisement/AdsReserve_Get"; static String adsCarCheckupSPBranchScheduleSlotGet = "${baseUrlServices}api/Advertisement/AdsCarCheckupSPBranchScheduleSlot_Get"; static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 02a0905..2f07f17 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -182,6 +182,63 @@ extension AdPostEnum on int { } } +extension AdPostStatusToInt on AdPostStatus { + int getIdFromAdPostStatusEnum() { + switch (this) { + case AdPostStatus.pendingForReview: + return 1; + case AdPostStatus.pendingForPayment: + return 2; + + case AdPostStatus.rejected: + return 3; + + case AdPostStatus.cancelled: + return 4; + + case AdPostStatus.pendingForPost: + return 5; + + case AdPostStatus.active: + return 6; + + case AdPostStatus.expired: + return 7; + + case AdPostStatus.sold: + return 8; + + case AdPostStatus.reserved: + return 9; + + case AdPostStatus.buyingService: + return 10; + + case AdPostStatus.reserveCancel: + return 11; + default: + return -1; + } + } +} + +extension CreatedByRoleEnumToInt on CreatedByRoleEnum { + int getIdFromCreatedByRoleEnum() { + switch (this) { + case CreatedByRoleEnum.admin: + return 1; + case CreatedByRoleEnum.customer: + return 2; + case CreatedByRoleEnum.provider: + return 3; + case CreatedByRoleEnum.allAds: + return -1; + default: + return 1; + } + } +} + extension AdReserveStatusEnum on int { AdReserveStatus toAdRserveStatusEnum() { if (this == 0) { @@ -199,15 +256,17 @@ extension AdReserveStatusEnum on int { } extension AdOwnerEnum on int { - AdOwner toAdOwnerEnum() { - if (this == 0) { - return AdOwner.customer; + CreatedByRoleEnum toCreatedByRoleEnum() { + if (this == -1) { + return CreatedByRoleEnum.allAds; } else if (this == 1) { - return AdOwner.provider; + return CreatedByRoleEnum.admin; } else if (this == 2) { - return AdOwner.mowater; + return CreatedByRoleEnum.customer; + } else if (this == 3) { + return CreatedByRoleEnum.provider; } - return AdOwner.customer; + return CreatedByRoleEnum.customer; } } diff --git a/lib/models/advertisment_models/ad_details_model.dart b/lib/models/advertisment_models/ad_details_model.dart index c14f6e2..4c7f85f 100644 --- a/lib/models/advertisment_models/ad_details_model.dart +++ b/lib/models/advertisment_models/ad_details_model.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/utils/enums.dart'; @@ -38,7 +40,9 @@ class AdDetailsModel { AdPostStatus? adPostStatus; AdReserveStatus? adReserveStatus; bool? isMyAd; - AdOwner? adOwnerEnum; + String? phoneNo; + String? whatsAppNo; + CreatedByRoleEnum? createdByRoleEnum; AdDetailsModel( {this.id, @@ -74,9 +78,17 @@ class AdDetailsModel { this.adPostStatus, this.adReserveStatus, this.isMyAd, - this.adOwnerEnum, + this.phoneNo, + this.whatsAppNo, + this.createdByRoleEnum, this.modifiedOn}); + int getRandomValue({required int min, required int max}) { + Random random = Random(); + int randomNumber = random.nextInt(max - min); + return randomNumber; + } + AdDetailsModel.fromJson(Map json, bool isMyAds) { id = json['id']; startdate = json['startdate']; @@ -88,12 +100,6 @@ class AdDetailsModel { specialservice!.add(SpecialServiceModel.fromJson(v)); }); } - // if (json['reserved'] != null) { - // reserved = []; - // json['reserved'].forEach((v) { - // reserved!.add(Null.fromJson(v)); - // }); - // } statusID = json['statusID']; statuslabel = json['statuslabel']; adsDurationPrice = json['adsDurationPrice']; @@ -119,11 +125,13 @@ class AdDetailsModel { reservePrice = json['reservePrice']; isMCHandled = json['isMCHandled']; modifiedOn = json['modifiedOn']; + whatsAppNo = json['phoneNo']; + modifiedOn = json['whatsAppNo']; 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(); + createdByRoleEnum = CreatedByRoleEnum.admin; + // createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum(); isMyAd = isMyAds; } diff --git a/lib/models/advertisment_models/reserved_ads_models.dart b/lib/models/advertisment_models/reserved_ads_models.dart new file mode 100644 index 0000000..83c793f --- /dev/null +++ b/lib/models/advertisment_models/reserved_ads_models.dart @@ -0,0 +1,36 @@ +class MyReservedAdsRespModel { + int? id; + int? adsID; + int? customerID; + int? paymentStatus; + int? reservationTimeID; + double? reservationBasePrice; + double? refundAmount; + String? refundDate; + + MyReservedAdsRespModel({this.id, this.adsID, this.customerID, this.paymentStatus, this.reservationTimeID, this.reservationBasePrice, this.refundAmount, this.refundDate}); + + MyReservedAdsRespModel.fromJson(Map json) { + id = json['id']; + adsID = json['adsID']; + customerID = json['customerID']; + paymentStatus = json['paymentStatus']; + reservationTimeID = json['reservationTimeID']; + reservationBasePrice = json['reservationBasePrice']; + refundAmount = json['refundAmount']; + refundDate = json['refundDate']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['adsID'] = adsID; + data['customerID'] = customerID; + data['paymentStatus'] = paymentStatus; + data['reservationTimeID'] = reservationTimeID; + data['reservationBasePrice'] = reservationBasePrice; + data['refundAmount'] = refundAmount; + data['refundDate'] = refundDate; + return data; + } +} diff --git a/lib/models/generic_resp_model.dart b/lib/models/generic_resp_model.dart index 7b476d7..89d935d 100644 --- a/lib/models/generic_resp_model.dart +++ b/lib/models/generic_resp_model.dart @@ -23,16 +23,7 @@ class GenericRespModel { } var json = { - "ads": { - "id": 0, - "adsDurationID": 1, - "startDate": "2023-04-12T10:10:20.905Z", - "countryId": 1, - "specialServiceIDs": [ - - ], - "isMCHandled": false - }, + "ads": {"id": 0, "adsDurationID": 1, "startDate": "2023-04-12T10:10:20.905Z", "countryId": 1, "specialServiceIDs": [], "isMCHandled": false}, "vehiclePosting": { "id": 0, "userID": "1A1597B3-D5A0-433A-098B-08DB189E51EC", @@ -56,24 +47,10 @@ var json = { "demandAmount": 34, "adStatus": 1, "vehiclePostingImages": [ - { - "id": 0, - "imageName": "onon", - "imageUrl": "string", - "imageStr": null, - "vehiclePostingID": 0, - "vehiclePosting": null - } + {"id": 0, "imageName": "onon", "imageUrl": "string", "imageStr": null, "vehiclePostingID": 0, "vehiclePosting": null} ], "vehiclePostingDamageParts": [ - { - "id": 0, - "comment": "hhsa", - "vehicleImageBase64": null, - "vehicleDamagePartID": 1, - "vehiclePostingID": 0, - "isActive": true - } + {"id": 0, "comment": "hhsa", "vehicleImageBase64": null, "vehicleDamagePartID": 1, "vehiclePostingID": 0, "isActive": true} ] } }; @@ -86,9 +63,7 @@ class AdsCreationPayloadModel { AdsCreationPayloadModel.fromJson(Map json) { ads = json['ads'] != null ? Ads.fromJson(json['ads']) : null; - vehiclePosting = json['vehiclePosting'] != null - ? VehiclePosting.fromJson(json['vehiclePosting']) - : null; + vehiclePosting = json['vehiclePosting'] != null ? VehiclePosting.fromJson(json['vehiclePosting']) : null; } Map toJson() { @@ -111,13 +86,7 @@ class Ads { List? specialServiceIDs; bool? isMCHandled; - Ads( - {this.id, - this.adsDurationID, - this.startDate, - this.countryId, - this.specialServiceIDs, - this.isMCHandled}); + Ads({this.id, this.adsDurationID, this.startDate, this.countryId, this.specialServiceIDs, this.isMCHandled}); Ads.fromJson(Map json) { id = json['id']; @@ -164,31 +133,35 @@ class VehiclePosting { int? adStatus; List? vehiclePostingImages; List? vehiclePostingDamageParts; + String? phoneNo; + String? whatsAppNo; VehiclePosting( {this.id, - this.userID, - this.vehicleType, - this.vehicleModelID, - this.vehicleModelYearID, - this.vehicleColorID, - this.vehicleCategoryID, - this.vehicleConditionID, - this.vehicleMileageID, - this.vehicleTransmissionID, - this.vehicleSellerTypeID, - this.cityID, - this.price, - this.vehicleVIN, - this.vehicleDescription, - this.vehicleTitle, - this.vehicleDescriptionN, - this.isFinanceAvailable, - this.warantyYears, - this.demandAmount, - this.adStatus, - this.vehiclePostingImages, - this.vehiclePostingDamageParts}); + this.userID, + this.vehicleType, + this.vehicleModelID, + this.vehicleModelYearID, + this.vehicleColorID, + this.vehicleCategoryID, + this.vehicleConditionID, + this.vehicleMileageID, + this.vehicleTransmissionID, + this.vehicleSellerTypeID, + this.cityID, + this.price, + this.vehicleVIN, + this.vehicleDescription, + this.vehicleTitle, + this.vehicleDescriptionN, + this.isFinanceAvailable, + this.warantyYears, + this.demandAmount, + this.adStatus, + this.phoneNo, + this.whatsAppNo, + this.vehiclePostingImages, + this.vehiclePostingDamageParts}); VehiclePosting.fromJson(Map json) { id = json['id']; @@ -212,6 +185,8 @@ class VehiclePosting { warantyYears = json['warantyYears']; demandAmount = json['demandAmount']; adStatus = json['adStatus']; + phoneNo = json['phoneNo']; + whatsAppNo = json['whatsAppNo']; if (json['vehiclePostingImages'] != null) { vehiclePostingImages = []; json['vehiclePostingImages'].forEach((v) { @@ -221,8 +196,7 @@ class VehiclePosting { if (json['vehiclePostingDamageParts'] != null) { vehiclePostingDamageParts = []; json['vehiclePostingDamageParts'].forEach((v) { - vehiclePostingDamageParts! - .add(VehiclePostingDamageParts.fromJson(v)); + vehiclePostingDamageParts!.add(VehiclePostingDamageParts.fromJson(v)); }); } } @@ -250,16 +224,21 @@ class VehiclePosting { data['warantyYears'] = warantyYears; data['demandAmount'] = demandAmount; data['adStatus'] = adStatus; + data['phoneNo'] = phoneNo; + data['whatsAppNo'] = whatsAppNo; if (vehiclePostingImages != null) { - data['vehiclePostingImages'] = - vehiclePostingImages!.map((v) => v.toJson()).toList(); + data['vehiclePostingImages'] = vehiclePostingImages!.map((v) => v.toJson()).toList(); } if (vehiclePostingDamageParts != null) { - data['vehiclePostingDamageParts'] = - vehiclePostingDamageParts!.map((v) => v.toJson()).toList(); + data['vehiclePostingDamageParts'] = vehiclePostingDamageParts!.map((v) => v.toJson()).toList(); } return data; } + + @override + String toString() { + return 'VehiclePosting{id: $id, userID: $userID, vehicleType: $vehicleType, vehicleModelID: $vehicleModelID, vehicleModelYearID: $vehicleModelYearID, vehicleColorID: $vehicleColorID, vehicleCategoryID: $vehicleCategoryID, vehicleConditionID: $vehicleConditionID, vehicleMileageID: $vehicleMileageID, vehicleTransmissionID: $vehicleTransmissionID, vehicleSellerTypeID: $vehicleSellerTypeID, cityID: $cityID, price: $price, vehicleVIN: $vehicleVIN, vehicleDescription: $vehicleDescription, vehicleTitle: $vehicleTitle, vehicleDescriptionN: $vehicleDescriptionN, isFinanceAvailable: $isFinanceAvailable, warantyYears: $warantyYears, demandAmount: $demandAmount, adStatus: $adStatus, vehiclePostingImages: $vehiclePostingImages, vehiclePostingDamageParts: $vehiclePostingDamageParts, phoneNo: $phoneNo, whatsAppNo: $whatsAppNo}'; + } } class VehiclePostingImages { @@ -270,13 +249,7 @@ class VehiclePostingImages { int? vehiclePostingID; String? vehiclePosting; - VehiclePostingImages( - {this.id, - this.imageName, - this.imageUrl, - this.imageStr, - this.vehiclePostingID, - this.vehiclePosting}); + VehiclePostingImages({this.id, this.imageName, this.imageUrl, this.imageStr, this.vehiclePostingID, this.vehiclePosting}); VehiclePostingImages.fromJson(Map json) { id = json['id']; @@ -307,13 +280,7 @@ class VehiclePostingDamageParts { int? vehiclePostingID; bool? isActive; - VehiclePostingDamageParts( - {this.id, - this.comment, - this.vehicleImageBase64, - this.vehicleDamagePartID, - this.vehiclePostingID, - this.isActive}); + VehiclePostingDamageParts({this.id, this.comment, this.vehicleImageBase64, this.vehicleDamagePartID, this.vehiclePostingID, this.isActive}); VehiclePostingDamageParts.fromJson(Map json) { id = json['id']; diff --git a/lib/models/payment_models/pay_order_detail_resp_model.dart b/lib/models/payment_models/pay_order_detail_resp_model.dart index ca54aeb..7ed268c 100644 --- a/lib/models/payment_models/pay_order_detail_resp_model.dart +++ b/lib/models/payment_models/pay_order_detail_resp_model.dart @@ -30,6 +30,11 @@ class PayOrderDetailRespModel { this.serviceAppointmentID, this.providerSubscriptionID}); + @override + String toString() { + return 'PayOrderDetailRespModel{id: $id, userFullName: $userFullName, userMobile: $userMobile, userEmail: $userEmail, userID: $userID, amount: $amount, currency: $currency, payFortProjectID: $payFortProjectID, payFortServiceID: $payFortServiceID, description: $description, isPaid: $isPaid, language: $language, serviceAppointmentID: $serviceAppointmentID, providerSubscriptionID: $providerSubscriptionID}'; + } + PayOrderDetailRespModel.fromJson(Map json) { id = json['id']; userFullName = json['userFullName']; diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index df78709..fb54c80 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -4,11 +4,14 @@ import 'package:mc_common_app/api/api_client.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; +import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/utils/enums.dart'; abstract class AdsRepo { Future> getVehicleTypes(); @@ -47,6 +50,8 @@ abstract class AdsRepo { Future> getAllAds({required bool isMyAds}); + Future> getMyReservedAds(); + Future> getMyAds(); } @@ -315,27 +320,46 @@ class AdsRepoImp implements AdsRepo { postParams, token: token, ); - log("value: ${adsGenericModel}"); return Future.value(adsGenericModel); } @override Future> getAllAds({required isMyAds}) async { - var params = { + var onlyMyAdsParams = { "userID": appState.getUser.data!.userInfo!.userId ?? "", }; + var allAdsParams = { + "AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS + "IsPaid": "true", //only Active ADS + }; GenericRespModel adsGenericModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsGet, - queryParameters: isMyAds ? params : null, + queryParameters: isMyAds ? onlyMyAdsParams : allAdsParams, ); List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], isMyAds)); return vehicleAdsDetails; } + @override + Future> getMyReservedAds() async { + var params = { + "userID": appState.getUser.data!.userInfo!.userId ?? "", + }; + + GenericRespModel adsGenericModel = await apiClient.getJsonForObject( + token: appState.getUser.data!.accessToken, + (json) => GenericRespModel.fromJson(json), + ApiConsts.myAdsReserveGet, + queryParameters: params, + ); + List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => MyReservedAdsRespModel.fromJson(adsGenericModel.data[index])); + return vehicleAdsDetails; + } + @override Future> getMyAds() async { var params = { diff --git a/lib/services/payments_service.dart b/lib/services/payments_service.dart index 7ff2949..74d19dc 100644 --- a/lib/services/payments_service.dart +++ b/lib/services/payments_service.dart @@ -50,10 +50,11 @@ class PaymentServiceImp implements PaymentService { required Function() onSuccess, required Function() onFailure, }) async { + print("PaymentUrl: ${ApiConsts.paymentWebViewUrl}?PaymentType=$paymentType&AdsID=$id"); myInAppBrowser = MyInAppBrowser(onExitCallback: () { log("Browser Exited"); }, onLoadStartCallback: (String url) { - log("Browser LoadStart"); + log("Browser LoadStart for : $url"); onBrowserLoadStart(onFailure: onFailure, onSuccess: onSuccess, url: url); }); await myInAppBrowser!.openUrlRequest( diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 0cc7d6f..d005c0f 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -19,11 +19,7 @@ enum AdReserveStatus { cancelledByAdmin, } -enum AdOwner { - customer, - provider, - mowater, -} +enum CreatedByRoleEnum { customer, provider, admin, allAds } enum AdPostStatus { pendingForReview, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index b7dbc27..3ba8337 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -23,13 +23,7 @@ class Utils { static void showToast(String message) { Fluttertoast.showToast( - msg: message, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.BOTTOM, - timeInSecForIosWeb: 2, - backgroundColor: Colors.black54, - textColor: Colors.white, - fontSize: 16.0); + msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 2, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); } static Future pickDateFromDatePicker(BuildContext context, {DateTime? firstDate, DateTime? lastDate}) async { @@ -54,11 +48,7 @@ class Utils { return ""; } - return ("${timeOfDay.hour - .toString() - .length == 1 ? "0" : ""}${timeOfDay.hour}:${timeOfDay.minute - .toString() - .length == 1 ? "0" : ""}${timeOfDay.minute}").toString(); + return ("${timeOfDay.hour.toString().length == 1 ? "0" : ""}${timeOfDay.hour}:${timeOfDay.minute.toString().length == 1 ? "0" : ""}${timeOfDay.minute}").toString(); } static dynamic getNotNullValue(List list, int index) { @@ -214,7 +204,6 @@ class Utils { } } - static statusContainerChip({required String text, EdgeInsetsGeometry padding = const EdgeInsets.symmetric(vertical: 3, horizontal: 6), Color chipColor = MyColors.greenColor}) { return Container( decoration: BoxDecoration( @@ -358,7 +347,7 @@ class Utils { border: Border.all( width: w, // color: color // <--- border width here - ), + ), borderRadius: BorderRadius.circular(radius), ); } @@ -381,7 +370,7 @@ class Utils { border: Border.all( width: 1, // color: color // <--- border width here - ), + ), borderRadius: BorderRadius.circular(radius), ); } diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index e7cc19c..31076db 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -9,6 +9,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; +import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; @@ -71,6 +72,7 @@ class AdVM extends BaseVM { List exploreAdsFilteredList = []; List myAdsFilteredList = []; List myAds = []; + List myReservedAdsRespModel = []; List myActiveAdsForHome = []; List vehicleDamageCards = []; @@ -140,9 +142,10 @@ class AdVM extends BaseVM { isExploreAdsTapped = value; //To show the Active Ads - applyFilterOnMyAds(index: 0, selectedFilterId: 6); + applyFilterOnMyAds(index: 0, adPostStatusEnum: AdPostStatus.active); + applyFilterOnExploreAds(index: 0, createdByRoleFilter: CreatedByRoleEnum.allAds); // if (value) { - // await getAllAds(); + // await getExploreAds(); // } notifyListeners(); } @@ -151,13 +154,12 @@ class AdVM extends BaseVM { List myAdsFilterOptions = []; populateAdsFilterList() { - exploreAdsFilterOptions.clear(); exploreAdsFilterOptions.clear(); exploreAdsFilterOptions = [ FilterListModel(title: "All Ads", isSelected: true, id: -1), - FilterListModel(title: "Customer Ads", isSelected: false, id: 0), - FilterListModel(title: "Provider Ads", isSelected: false, id: 1), - FilterListModel(title: "Mowater Ads", isSelected: false, id: 2), + FilterListModel(title: "Mowater Ads", isSelected: false, id: 1), + FilterListModel(title: "Customer Ads", isSelected: false, id: 2), + FilterListModel(title: "Provider Ads", isSelected: false, id: 3), ]; myAdsFilterOptions = [ @@ -172,7 +174,7 @@ class AdVM extends BaseVM { notifyListeners(); } - applyFilterOnExploreAds({required int index}) { + applyFilterOnExploreAds({required int index, required CreatedByRoleEnum createdByRoleFilter}) { if (exploreAdsFilterOptions.isEmpty) return; for (var value in exploreAdsFilterOptions) { value.isSelected = false; @@ -180,25 +182,39 @@ class AdVM extends BaseVM { exploreAdsFilterOptions[index].isSelected = true; // TODO: --> here we will filter the allAds list // TODO: --> and get the updated list into this new list everytime filter changes + if (createdByRoleFilter == CreatedByRoleEnum.allAds) { + exploreAdsFilteredList = exploreAds; + notifyListeners(); + return; + } + + exploreAdsFilteredList = exploreAds.where((element) => element.createdByRoleEnum == createdByRoleFilter).toList(); - exploreAdsFilteredList = exploreAds; notifyListeners(); } - applyFilterOnMyAds({required int index, required int selectedFilterId}) { + applyFilterOnMyAds({required int index, required AdPostStatus adPostStatusEnum}) { if (myAdsFilterOptions.isEmpty) return; for (var value in myAdsFilterOptions) { value.isSelected = false; } myAdsFilterOptions[index].isSelected = true; - if (selectedFilterId == -1) { + if (adPostStatusEnum.getIdFromAdPostStatusEnum() == -1) { myAdsFilteredList = myAds; notifyListeners(); return; } + // this means if the filter is reserved ads + dynamic selectedIds = []; + if (index == 3 && adPostStatusEnum.getIdFromAdPostStatusEnum() == 9) { + selectedIds = myReservedAdsRespModel.map((component) => component.adsID).toList(); + myAdsFilteredList = myAds.where((element) => selectedIds.contains(element.id)).toList(); + notifyListeners(); + return; + } - myAdsFilteredList = myAds.where((element) => element.statusID! == selectedFilterId).toList(); + myAdsFilteredList = myAds.where((element) => element.statusID! == adPostStatusEnum.getIdFromAdPostStatusEnum()).toList(); notifyListeners(); } @@ -208,15 +224,23 @@ class AdVM extends BaseVM { myAds = await adsRepo.getAllAds(isMyAds: true); final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList(); myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds; + await getMyReservedAds(); + isFetchingLists = true; + setState(ViewState.idle); + } + Future getMyReservedAds() async { isFetchingLists = true; + setState(ViewState.busy); + myReservedAdsRespModel = await adsRepo.getMyReservedAds(); + isFetchingLists = false; setState(ViewState.idle); } Future getExploreAds() async { setState(ViewState.busy); exploreAds = await adsRepo.getAllAds(isMyAds: false); - myAdsFilteredList = exploreAds; + exploreAdsFilteredList = exploreAds; setState(ViewState.idle); } @@ -844,7 +868,7 @@ class AdVM extends BaseVM { currentProgressStep = AdCreationStepsEnum.vehicleDetails; resetValues(); updateIsExploreAds(false); - applyFilterOnMyAds(index: 1, selectedFilterId: 1); + applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review navigateReplaceWithName(context, AppRoutes.dashboard); } catch (e) { Utils.hideLoading(context); @@ -1044,6 +1068,8 @@ class AdVM extends BaseVM { demandAmount: int.parse(vehicleDemandAmount), vehiclePostingImages: vehicleImages, vehiclePostingDamageParts: vehicleDamageImages, + phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null, + whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null, ); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); diff --git a/lib/view_models/payment_view_model.dart b/lib/view_models/payment_view_model.dart index f41f9b8..2fc559d 100644 --- a/lib/view_models/payment_view_model.dart +++ b/lib/view_models/payment_view_model.dart @@ -27,13 +27,13 @@ class PaymentVM extends ChangeNotifier { notifyListeners(); } - Future onContinuePressed(BuildContext context) async { + Future onContinuePressed(BuildContext context, {required PaymentTypesEnum paymentType}) async { switch (selectedPaymentMethod) { case PaymentMethodsEnum.mada: // TODO: Handle this case. break; case PaymentMethodsEnum.visa: - await onVisaCardSelected(context); + await onVisaCardSelected(context, paymentType); break; case PaymentMethodsEnum.applePay: // TODO: Handle this case. @@ -49,7 +49,8 @@ class PaymentVM extends ChangeNotifier { return; } - Future onVisaCardSelected(BuildContext context) async { + Future onVisaCardSelected(BuildContext context, PaymentTypesEnum paymentType) async { + currentPaymentType = paymentType; switch (currentPaymentType) { case PaymentTypesEnum.subscription: // TODO: Handle this case. @@ -68,10 +69,12 @@ class PaymentVM extends ChangeNotifier { }, onSuccess: () async { Utils.showLoading(context); - PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: 3); - await Future.delayed(Duration(seconds: 2)); + PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: currentAdId); + await Future.delayed(const Duration(seconds: 2)); Utils.hideLoading(context); + print("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}"); + if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) { Utils.showToast("Payment Failed!"); return; @@ -85,7 +88,33 @@ class PaymentVM extends ChangeNotifier { ); break; case PaymentTypesEnum.adReserve: - // TODO: Handle this case. + if (currentAdId == -1) return; + int paymentType = 4; + await paymentService.placeAdPayment( + id: currentAdId, + paymentType: paymentType, + onFailure: () { + Utils.showToast("Payment Failed!"); + }, + onSuccess: () async { + Utils.showLoading(context); + PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: currentAdId); + await Future.delayed(const Duration(seconds: 2)); + Utils.hideLoading(context); + + print("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}"); + + if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) { + Utils.showToast("Payment Failed!"); + return; + } + + if (payOrderDetailRespModel.isPaid != null && payOrderDetailRespModel.isPaid!) { + Utils.showToast("Payment Successfully Completed!"); + navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); + } + }, + ); break; case PaymentTypesEnum.request: // TODO: Handle this case. diff --git a/lib/views/advertisement/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view.dart index 611a945..30465cf 100644 --- a/lib/views/advertisement/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view.dart @@ -22,17 +22,16 @@ class AdsDetailView extends StatelessWidget { @override Widget build(BuildContext context) { - print("adId: ${adDetails.isMyAd}"); + print("adId: ${adDetails.id}"); + print("statusID: ${adDetails.adPostStatus}"); return Scaffold( appBar: CustomAppBar( title: "Ads", profileImageUrl: MyAssets.bnCar, isRemoveBackButton: false, isDrawerEnabled: false, - actions: [Icon(Icons.chat_outlined).paddingOnly(right: 21)], - onTap: () { - print("heyyyy"); - }, + actions: [const Icon(Icons.chat_outlined).paddingOnly(right: 21)], + onTap: () {}, ), body: Container( padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21), @@ -116,9 +115,7 @@ class AdsDetailView extends StatelessWidget { ], ), 14.height, - adDetails.isMyAd ?? false - ? BuildAdDetailsActionButtonForMyAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!) - : BuildAdDetailsActionButtonForExploreAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!), + adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: adDetails), ], ), ) @@ -130,73 +127,159 @@ class AdsDetailView extends StatelessWidget { } class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { - final AdPostStatus adPostStatus; - final int adId; + final AdDetailsModel adDetailsModel; - const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key); + const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adDetailsModel}) : 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), - ), - ), - ], - ) - ], - ); + void reserveAdPriceBreakDownClicked(BuildContext context, AdDetailsModel adDetailsModel) { + 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: [ + "${adDetailsModel.reservePrice}".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: [ + "${adDetailsModel.vehicle!.demandAmount ?? 0.0}".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: [ + // "${adDetailsModel.taxPrice}".toText(fontSize: 16, isBold: true), + // 2.width, + // "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0), + // ], + // ) + // ], + // ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + "VAT Excluded".toText(fontSize: 10, isBold: true), + ], + ), + 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: [ + "${(adDetailsModel.vehicle!.demandAmount ?? 0.0)}".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, arguments: PaymentTypesEnum.adReserve); + }, + ), + ), + ], + ), + 19.height, + ], + )); + }); } Widget cancelReservationAction(BuildContext context) { @@ -217,151 +300,7 @@ class BuildAdDetailsActionButtonForExploreAds 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, - ], - )); - }); - } - + Widget reserveAdAction(BuildContext context, AdDetailsModel adDetailsModel) { return Row( children: [ Expanded( @@ -369,67 +308,274 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { maxHeight: 55, title: "Reserve Ad", onPressed: () { - reserveAdPriceBreakDownClicked(context); + reserveAdPriceBreakDownClicked(context, adDetailsModel); // 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(() {}), + if (adDetailsModel.whatsAppNo != null) ...[ + 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(() {}), + ], + if (adDetailsModel.phoneNo != null) ...[ + 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(() {}), + ] ], ); } + Widget defaultActionForProviderAndCustomer(BuildContext context, AdDetailsModel adDetailsModel) { + return (adDetailsModel.phoneNo != null) + ? Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Contact", + fontSize: 18, + isBold: false, + iconWidget: const Padding( + padding: EdgeInsets.only(right: 10), + child: Icon(Icons.phone, color: MyColors.white, size: 24), + ), + onPressed: () {}, + ), + ), + if (adDetailsModel.whatsAppNo != null) ...[ + 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(() {}), + ], + ], + ) + : const SizedBox.shrink(); + } + @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: - return cancelReservationAction(context); - - case AdPostStatus.buyingService: - case AdPostStatus.reserveCancel: - case AdPostStatus.rejected: - case AdPostStatus.cancelled: - case AdPostStatus.pendingForPost: - case AdPostStatus.pendingForReview: - return pendingForPaymentAction(context, adID: adId); - - return defaultAction(context); + context.read().updateCurrentAdId(id: adDetailsModel.id!); + // switch (adPostStatus) { + // case AdPostStatus.pendingForPayment: + // break; + // case AdPostStatus.active: + // break; + // case AdPostStatus.reserved: + // return cancelReservationAction(context); + // + // case AdPostStatus.buyingService: + // case AdPostStatus.reserveCancel: + // case AdPostStatus.rejected: + // case AdPostStatus.cancelled: + // case AdPostStatus.pendingForPost: + // case AdPostStatus.pendingForReview: + // case AdPostStatus.sold: + // case AdPostStatus.expired: + // break; + // } + // return defaultAction(context); - return pendingForPaymentAction(context, adID: adId); - case AdPostStatus.sold: - case AdPostStatus.expired: - break; + switch (adDetailsModel.createdByRoleEnum!) { + case CreatedByRoleEnum.customer: + case CreatedByRoleEnum.provider: + return defaultActionForProviderAndCustomer(context, adDetailsModel); + case CreatedByRoleEnum.admin: + return reserveAdAction(context, adDetailsModel); + case CreatedByRoleEnum.allAds: + return SizedBox.shrink(); } - return defaultAction(context); } } class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { - final AdPostStatus adPostStatus; - final int adId; + final AdDetailsModel adDetailsModel; - const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key); + const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adDetailsModel}) : super(key: key); + + 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, + ], + )); + }); + } + + Widget pendingForReviewAction(BuildContext context, {required int adID}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Expanded( + child: ShowFillButton( + backgroundColor: MyColors.grey98Color.withOpacity(0.3), + txtColor: MyColors.lightTextColor, + maxHeight: 55, + title: "Waiting for Admins Approval", + isBold: false, + onPressed: () {}, + ), + ), + ], + ), + ], + ); + } Widget pendingForPaymentAction(BuildContext context, {required int adID}) { return Column( @@ -442,7 +588,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { maxHeight: 55, title: "Pay Now", onPressed: () { - navigateWithName(context, AppRoutes.paymentMethodsView); + navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypesEnum.ads); }, ), ), @@ -480,17 +626,18 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { ], ), 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), + Expanded( + child: ShowFillButton( + isFilled: true, + borderColor: MyColors.darkPrimaryColor, + maxHeight: 55, + title: "Deactivate Ad", + onPressed: () {}, ), ), ], - ) + ), ], ); } @@ -514,150 +661,6 @@ class BuildAdDetailsActionButtonForMyAds 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( @@ -693,10 +696,10 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { @override Widget build(BuildContext context) { - context.read().updateCurrentAdId(id: adId); - switch (adPostStatus) { + context.read().updateCurrentAdId(id: adDetailsModel.id!); + switch (adDetailsModel.adPostStatus!) { case AdPostStatus.pendingForPayment: - return pendingForPaymentAction(context, adID: adId); + return pendingForPaymentAction(context, adID: adDetailsModel.id!); case AdPostStatus.active: return markAsSoldAction(context); case AdPostStatus.reserved: @@ -707,10 +710,9 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { case AdPostStatus.cancelled: case AdPostStatus.pendingForPost: case AdPostStatus.pendingForReview: - break; - return defaultAction(context); + return pendingForReviewAction(context, adID: adDetailsModel.id!); - return pendingForPaymentAction(context, adID: adId); + // return pendingForPaymentAction(context, adID: adId); case AdPostStatus.sold: case AdPostStatus.expired: break; diff --git a/lib/views/advertisement/ads_list.dart b/lib/views/advertisement/ads_list.dart index c5e0e26..afdaa3f 100644 --- a/lib/views/advertisement/ads_list.dart +++ b/lib/views/advertisement/ads_list.dart @@ -53,7 +53,7 @@ class BuildAdsList extends StatelessWidget { separatorBuilder: (BuildContext context, int index) { return 12.height; }, - padding: EdgeInsets.symmetric(horizontal: 21), + padding: const EdgeInsets.symmetric(horizontal: 21), ); } } @@ -99,10 +99,7 @@ class AdCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - if (isAdsFragment && context.read().isExploreAdsTapped) ...[ - Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), - ], - if (shouldShowAdStatus) ...[ + if (isAdsFragment && !context.read().isExploreAdsTapped) ...[ Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), ], (adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, isBold: true), diff --git a/lib/views/advertisement/bottom_sheet_content.dart b/lib/views/advertisement/bottom_sheet_content.dart index 6698f63..6a270ba 100644 --- a/lib/views/advertisement/bottom_sheet_content.dart +++ b/lib/views/advertisement/bottom_sheet_content.dart @@ -104,7 +104,6 @@ class _BottomSheetListContentState extends State { const SizedBox(width: 20), vehiclePart.partName.toString().toText( fontSize: 16, - isBold: true, color: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.black, ) ], diff --git a/lib/views/payments/payment_methods_view.dart b/lib/views/payments/payment_methods_view.dart index c96b521..01d6071 100644 --- a/lib/views/payments/payment_methods_view.dart +++ b/lib/views/payments/payment_methods_view.dart @@ -11,7 +11,9 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:provider/provider.dart'; class PaymentMethodsView extends StatelessWidget { - const PaymentMethodsView({Key? key}) : super(key: key); + final PaymentTypesEnum paymentType; + + const PaymentMethodsView({Key? key, required this.paymentType}) : super(key: key); @override Widget build(BuildContext context) { @@ -68,7 +70,7 @@ class PaymentMethodsView extends StatelessWidget { maxHeight: 55, title: "Continue", onPressed: () { - context.read().onContinuePressed(context); + context.read().onContinuePressed(context, paymentType: paymentType); }, backgroundColor: MyColors.darkPrimaryColor, ), diff --git a/lib/views/user/login_with_password_page.dart b/lib/views/user/login_with_password_page.dart index c3d4005..0d74b32 100644 --- a/lib/views/user/login_with_password_page.dart +++ b/lib/views/user/login_with_password_page.dart @@ -29,7 +29,7 @@ class _LoginWithPasswordState extends State { ClassType type = ClassType.EMAIL; //TODO: ONLY FOR DEVELOPMENT PURPOSE - String phoneNum = "966504278212", password = "Fa@123"; + String phoneNum = "966504278213", password = "Fa@1234"; String email = ""; String countryCode = ""; Country? _country; diff --git a/lib/widgets/button/show_fill_button.dart b/lib/widgets/button/show_fill_button.dart index 644870c..e55f813 100644 --- a/lib/widgets/button/show_fill_button.dart +++ b/lib/widgets/button/show_fill_button.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; class ShowFillButton extends StatelessWidget { String title; @@ -12,6 +13,7 @@ class ShowFillButton extends StatelessWidget { EdgeInsets? margin; bool isFilled; Color borderColor; + Widget? iconWidget; ShowFillButton({ super.key, @@ -31,6 +33,7 @@ class ShowFillButton extends StatelessWidget { this.horizontalMargin = 0, this.verticalMargin = 0, this.margin, + this.iconWidget, this.borderColor = MyColors.primaryColor, }); @@ -62,21 +65,37 @@ class ShowFillButton extends StatelessWidget { Widget showButton() { return Container( // decoration: isFlatButton ? null : MyColors.gradientButton, - color: isFlatButton ? null : isFilled ? backgroundColor : null, + color: isFlatButton + ? null + : isFilled + ? backgroundColor + : null, margin: EdgeInsets.symmetric(horizontal: horizontalMargin, vertical: verticalMargin), child: MaterialButton( onPressed: onPressed, - shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radius), - side: isFilled ? BorderSide.none: BorderSide(width: 2, color: borderColor), - ), - child: title.toText( - fontSize: fontSize, - isBold: isBold, - color: txtColor, - maxLines: 1, + side: isFilled ? BorderSide.none : BorderSide(width: 2, color: borderColor), ), + child: iconWidget != null + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + iconWidget!, + title.toText( + fontSize: fontSize, + isBold: isBold, + color: txtColor, + maxLines: 1, + ), + ], + ) + : title.toText( + fontSize: fontSize, + isBold: isBold, + color: txtColor, + maxLines: 1, + ), ), ); } From b766157d7f821f97ca2966589be6fe52cbd9bd52 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Sun, 17 Sep 2023 15:06:20 +0300 Subject: [PATCH 12/12] Ad Module Commit --- pubspec.lock | 1087 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1087 insertions(+) create mode 100644 pubspec.lock diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..18dfded --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,1087 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + 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: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + 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" + country_code_picker: + dependency: "direct main" + description: + name: country_code_picker + sha256: "92818885f0e47486539f80463b66f649970506a91dd3c0731ca3ba5308324a4d" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb + url: "https://pub.dev" + source: hosted + version: "0.3.3+5" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1 + url: "https://pub.dev" + source: hosted + version: "2.3.9" + easy_localization: + dependency: "direct main" + description: + name: easy_localization + sha256: de63e3b422adfc97f256cbb3f8cf12739b6a4993d390f3cadb3f51837afaefe5 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + 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" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" + url: "https://pub.dev" + source: hosted + version: "0.9.2+1" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "182c3f8350cee659f7b115e956047ee3dc672a96665883a545e81581b9a82c72" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" + url: "https://pub.dev" + source: hosted + version: "2.6.1" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + url: "https://pub.dev" + source: hosted + version: "0.9.3+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: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" + url: "https://pub.dev" + source: hosted + version: "3.3.1" + 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: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + url: "https://pub.dev" + source: hosted + version: "2.0.3" + 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: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c + url: "https://pub.dev" + source: hosted + version: "2.0.16" + 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: "9d6eff112971b9f195271834b390fc0e1899a9a6c96225ead72efd5d4aaa80c7" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + 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: "36527c555f4c425f7d8fa8c7c07d67b78e3ff7590d40448051959e1860c1cfb4" + url: "https://pub.dev" + source: hosted + version: "2.2.7" + 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: "463045515b08bd83f73e014359c4ad063b902eb3899952cfb784497ae6c6583b" + url: "https://pub.dev" + source: hosted + version: "0.2.0" + google_maps: + dependency: transitive + description: + name: google_maps + sha256: "555d5d736339b0478e821167ac521c810d7b51c3b2734e6802a9f046b64ea37a" + url: "https://pub.dev" + source: hosted + version: "6.3.0" + google_maps_flutter: + dependency: "direct main" + description: + name: google_maps_flutter + sha256: d4914cb38b3dcb62c39c085d968d434de0f8050f00f4d9f5ba4a7c7e004934cb + url: "https://pub.dev" + source: hosted + version: "2.5.0" + google_maps_flutter_android: + dependency: transitive + description: + name: google_maps_flutter_android + sha256: e6cb018169e49332f88d23b1d2119b09e8ab4e7d3a1b889a1b7b3fd113e034ba + url: "https://pub.dev" + source: hosted + version: "2.5.1" + google_maps_flutter_ios: + dependency: transitive + description: + name: google_maps_flutter_ios + sha256: "2a595c9789070786c654e9772ec0d1bb759ae37d2dd776291af5398531274e06" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + google_maps_flutter_platform_interface: + dependency: transitive + description: + name: google_maps_flutter_platform_interface + sha256: a3e9e6896501e566d902c6c69f010834d410ef4b7b5c18b90c77e871c86b7907 + url: "https://pub.dev" + source: hosted + version: "2.4.1" + google_maps_flutter_web: + dependency: transitive + description: + name: google_maps_flutter_web + sha256: "05067c5aa762ebee44b7ef4902a311ed8cf891ef655e2798bae063aa3050c8d9" + url: "https://pub.dev" + source: hosted + version: "0.5.4+1" + hexcolor: + dependency: "direct main" + description: + name: hexcolor + sha256: c07f4bbb9095df87eeca87e7c69e8c3d60f70c66102d7b8d61c4af0453add3f6 + url: "https://pub.dev" + source: hosted + version: "3.0.1" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" + http: + dependency: "direct main" + description: + name: http + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" + source: hosted + version: "0.13.6" + 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: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c + url: "https://pub.dev" + source: hosted + version: "0.8.9" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: d32a997bcc4ee135aebca8e272b7c517927aa65a74b9c60a81a2764ef1a0462d + url: "https://pub.dev" + source: hosted + version: "0.8.7+5" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: c5538cacefacac733c724be7484377923b476216ad1ead35a0d2eadcdc0fc497 + url: "https://pub.dev" + source: hosted + version: "0.8.8+2" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 + url: "https://pub.dev" + source: hosted + version: "2.9.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + 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" + js_wrapping: + dependency: transitive + description: + name: js_wrapping + sha256: e385980f7c76a8c1c9a560dfb623b890975841542471eade630b2871d243851c + url: "https://pub.dev" + source: hosted + version: "0.7.4" + lints: + dependency: transitive + description: + name: lints + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + local_auth: + dependency: "direct main" + description: + name: local_auth + sha256: "7e6c63082e399b61e4af71266b012e767a5d4525dd6e9ba41e174fd42d76e115" + url: "https://pub.dev" + source: hosted + version: "2.1.7" + local_auth_android: + dependency: transitive + description: + name: local_auth_android + sha256: "9ad0b1ffa6f04f4d91e38c2d4c5046583e23f4cae8345776a994e8670df57fb1" + url: "https://pub.dev" + source: hosted + version: "1.0.34" + local_auth_ios: + dependency: transitive + description: + name: local_auth_ios + sha256: "26a8d1ad0b4ef6f861d29921be8383000fda952e323a5b6752cf82ca9cf9a7a9" + url: "https://pub.dev" + source: hosted + version: "1.1.4" + local_auth_platform_interface: + dependency: transitive + description: + name: local_auth_platform_interface + sha256: fc5bd537970a324260fda506cfb61b33ad7426f37a8ea5c461cf612161ebba54 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + local_auth_windows: + dependency: transitive + description: + name: local_auth_windows + sha256: "505ba3367ca781efb1c50d3132e44a2446bccc4163427bc203b9b4d8994d97ea" + url: "https://pub.dev" + source: hosted + version: "1.0.10" + logger: + dependency: "direct main" + description: + name: logger + sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f" + url: "https://pub.dev" + source: hosted + version: "1.4.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" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + 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: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905 + url: "https://pub.dev" + source: hosted + version: "2.0.7" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81" + url: "https://pub.dev" + source: hosted + version: "10.4.3" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: d74e77a5ecd38649905db0a7d05ef16bed42ff263b9efb73ed794317c5764ec3 + url: "https://pub.dev" + source: hosted + version: "10.3.4" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + url: "https://pub.dev" + source: hosted + version: "9.1.4" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9" + url: "https://pub.dev" + source: hosted + version: "3.11.3" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + url: "https://pub.dev" + source: hosted + version: "0.1.3" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + url: "https://pub.dev" + source: hosted + version: "5.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + url: "https://pub.dev" + source: hosted + version: "2.1.6" + 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" + sanitize_html: + dependency: transitive + description: + name: sanitize_html + sha256: "0a445f19bbaa196f5a4f93461aa066b94e6e025622eb1e9bc77872a5e25233a5" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + url: "https://pub.dev" + source: hosted + version: "2.3.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a + url: "https://pub.dev" + source: hosted + version: "2.3.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + url: "https://pub.dev" + source: hosted + version: "2.3.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f + url: "https://pub.dev" + source: hosted + version: "2.3.1" + 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" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + 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: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" + url: "https://pub.dev" + source: hosted + version: "6.1.14" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 + url: "https://pub.dev" + source: hosted + version: "6.1.0" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" + url: "https://pub.dev" + source: hosted + version: "6.1.5" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e + url: "https://pub.dev" + source: hosted + version: "3.0.6" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 + url: "https://pub.dev" + source: hosted + version: "3.0.7" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 + url: "https://pub.dev" + source: hosted + version: "2.0.19" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" + url: "https://pub.dev" + source: hosted + version: "3.0.8" + uuid: + dependency: transitive + description: + name: uuid + sha256: e03928880bdbcbf496fb415573f5ab7b1ea99b9b04f669c01104d085893c3134 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + 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: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + xml: + dependency: transitive + description: + name: xml + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + url: "https://pub.dev" + source: hosted + version: "6.3.0" +sdks: + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.10.0"