Merge pull request 'Common Push Ads and Appointment' (#3) from faiz_development_common into master

Reviewed-on: http://34.17.52.79/Haroon6138/car_common_app/pulls/3
models_removal
Mirza Shafique 2 years ago
commit d200584634

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32.302" height="21.85" viewBox="0 0 32.302 21.85">
<g id="buggy" transform="translate(0.002 -82.84)">
<g id="Page-1_7_" transform="translate(-0.002 82.84)">
<g id="mobility_filled_7_" transform="translate(0 0)">
<path id="buggy_x2C_-lightweight_x2C_-offroad_x2C_-car_x2C_-vehicle" d="M304.437,641.49l-.263-.525a.95.95,0,0,1-.082-.611l.95-4.75a.95.95,0,0,1,.932-.764h8.55a.95.95,0,0,1,.773.4l4.466,6.252h3.217a4.75,4.75,0,0,1,4.341,2.821l.9,2.018a.95.95,0,0,1-.868,1.336h-3.907l.327.98a4.037,4.037,0,1,1-1.78.67l-.55-1.65h-.694L317.7,652.45a.95.95,0,0,1-.8.44h-10.45a.95.95,0,0,1-.865-.557l-2.122-4.668h-.6l-.55,1.65a4.038,4.038,0,1,1-2.272-.7,4.078,4.078,0,0,1,.493.03l.327-.98h-3.907a.95.95,0,0,1-.868-1.336l1.9-4.275a.95.95,0,0,1,.868-.564h5.588Zm9.137,2.768-.278.278a.95.95,0,0,1-1.343-1.343l1.9-1.9a.95.95,0,0,1,1.343,1.343l-.278.278L316.4,644.4l1.671-2.006-4.039-5.655h-7.282l-.733,3.667,3.392,6.783h4.668l1.1-1.324ZM300.037,654.79a2.137,2.137,0,1,0-2.137-2.137A2.137,2.137,0,0,0,300.037,654.79Zm24.225,0a2.137,2.137,0,1,0-2.137-2.137A2.137,2.137,0,0,0,324.262,654.79Z" transform="translate(-295.998 -634.84)" fill="#28323a"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="34.298" height="13.328" viewBox="0 0 34.298 13.328">
<g id="car_10_" data-name="car (10)" transform="translate(-1.121 -15.731)">
<path id="Path_4736" data-name="Path 4736" d="M33.548,20.3a51.525,51.525,0,0,0-7.177-1.148c-.287-.072,0,0-4.378-2.656a3.75,3.75,0,0,0-1.507-.5c-4.952-.574-10.766-.431-14.714,2.656-.215.144-.359.287-.574.287l-2.3.718a1.486,1.486,0,0,0-.933.79,6.2,6.2,0,0,0-.646,4.665,1.627,1.627,0,0,0,1.22,1.22l.574.144c0-.215-.072-.359-.072-.574a4.665,4.665,0,0,1,9.331,0,4.236,4.236,0,0,1-.144,1H25.366a4.847,4.847,0,0,1-.144-1,4.665,4.665,0,1,1,9.331,0,3.5,3.5,0,0,1-.072.861,1.783,1.783,0,0,0,.933-1.579V22.958A2.522,2.522,0,0,0,33.548,20.3Zm-21.1-.072a.653.653,0,0,1-.574-.287L10.15,17.862a18.324,18.324,0,0,1,5.527-.79l.861,3.158Zm11.771-.072a.647.647,0,0,1-.359.072H18.045l-.861-3.086,3.015.215a2.339,2.339,0,0,1,.933.287L24.648,19.8Z" transform="translate(0)" fill="#28323a"/>
<circle id="Ellipse_234" data-name="Ellipse 234" cx="3.23" cy="3.23" r="3.23" transform="translate(4.479 22.599)" fill="#28323a"/>
<circle id="Ellipse_235" data-name="Ellipse 235" cx="3.23" cy="3.23" r="3.23" transform="translate(26.73 22.599)" fill="#28323a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,5 @@
<svg id="golf-cart" xmlns="http://www.w3.org/2000/svg" width="33.26" height="25.5" viewBox="0 0 33.26 25.5">
<path id="Path_4733" data-name="Path 4733" d="M13.761,44.88A3.88,3.88,0,1,1,9.88,41,3.88,3.88,0,0,1,13.761,44.88Zm-2.217,0A1.663,1.663,0,1,0,9.88,46.543,1.663,1.663,0,0,0,11.543,44.88Z" transform="translate(17.282 -23.261)" fill="#28323a"/>
<path id="Path_4734" data-name="Path 4734" d="M50.761,44.88A3.88,3.88,0,1,1,46.88,41a3.88,3.88,0,0,1,3.88,3.88Zm-2.217,0a1.663,1.663,0,1,0-1.663,1.663,1.663,1.663,0,0,0,1.663-1.663Z" transform="translate(-40.228 -23.261)" fill="#28323a"/>
<path id="Path_4735" data-name="Path 4735" d="M34.152,30.619A4.989,4.989,0,0,0,27.5,25.891a4.939,4.939,0,0,0-3.326,4.728l-10.532.554h-.033a4.579,4.579,0,0,0,.033-.554,4.989,4.989,0,0,0-9.978,0,4.579,4.579,0,0,0,.033.554H2.554A7.207,7.207,0,0,1,2,29.51a.554.554,0,0,1,.554-.554V28.4c0-3.293,1.608-6.264,4.435-7V11.772A1.109,1.109,0,0,1,5.88,10.663v-.554A1.109,1.109,0,0,1,6.989,9h16.8a.948.948,0,0,1,.937.942v.887a.948.948,0,0,1-.937.942L29.467,22.11l.682.1a5.627,5.627,0,0,1,1.935.6,6.353,6.353,0,0,1,3.176,5.033A4.462,4.462,0,0,1,34.152,30.619Zm-6.536-8.775L22.084,11.772H9.206v9.241l1.109-.371V18.507a.882.882,0,0,1,1.763-.083l.349,3.88a1.253,1.253,0,0,0,1.214,1.109h1.48a1.663,1.663,0,0,1,1.619,1.325.87.87,0,0,1-.759,1.026l-1.84.244-.033.044.554,2.323h8.77l.033-.039-.222-3.98-3.3-3.3-.665.665a.557.557,0,1,1-.787-.787l2.118-2.112a.566.566,0,1,1,.793.809l-.665.665,2.422,2.422-.05-.887a.554.554,0,0,1,.6-.554Z" transform="translate(-2 -9)" fill="#28323a"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="34.141" height="21.621" viewBox="0 0 34.141 21.621">
<g id="transportation" transform="translate(-1.505 -12.69)">
<path id="Path_4726" data-name="Path 4726" d="M10.229,39.426h2.407a2.547,2.547,0,1,1,0-1.679H10.229a.84.84,0,0,0,0,1.679Z" transform="translate(-2.72 -10.278)" fill="#28323a"/>
<path id="Path_4727" data-name="Path 4727" d="M52.316,38.586A2.553,2.553,0,1,1,47.8,36.957a24.27,24.27,0,0,0,2.043,2.631.835.835,0,0,0,1.192.039.844.844,0,0,0,.034-1.187,21.472,21.472,0,0,1-1.819-2.351,2.557,2.557,0,0,1,3.062,2.5Z" transform="translate(-20.118 -10.278)" fill="#28323a"/>
<path id="Path_4728" data-name="Path 4728" d="M47.055,29.879a5.964,5.964,0,0,0-2.362.487c.521.963,1.041,1.808,1.517,2.519a3.023,3.023,0,0,1,.845-.118,3.12,3.12,0,1,1-2.278,1c-.481-.722-1-1.568-1.523-2.525a6,6,0,1,0,3.8-1.36Z" transform="translate(-17.411 -7.566)" fill="#28323a"/>
<path id="Path_4729" data-name="Path 4729" d="M46.7,18.615v1.9a.829.829,0,0,1-.549.784,6.81,6.81,0,0,1-2.4.375,29.7,29.7,0,0,1-1.31-3.695,4.115,4.115,0,0,1,3.874-.067.8.8,0,0,1,.386.7Z" transform="translate(-18.018 -2.096)" fill="#28323a"/>
<path id="Path_4730" data-name="Path 4730" d="M18.124,40.089a2.341,2.341,0,0,1,0,.56H12.01a.28.28,0,0,1,0-.56Z" transform="translate(-4.501 -12.06)" fill="#28323a"/>
<path id="Path_4731" data-name="Path 4731" d="M30.743,28.947a.274.274,0,0,1-.392-.011A31.887,31.887,0,0,1,25.43,21.2c-.778.308-3.393,1.719-3.2,6.751a.968.968,0,0,1-.4.834A6.2,6.2,0,0,1,18.2,29.854a10.271,10.271,0,0,1-3.952-.873q.034-.336.034-.672a6.563,6.563,0,0,0-6.751-6.55,1.08,1.08,0,0,0-.213-.537,1.191,1.191,0,0,0-.823-.442,10.752,10.752,0,0,1-4.036-.453.728.728,0,0,1-.28-1.181c1.215-1.22,2.973-1.763,5.693-1.763a4.7,4.7,0,0,1,2.967,1.142,9.953,9.953,0,0,1,.974,1.556.576.576,0,0,0,.493.28c.885.017,2.62,0,3.5-.017a.56.56,0,0,0,.532-.392,4.128,4.128,0,0,1,4.669-3.012c.481.084,1.993.336,2.491-.05a.448.448,0,0,0,.168-.3c-.291-.952-.549-1.948-.761-2.984a.442.442,0,0,0-.465-.353,4.793,4.793,0,0,0-2.911,1.288.287.287,0,0,1-.4,0,.28.28,0,0,1,0-.4A5.3,5.3,0,0,1,22.385,12.7a.988.988,0,0,1,1.069.795,36.988,36.988,0,0,0,7.3,15.059.28.28,0,0,1-.011.4Z" transform="translate(-0.208)" fill="#28323a"/>
<path id="Path_4732" data-name="Path 4732" d="M7.509,38.983a3.11,3.11,0,1,1,3-3.952h2.945a6,6,0,1,0,0,1.679H10.5a3.12,3.12,0,0,1-3,2.273Z" transform="translate(0 -7.562)" fill="#28323a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -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";
@ -76,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";
@ -91,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";
@ -124,7 +127,9 @@ 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 =
"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.";
}
@ -194,6 +199,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";

@ -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';
@ -33,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";
@ -53,40 +45,47 @@ class AppRoutes {
static const String dashboard = "/dashboard";
static const String bookProviderAppView = "/bookProviderAppView";
static const String appointmentDetailView = "/appointmentDetailView";
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 bookAppointmenServicesView = "/bookAppointmenServicesView";
static const String adsSearchFilterScreen = "/adsSearchFilterScreen";
// Payments
static const String paymentMethodsView = "/paymentMethodsView";
//Customer APP: Provider & Services
static const String branchDetailPage = "/branchDetailPage";
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<String, WidgetBuilder> 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(),
};
}

@ -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(
@ -14,6 +15,7 @@ extension EmailValidator on String {
TextDecoration? textDecoration,
double letterSpacing = -0.4,
TextAlign? textAlign,
FontWeight? fontWeight,
double? height,
int? maxLines}) =>
AutoSizeText(
@ -25,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,
),
@ -180,6 +182,94 @@ 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) {
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 {
CreatedByRoleEnum toCreatedByRoleEnum() {
if (this == -1) {
return CreatedByRoleEnum.allAds;
} else if (this == 1) {
return CreatedByRoleEnum.admin;
} else if (this == 2) {
return CreatedByRoleEnum.customer;
} else if (this == 3) {
return CreatedByRoleEnum.provider;
}
return CreatedByRoleEnum.customer;
}
}
extension BranchsEnum on int {
BranchStatusEnum toBranchStatusEnum() {
if (this == 1) {
@ -246,3 +336,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;
}
}
}

@ -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<NavigatorState>();
Logger logger = Logger(

@ -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';
@ -36,6 +38,11 @@ class AdDetailsModel {
bool? isMCHandled;
String? modifiedOn;
AdPostStatus? adPostStatus;
AdReserveStatus? adReserveStatus;
bool? isMyAd;
String? phoneNo;
String? whatsAppNo;
CreatedByRoleEnum? createdByRoleEnum;
AdDetailsModel(
{this.id,
@ -69,9 +76,20 @@ class AdDetailsModel {
this.reservePrice,
this.isMCHandled,
this.adPostStatus,
this.adReserveStatus,
this.isMyAd,
this.phoneNo,
this.whatsAppNo,
this.createdByRoleEnum,
this.modifiedOn});
AdDetailsModel.fromJson(Map<String, dynamic> json) {
int getRandomValue({required int min, required int max}) {
Random random = Random();
int randomNumber = random.nextInt(max - min);
return randomNumber;
}
AdDetailsModel.fromJson(Map<String, dynamic> json, bool isMyAds) {
id = json['id'];
startdate = json['startdate'];
enddate = json['enddate'];
@ -82,12 +100,6 @@ class AdDetailsModel {
specialservice!.add(SpecialServiceModel.fromJson(v));
});
}
// if (json['reserved'] != null) {
// reserved = <Null>[];
// json['reserved'].forEach((v) {
// reserved!.add(Null.fromJson(v));
// });
// }
statusID = json['statusID'];
statuslabel = json['statuslabel'];
adsDurationPrice = json['adsDurationPrice'];
@ -113,7 +125,14 @@ 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;
createdByRoleEnum = CreatedByRoleEnum.admin;
// createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum();
isMyAd = isMyAds;
}
Map<String, dynamic> toJson() {

@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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;
}
}

@ -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<VehicleBrandsModel>? vehicleBrands;
List<VehicleCategoryModel>? 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<String, dynamic> json) {
id = json['id'];
vehicleTypeName = json['vehicleTypeName'];
vehicleTypeNameN = json['vehicleTypeNameN'];
isActive = json['isActive'];
vehicleTypeEnum = (json['id'] as int).getVehicleTypeEnum();
}
Map<String, dynamic> toJson() {

@ -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<String, dynamic> 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<String, dynamic> toJson() {
@ -111,13 +86,7 @@ class Ads {
List<int>? 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<String, dynamic> json) {
id = json['id'];
@ -164,31 +133,35 @@ class VehiclePosting {
int? adStatus;
List<VehiclePostingImages>? vehiclePostingImages;
List<VehiclePostingDamageParts>? 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<String, dynamic> 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 = <VehiclePostingImages>[];
json['vehiclePostingImages'].forEach((v) {
@ -221,8 +196,7 @@ class VehiclePosting {
if (json['vehiclePostingDamageParts'] != null) {
vehiclePostingDamageParts = <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<String, dynamic> 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<String, dynamic> json) {
id = json['id'];

@ -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<String, dynamic> 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<String, dynamic> 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<BranchModel>? serviceProviderBranch;
final List<BranchDetailModel>? serviceProviderBranch;
factory ProviderModelData.fromJson(Map<String, dynamic> 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<BranchModel>.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<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
);
Map<String, dynamic> 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<dynamic>.from(serviceProviderBranch!.map((x) => x.toJson())),
};
}

@ -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<String, dynamic> json) {
id = json['id'];
userFullName = json['userFullName'];

@ -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<String, dynamic> json) => BranchModel(
factory BranchDetailModel.fromJson(Map<String, dynamic> json) => BranchDetailModel(
id: json["id"],
serviceProviderId: json["serviceProviderID"],
serviceProviderName: json["serviceProviderName"],

@ -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));

@ -23,18 +23,18 @@ class Services {
factory Services.fromJson(Map<String, dynamic> json) =>
Services(
totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : List<ServicesData>.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<String, dynamic> toJson() =>
{
"totalItemsCount": totalItemsCount == null ? null : totalItemsCount,
"totalItemsCount": totalItemsCount,
"data": data == null ? null : List<dynamic>.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<String, dynamic> 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<String, dynamic> 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,
};
}

@ -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<BranchDetailModel>? serviceProviderBranch;
factory ProviderProfileModel.fromJson(Map<String, dynamic> 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<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"companyName": companyName,
"companyDescription": companyDescription,
"allDocStatus": allDocStatus,
"isValidSubscription": isValidSubscription,
"userID": userId,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x.toJson())),
};
}

@ -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<String, dynamic> json) {
id = json['id'];
categoryName = json['categoryName'];
categoryNameN = json['categoryNameN'];
serviceCategoryIconUrl = json['serviceCategoryIconUrl'];
serviceCategoryImageUrl = json['serviceCategoryImageUrl'];
isActive = json['isActive'];
isSelected = false;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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<String, dynamic> json) {
// id = json['id'];
// categoryName = json['categoryName'];
// categoryNameN = json['categoryNameN'];
// serviceCategoryIconUrl = json['serviceCategoryIconUrl'];
// serviceCategoryImageUrl = json['serviceCategoryImageUrl'];
// isActive = json['isActive'];
// isSelected = false;
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = <String, dynamic>{};
// data['id'] = id;
// data['categoryName'] = categoryName;
// data['categoryNameN'] = categoryNameN;
// data['serviceCategoryIconUrl'] = serviceCategoryIconUrl;
// data['serviceCategoryImageUrl'] = serviceCategoryImageUrl;
// data['isActive'] = isActive;
// return data;
// }
// }

@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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<String, dynamic> 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<String, dynamic> toJson() {
// final Map<String, dynamic> data = <String, dynamic>{};
// 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}';
// }
// }

@ -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<WeeklyOffDay>? weeklyOffDays;
final List<ScheduleService>? scheduleServices;
final List<ServiceModel>? scheduleServices;
final List<ServiceModel>? 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<WeeklyOffDay>.from(json["weeklyOffDays"]!.map((x) => WeeklyOffDay.fromJson(x))),
scheduleServices: json["scheduleServices"] == null ? [] : List<ScheduleService>.from(json["scheduleServices"]!.map((x) => ScheduleService.fromJson(x))),
scheduleServices: json["scheduleServices"] == null ? [] : List<ServiceModel>.from(json["scheduleServices"]!.map((x) => ServiceModel.fromJson(x))),
selectedServices: [],
);
Map<String, dynamic> toJson() =>
@ -111,33 +116,14 @@ class ScheduleData {
"longitude": longitude,
"scheduleServices": scheduleServices == null ? [] : List<dynamic>.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<String, dynamic> json) =>
ScheduleService(
providerServiceId: json["providerServiceID"],
// branchScheduleGroupServiceID: json["branchScheduleGroupServiceID"],
providerServiceName: json["providerServiceName"],
);
Map<String, dynamic> 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;

@ -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>? serviceSlotList;
List<ItemData>? serviceItemList;
String? selectedDate;
String? selectedTimeSlot;
List<TimeSlotModel>? availableDates;
List<TimeSlotModel>? 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<TimeSlotModel> getFormattedSlotTimes() {
var seenSlots = <TimeSlotModel>{};
var slotTimeData = serviceSlotList!
.where((slot) => seenSlots.add(TimeSlotModel(
slot: slot.startTime!,
slotId: slot.id!,
isSelected: false,
)))
.toList();
List<TimeSlotModel> slotTime = [];
for (var element in slotTimeData) {
slotTime.add(TimeSlotModel(isSelected: false, slotId: element.id!, slot: element.slotDate ?? ""));
}
return slotTime;
}
List<TimeSlotModel> getFormattedSlotDates() {
var seenDates = <TimeSlotModel>{};
var slotDatesData = serviceSlotList!
.where((slot) => seenDates.add(TimeSlotModel(
slot: slot.slotDate!,
slotId: slot.id!,
isSelected: false,
)))
.toList();
List<TimeSlotModel> 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<String, dynamic> json) {
if (json['serviceSlotList'] != null) {
serviceSlotList = <ServiceSlotList>[];
json['serviceSlotList'].forEach((v) {
serviceSlotList!.add(ServiceSlotList.fromJson(v));
});
}
if (json['serviceItemList'] != null) {
serviceItemList = <ItemData>[];
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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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;
}
}

@ -22,18 +22,18 @@ class ItemModel {
});
factory ItemModel.fromJson(Map<String, dynamic> json) => ItemModel(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<ItemData>.from(json["data"]!.map((x) => ItemData.fromJson(x))),
message: json["message"],
);
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<ItemData>.from(json["data"]!.map((x) => ItemData.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
}
class ItemData {
@ -49,6 +49,7 @@ class ItemData {
final bool? isAllowAppointment;
final bool? isAppointmentCompanyLoc;
final bool? isAppointmentCustomerLoc;
final double? appointmentPricePercentage;
bool? isUpdateOrSelected;
ItemData({
@ -64,37 +65,38 @@ class ItemData {
this.isAllowAppointment,
this.isAppointmentCompanyLoc,
this.isAppointmentCustomerLoc,
this.appointmentPricePercentage,
this.isUpdateOrSelected,
});
factory ItemData.fromJson(Map<String, dynamic> 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"],
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<String, dynamic> 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,
};
}

@ -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<BranchModel>? data;
final String? message;
NearBrancheModel({
this.messageStatus,
this.totalItemsCount,
this.data,
this.message,
});
factory NearBrancheModel.fromJson(Map<String, dynamic> json) => NearBrancheModel(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<BranchModel>.from(json["data"]!.map((x) => BranchModel.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
}

@ -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<dynamic>.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}';
}
}

@ -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<CountryCode>? onChanged;
final ValueChanged<CountryCode?>? onInit;
final String? initialSelection;
final List<String> 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<String>? 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<CountryCode>? 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<Map<String, String>> 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<StatefulWidget> createState() {
List<Map<String, String>> jsonList = countryList;
List<CountryCode> 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<CustomCountryCodePicker> {
CountryCode? selectedItem;
List<CountryCode> elements = [];
List<CountryCode> 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: <Widget>[
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);
}
}
}

@ -1,16 +1,23 @@
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';
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<List<VehicleTypeModel>> getVehicleTypes();
Future<List<VehicleBrandsModel>> getVehicleBrands({required int vehicleTypeId});
Future<List<VehicleModel>> getVehicleModels({required int vehicleTypeId});
Future<List<VehicleYearModel>> getVehicleModelYears({required int vehicleTypeId});
@ -33,7 +40,7 @@ abstract class AdsRepo {
Future<List<VehiclePartModel>> getVehicleDamageParts();
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId});
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId, required int vehicleBrandId});
Future<List<AdsDurationModel>> getAdsDuration();
@ -43,6 +50,8 @@ abstract class AdsRepo {
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds});
Future<List<MyReservedAdsRespModel>> getMyReservedAds();
Future<List<AdDetailsModel>> getMyAds();
}
@ -145,6 +154,17 @@ class AdsRepoImp implements AdsRepo {
return vehicleModels;
}
@override
Future<List<VehicleBrandsModel>> 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<VehicleBrandsModel> vehicleBrands = List.generate(adsGenericModel.data.length, (index) => VehicleBrandsModel.fromJson(adsGenericModel.data[index]));
return vehicleBrands;
}
@override
Future<List<VehicleSellerTypeModel>> getVehicleSellerTypes({required int vehicleTypeId}) async {
var postParams = {
@ -168,11 +188,11 @@ class AdsRepoImp implements AdsRepo {
}
@override
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId}) async {
Future<VehicleDetailsModel> 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",
@ -306,17 +326,37 @@ class AdsRepoImp implements AdsRepo {
@override
Future<List<AdDetailsModel>> 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<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], isMyAds));
return vehicleAdsDetails;
}
@override
Future<List<MyReservedAdsRespModel>> 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<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
List<MyReservedAdsRespModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => MyReservedAdsRespModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
}
@ -331,7 +371,7 @@ class AdsRepoImp implements AdsRepo {
queryParameters: params,
ApiConsts.vehicleAdsGet,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], true));
return vehicleAdsDetails;
}
}

@ -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<Role> getRoles();
Future<List<AppointmentListModel>> getMyAppointments();
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long});
Future<SSPhotoScheduleModel> getPhotographyServiceScheduleDetails({required double lat, required double long});
Future<List<ProviderCategoryModel>> getProviderServiceCategories();
// Future<List<ProviderCategoryModel>> getProviderServiceCategories();
Future<List<ProviderServiceModel>> getProviderServices({required int categoryId});
// Future<List<ProviderServiceModel>> 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<List<AppointmentListModel>> getMyAppointments() async {
var params = {
@ -104,22 +96,22 @@ class CommonRepoImp implements CommonRepo {
SSPhotoScheduleModel ssPhotoScheduleModel = SSPhotoScheduleModel.fromJson(genericRespModel.data[0]);
return ssPhotoScheduleModel;
}
@override
Future<List<ProviderCategoryModel>> getProviderServiceCategories() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet);
List<ProviderCategoryModel> providerCategories = List.generate(adsGenericModel.data.length, (index) => ProviderCategoryModel.fromJson(adsGenericModel.data[index]));
return providerCategories;
}
@override
Future<List<ProviderServiceModel>> 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<ProviderServiceModel> providerServices = List.generate(adsGenericModel.data.length, (index) => ProviderServiceModel.fromJson(adsGenericModel.data[index]));
return providerServices;
}
//
// @override
// Future<List<ProviderCategoryModel>> getProviderServiceCategories() async {
// GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet);
// List<ProviderCategoryModel> providerCategories = List.generate(adsGenericModel.data.length, (index) => ProviderCategoryModel.fromJson(adsGenericModel.data[index]));
// return providerCategories;
// }
// @override
// Future<List<ProviderServiceModel>> 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<ProviderServiceModel> providerServices = List.generate(adsGenericModel.data.length, (index) => ProviderServiceModel.fromJson(adsGenericModel.data[index]));
// return providerServices;
// }
}

@ -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(

@ -5,6 +5,22 @@
// unverified,
// }
enum VehicleTypeEnum {
car,
motorCycle,
golfCart,
buggy,
}
enum AdReserveStatus {
defaultStatus,
reserved,
cancelledByOwner,
cancelledByAdmin,
}
enum CreatedByRoleEnum { customer, provider, admin, allAds }
enum AdPostStatus {
pendingForReview,
pendingForPayment,

@ -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<String> 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<dynamic> 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),
);
}

@ -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';
@ -37,6 +38,7 @@ class AdVM extends BaseVM {
VehicleDetailsModel? vehicleDetails;
List<VehicleTypeModel> vehicleTypes = [];
List<VehicleBrandsModel> vehicleBrands = [];
List<VehicleModel> vehicleModels = [];
List<VehicleYearModel> vehicleModelYears = [];
List<VehicleColorModel> vehicleColors = [];
@ -64,11 +66,13 @@ class AdVM extends BaseVM {
String adStartDateError = "";
String damagePartSearchValue = "";
String adReservePriceError = "";
String adPhoneNumberError = "";
List<AdDetailsModel> exploreAds = [];
List<AdDetailsModel> exploreAdsFilteredList = [];
List<AdDetailsModel> myAdsFilteredList = [];
List<AdDetailsModel> myAds = [];
List<MyReservedAdsRespModel> myReservedAdsRespModel = [];
List<AdDetailsModel> myActiveAdsForHome = [];
List<VehicleDamageCard> vehicleDamageCards = [];
@ -138,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();
}
@ -149,13 +154,12 @@ class AdVM extends BaseVM {
List<FilterListModel> 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 = [
@ -163,14 +167,14 @@ 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();
}
applyFilterOnExploreAds({required int index}) {
applyFilterOnExploreAds({required int index, required CreatedByRoleEnum createdByRoleFilter}) {
if (exploreAdsFilterOptions.isEmpty) return;
for (var value in exploreAdsFilterOptions) {
value.isSelected = false;
@ -178,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();
}
@ -206,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<void> getMyReservedAds() async {
isFetchingLists = true;
setState(ViewState.busy);
myReservedAdsRespModel = await adsRepo.getMyReservedAds();
isFetchingLists = false;
setState(ViewState.idle);
}
Future<void> getExploreAds() async {
setState(ViewState.busy);
exploreAds = await adsRepo.getAllAds(isMyAds: false);
myAdsFilteredList = exploreAds;
exploreAdsFilteredList = exploreAds;
setState(ViewState.idle);
}
@ -236,31 +262,39 @@ class AdVM extends BaseVM {
bool isFetchingLists = false;
bool isCountryFetching = false;
Future<void> getAllDataBasedOnVehicleTypeId() async {
// Future<void> 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<void> getVehicleDetailsByVehicleId() async {
if (vehicleTypeId.selectedId == -1) {
Future<void> 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 +319,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 +356,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 +502,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 +785,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 +868,7 @@ class AdVM extends BaseVM {
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
resetValues();
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
} catch (e) {
Utils.hideLoading(context);
@ -821,6 +886,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<File> pickedVehicleImages = [];
void removeImageFromList(String filePath) {
@ -905,7 +984,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: "");
@ -988,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);

@ -27,13 +27,13 @@ class PaymentVM extends ChangeNotifier {
notifyListeners();
}
Future<void> onContinuePressed(BuildContext context) async {
Future<void> 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<void> onVisaCardSelected(BuildContext context) async {
Future<void> 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.

@ -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';
@ -33,7 +35,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,
)),
);
});
}
@ -49,20 +60,34 @@ class AdDuration extends StatelessWidget {
children: [
"Ad Duration".toText(fontSize: 18, isBold: true),
8.height,
Builder(builder: (context) {
List<DropValue> 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<DropValue> 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',
@ -75,49 +100,135 @@ class AdDuration extends StatelessWidget {
adVM.updateSelectionDurationStartDate(formattedDate);
},
),
],
).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<DropValue> 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<DropValue> 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);
},
@ -169,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,
@ -229,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)),
],
);
},

@ -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<AdVM>();
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<AdVM>();
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<AdVM>();
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();
}
}

@ -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(

@ -24,26 +24,24 @@ class VehicleDetails extends StatelessWidget {
children: [
"Vehicle Detail".toText(fontSize: 18, isBold: true),
8.height,
Builder(
builder: (BuildContext context) {
List<DropValue> 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<DropValue> 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) ...[
Row(
const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
children: [
CircularProgressIndicator(),
],
).paddingAll(10),
@ -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,

@ -0,0 +1,113 @@
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/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 {
const AdDurationSelectionSheetContent({super.key});
@override
Widget build(BuildContext context) {
AdVM adVM = context.watch<AdVM>();
print("hello : ${adVM.vehicleAdDurationId.selectedId}");
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: adVM.vehicleAdsDurations.length,
itemBuilder: (BuildContext context, int index) {
AdsDurationModel adDuration = adVM.vehicleAdsDurations[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: [
"${adDuration.days} Days".toString().toText(fontSize: 16, isBold: true),
4.height,
"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,
),
12.height,
"Ad Charges".toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${adDuration.price}".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: 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;
},
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),
],
),
);
}
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),
],
);
}
}

@ -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,16 @@ class AdsDetailView extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("adId: ${adDetails.id}");
print("statusID: ${adDetails.adPostStatus}");
return Scaffold(
appBar: CustomAppBar(
title: "Ads",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [const Icon(Icons.chat_outlined).paddingOnly(right: 21)],
onTap: () {},
),
body: Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
@ -106,11 +111,11 @@ 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(adDetailsModel: adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: adDetails),
],
),
)
@ -121,11 +126,456 @@ class AdsDetailView extends StatelessWidget {
}
}
class BuildAdDetailsActionButton extends StatelessWidget {
final AdPostStatus adPostStatus;
final int adId;
class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
final AdDetailsModel adDetailsModel;
const BuildAdDetailsActionButton({Key? key, required this.adPostStatus, required this.adId}) : super(key: key);
const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adDetailsModel}) : super(key: key);
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) {
return Row(
children: [
Expanded(
child: ShowFillButton(
borderColor: MyColors.redColor,
txtColor: MyColors.redColor,
isFilled: false,
fontSize: 16,
maxHeight: 55,
title: "Cancel Reservation",
onPressed: () {},
),
),
],
);
}
Widget reserveAdAction(BuildContext context, AdDetailsModel adDetailsModel) {
return Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Reserve Ad",
onPressed: () {
reserveAdPriceBreakDownClicked(context, adDetailsModel);
// navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
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<PaymentVM>().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);
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();
}
}
}
class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
final AdDetailsModel adDetailsModel;
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(
@ -138,7 +588,7 @@ class BuildAdDetailsActionButton extends StatelessWidget {
maxHeight: 55,
title: "Pay Now",
onPressed: () {
navigateWithName(context, AppRoutes.paymentMethodsView);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypesEnum.ads);
},
),
),
@ -176,17 +626,18 @@ class BuildAdDetailsActionButton 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: () {},
),
),
],
)
),
],
);
}
@ -217,16 +668,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(() {}),
],
@ -235,26 +696,27 @@ class BuildAdDetailsActionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adId);
switch (adPostStatus) {
context.read<PaymentVM>().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:
return cancelReservationAction(context);
break;
case AdPostStatus.buyingService:
case AdPostStatus.reserveCancel:
case AdPostStatus.rejected:
case AdPostStatus.cancelled:
case AdPostStatus.pendingForPost:
case AdPostStatus.pendingForReview:
return pendingForPaymentAction(context, adID: adId);
return pendingForReviewAction(context, adID: adDetailsModel.id!);
// return pendingForPaymentAction(context, adID: adId);
case AdPostStatus.sold:
case AdPostStatus.expired:
break;
}
return defaultAction(context);
return const SizedBox.shrink();
}
}

@ -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<AdDetailsModel> adsList;
@ -46,7 +45,7 @@ class BuildAdsList extends StatelessWidget {
isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus,
).onPress(
() {
() {
navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]);
},
);
@ -54,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),
);
}
}
@ -100,12 +99,7 @@ class AdCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (isAdsFragment && context
.read<AdVM>()
.isExploreAdsTapped) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
],
if (shouldShowAdStatus) ...[
if (isAdsFragment && !context.read<AdVM>().isExploreAdsTapped) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
],
(adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, isBold: true),
@ -139,8 +133,8 @@ class AdCard extends StatelessWidget {
),
adDetails.createdOn != null
? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(
color: MyColors.lightTextColor,
)
color: MyColors.lightTextColor,
)
: const SizedBox(),
],
),
@ -191,6 +185,9 @@ class AdCard extends StatelessWidget {
else
const SizedBox(),
],
).toWhiteContainer(width: double.infinity, allPading: 12,);
).toWhiteContainer(
width: double.infinity,
allPading: 12,
);
}
}

@ -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,
),
);
}
}

@ -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);
@ -103,7 +104,6 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
const SizedBox(width: 20),
vehiclePart.partName.toString().toText(
fontSize: 16,
isBold: true,
color: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.black,
)
],
@ -147,7 +147,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 +164,6 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
Flexible(
child: description.toText(
fontSize: 15,
isBold: true,
color: MyColors.lightTextColor,
),
),
@ -217,55 +216,56 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
] else ...[
8.height,
if ((adVM.vehicleAdsSpecialServicesId.selectedId == 1 && adVM.ssPhotoScheduleModel != null)) ...[
Builder(
builder: (context) {
List<DropValue> 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<DropValue> 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<DropValue> 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<DropValue> 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) ...[
@ -278,8 +278,14 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
],
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),
],
),
],
],
],
@ -298,28 +304,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),
),

@ -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<AdVM>();
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),
],
),
],

@ -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: [

@ -0,0 +1,166 @@
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';
class SelectAdTypeView extends StatelessWidget {
final bool isProvider;
const SelectAdTypeView({
Key? key,
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(
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 InkWell(
onTap: () {
adVM.updateSelectionVehicleTypeId(
SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""),
);
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent());
},
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 ...[
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: [
adVM.vehicleAdDurationId.itemPrice.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, pading: const EdgeInsets.symmetric(horizontal: 20, vertical: 10)),
);
},
separatorBuilder: (BuildContext context, int index) {
return 9.height;
},
padding: const EdgeInsets.all(20),
);
}),
),
if (isProvider) ...[
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,
))
],
),
),
10.height,
],
).toContainer(paddingAll: 20, backgroundColor: Colors.white),
]
],
),
);
}
}

@ -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<PaymentVM>().onContinuePressed(context);
context.read<PaymentVM>().onContinuePressed(context, paymentType: paymentType);
},
backgroundColor: MyColors.darkPrimaryColor,
),

@ -28,7 +28,8 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
int otpType = 1;
ClassType type = ClassType.EMAIL;
String phoneNum = "580816976", password = "123@Shf";
//TODO: ONLY FOR DEVELOPMENT PURPOSE
String phoneNum = "966504278213", password = "Fa@1234";
String email = "";
String countryCode = "";
Country? _country;

@ -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,
),
),
);
}

@ -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) {

@ -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());
}

@ -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<ServiceModel>? items;
final List<ServiceModel>? 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);
@ -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),
],
@ -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,

@ -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: () {

@ -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);
}

@ -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 ?? "",

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: args
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
async:
dependency: transitive
description:
@ -29,10 +29,10 @@ packages:
dependency: "direct main"
description:
name: badges
sha256: "6e7f3ec561ec08f47f912cfe349d4a1707afdc8dda271e17b046aa6d42c89e77"
sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.1.2"
boolean_selector:
dependency: transitive
description:
@ -97,46 +97,62 @@ packages:
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: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
version: "0.3.3+5"
crypto:
dependency: transitive
description:
name: crypto
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.2"
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: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.5"
version: "1.0.6"
dropdown_button2:
dependency: "direct main"
description:
name: dropdown_button2
sha256: "374f2390161bf782b4896f0b1b24cbb2b5daaa1cfb11047c3307461dcdf44e07"
sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.3.9"
easy_localization:
dependency: "direct main"
description:
name: easy_localization
sha256: "30ebf25448ffe169e0bd9bc4b5da94faa8398967a2ad2ca09f438be8b6953645"
sha256: de63e3b422adfc97f256cbb3f8cf12739b6a4993d390f3cadb3f51837afaefe5
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.3"
easy_logger:
dependency: transitive
description:
@ -185,6 +201,38 @@ packages:
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
@ -202,10 +250,10 @@ packages:
dependency: transitive
description:
name: flutter_cache_manager
sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3"
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
version: "3.3.1"
flutter_inappwebview:
dependency: "direct main"
description:
@ -218,10 +266,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.3"
flutter_localizations:
dependency: transitive
description: flutter
@ -231,10 +279,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360"
sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
url: "https://pub.dev"
source: hosted
version: "2.0.15"
version: "2.0.16"
flutter_svg:
dependency: "direct main"
description:
@ -261,46 +309,14 @@ 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:
name: geolocator
sha256: "5c23f3613f50586c0bbb2b8f970240ae66b3bd992088cf60dd5ee2e6f7dde3a8"
sha256: "9d6eff112971b9f195271834b390fc0e1899a9a6c96225ead72efd5d4aaa80c7"
url: "https://pub.dev"
source: hosted
version: "9.0.2"
version: "10.0.0"
geolocator_android:
dependency: transitive
description:
@ -313,10 +329,10 @@ packages:
dependency: transitive
description:
name: geolocator_apple
sha256: "22b60ca3b8c0f58e6a9688ff855ee39ab813ca3f0c0609a48d282f6631266f2e"
sha256: "36527c555f4c425f7d8fa8c7c07d67b78e3ff7590d40448051959e1860c1cfb4"
url: "https://pub.dev"
source: hosted
version: "2.2.5"
version: "2.2.7"
geolocator_platform_interface:
dependency: transitive
description:
@ -337,58 +353,82 @@ packages:
dependency: transitive
description:
name: geolocator_windows
sha256: f5911c88e23f48b598dd506c7c19eff0e001645bdc03bb6fecb9f4549208354d
sha256: "463045515b08bd83f73e014359c4ad063b902eb3899952cfb784497ae6c6583b"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
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: abefcb1e5e5c96bdd8084939dda555257af272c7972902ca46d5631092c1df68
sha256: d4914cb38b3dcb62c39c085d968d434de0f8050f00f4d9f5ba4a7c7e004934cb
url: "https://pub.dev"
source: hosted
version: "2.2.8"
version: "2.5.0"
google_maps_flutter_android:
dependency: transitive
description:
name: google_maps_flutter_android
sha256: "9512c862df77c1f0fa5f445513dd3c57f5996f0a809dccb74e54b690ee4e3a0f"
sha256: e6cb018169e49332f88d23b1d2119b09e8ab4e7d3a1b889a1b7b3fd113e034ba
url: "https://pub.dev"
source: hosted
version: "2.4.15"
version: "2.5.1"
google_maps_flutter_ios:
dependency: transitive
description:
name: google_maps_flutter_ios
sha256: a9462a433bf3ebe60aadcf4906d2d6341a270d69d3e0fcaa8eb2b64699fcfb4f
sha256: "2a595c9789070786c654e9772ec0d1bb759ae37d2dd776291af5398531274e06"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.3.1"
google_maps_flutter_platform_interface:
dependency: transitive
description:
name: google_maps_flutter_platform_interface
sha256: "308f0af138fa78e8224d598d46ca182673874d0ef4d754b7157c073b5b4b8e0d"
sha256: a3e9e6896501e566d902c6c69f010834d410ef4b7b5c18b90c77e871c86b7907
url: "https://pub.dev"
source: hosted
version: "2.2.7"
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: e572c3346f4b26422a281dc4c10f83022131f56f7364837671b50f53c7adc5e7
sha256: c07f4bbb9095df87eeca87e7c69e8c3d60f70c66102d7b8d61c4af0453add3f6
url: "https://pub.dev"
source: hosted
version: "2.0.7"
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: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.5"
version: "0.13.6"
http_parser:
dependency: transitive
description:
@ -401,42 +441,66 @@ packages:
dependency: "direct main"
description:
name: image_picker
sha256: "9978d3510af4e6a902e545ce19229b926e6de6a1828d6134d3aab2e129a4d270"
sha256: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c
url: "https://pub.dev"
source: hosted
version: "0.8.7+5"
version: "0.8.9"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: c2f3c66400649bd132f721c88218945d6406f693092b2f741b79ae9cdb046e59
sha256: d32a997bcc4ee135aebca8e272b7c517927aa65a74b9c60a81a2764ef1a0462d
url: "https://pub.dev"
source: hosted
version: "0.8.6+16"
version: "0.8.7+5"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c"
sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0"
url: "https://pub.dev"
source: hosted
version: "2.1.12"
version: "2.2.0"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: d779210bda268a03b57e923fb1e410f32f5c5e708ad256348bcbf1f44f558fd0
sha256: c5538cacefacac733c724be7484377923b476216ad1ead35a0d2eadcdc0fc497
url: "https://pub.dev"
source: hosted
version: "0.8.7+4"
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: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8"
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: "2.6.3"
version: "0.2.1+1"
injector:
dependency: "direct main"
description:
@ -461,62 +525,70 @@ packages:
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: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.1.1"
local_auth:
dependency: "direct main"
description:
name: local_auth
sha256: "0cf238be2bfa51a6c9e7e9cfc11c05ea39f2a3a4d3e5bb255d0ebc917da24401"
sha256: "7e6c63082e399b61e4af71266b012e767a5d4525dd6e9ba41e174fd42d76e115"
url: "https://pub.dev"
source: hosted
version: "2.1.6"
version: "2.1.7"
local_auth_android:
dependency: transitive
description:
name: local_auth_android
sha256: c5e48c4a67fc0e5dd9b5725cc8766b67e2da9a54155c82c6e2ea4a0d1cf9ef93
sha256: "9ad0b1ffa6f04f4d91e38c2d4c5046583e23f4cae8345776a994e8670df57fb1"
url: "https://pub.dev"
source: hosted
version: "1.0.28"
version: "1.0.34"
local_auth_ios:
dependency: transitive
description:
name: local_auth_ios
sha256: edc2977c5145492f3451db9507a2f2f284ee4f408950b3e16670838726761940
sha256: "26a8d1ad0b4ef6f861d29921be8383000fda952e323a5b6752cf82ca9cf9a7a9"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
version: "1.1.4"
local_auth_platform_interface:
dependency: transitive
description:
name: local_auth_platform_interface
sha256: "9e160d59ef0743e35f1b50f4fb84dc64f55676b1b8071e319ef35e7f3bc13367"
sha256: fc5bd537970a324260fda506cfb61b33ad7426f37a8ea5c461cf612161ebba54
url: "https://pub.dev"
source: hosted
version: "1.0.7"
version: "1.0.8"
local_auth_windows:
dependency: transitive
description:
name: local_auth_windows
sha256: "19323b75ab781d5362dbb15dcb7e0916d2431c7a6dbdda016ec9708689877f73"
sha256: "505ba3367ca781efb1c50d3132e44a2446bccc4163427bc203b9b4d8994d97ea"
url: "https://pub.dev"
source: hosted
version: "1.0.8"
version: "1.0.10"
logger:
dependency: "direct main"
description:
name: logger
sha256: db2ff852ed77090ba9f62d3611e4208a3d11dfa35991a81ae724c113fcb3e3f7
sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
matcher:
dependency: transitive
description:
@ -541,6 +613,14 @@ packages:
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:
@ -593,34 +673,34 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
url: "https://pub.dev"
source: hosted
version: "2.0.27"
version: "2.2.0"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.1.11"
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev"
source: hosted
version: "2.0.6"
version: "2.1.1"
path_provider_windows:
dependency: transitive
description:
@ -629,86 +709,70 @@ packages:
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"
sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81"
url: "https://pub.dev"
source: hosted
version: "10.2.0"
version: "10.4.3"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d8cc6a62ded6d0f49c6eac337e080b066ee3bce4d405bd9439a61e1f1927bfe8
sha256: d74e77a5ecd38649905db0a7d05ef16bed42ff263b9efb73ed794317c5764ec3
url: "https://pub.dev"
source: hosted
version: "10.2.1"
version: "10.3.4"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
version: "9.0.8"
version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84"
sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
version: "3.11.3"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
version: "0.1.2"
version: "0.1.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.1.0"
version: "5.4.0"
platform:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
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"
version: "2.1.6"
provider:
dependency: "direct main"
description:
@ -725,62 +789,70 @@ packages:
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: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022"
sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.2.1"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749"
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb
sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.3.4"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa"
sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d
sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5"
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173"
sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.1"
shimmer:
dependency: "direct main"
description:
@ -810,22 +882,30 @@ packages:
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: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
url: "https://pub.dev"
source: hosted
version: "2.2.8+4"
version: "2.3.0"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555
sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a"
url: "https://pub.dev"
source: hosted
version: "2.4.5"
version: "2.5.0"
stack_trace:
dependency: transitive
description:
@ -894,82 +974,82 @@ packages:
dependency: transitive
description:
name: universal_io
sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d"
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.2.2"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
url: "https://pub.dev"
source: hosted
version: "6.1.11"
version: "6.1.14"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: eed4e6a1164aa9794409325c3b707ff424d4d1c2a785e7db67f8bbda00e36e51
sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330
url: "https://pub.dev"
source: hosted
version: "6.0.35"
version: "6.1.0"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "6.1.5"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e"
sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.7"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.5"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab"
sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2
url: "https://pub.dev"
source: hosted
version: "2.0.17"
version: "2.0.19"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771"
sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.0.8"
uuid:
dependency: transitive
description:
name: uuid
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
sha256: e03928880bdbcbf496fb415573f5ab7b1ea99b9b04f669c01104d085893c3134
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "4.0.0"
vector_math:
dependency: transitive
description:
@ -990,18 +1070,18 @@ packages:
dependency: transitive
description:
name: xdg_directories
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "6.3.0"
sdks:
dart: ">=3.0.0-0 <4.0.0"
flutter: ">=3.3.0"
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"

@ -29,18 +29,19 @@ 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
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
geolocator: any
geocoding: any
# geocoding: ^2.1.0
dev_dependencies:

Loading…
Cancel
Save