Merge branch 'master' into mirza_development

# Conflicts:
#	lib/api/api_client.dart
#	lib/classes/consts.dart
#	lib/widgets/txt_field.dart
merge-requests/13/head
mirza.shafique 3 years ago
commit a9e054820a

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -74,20 +75,20 @@ class ApiClientImp implements ApiClient {
headers0.addAll(headers); headers0.addAll(headers);
} }
if (!kReleaseMode) { if (!kReleaseMode) {
debugPrint("Url:$url"); log("Url:$url");
debugPrint("body:$jsonObject"); log("body:$jsonObject");
} }
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: headers0, retryTimes: retryTimes); var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: headers0, retryTimes: retryTimes);
try { try {
if (!kReleaseMode) { if (!kReleaseMode) {
debugPrint("res121:${response.body}"); log("res121:${response.body}");
debugPrint("res121:${response.statusCode}"); log("res121:${response.statusCode}");
} }
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
return factoryConstructor(jsonData); return factoryConstructor(jsonData);
} catch (ex) { } catch (ex) {
debugPrint(ex.toString()); log(ex.toString());
debugPrint("exception:$ex"); log("exception:$ex");
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
} }
} }
@ -135,9 +136,9 @@ class ApiClientImp implements ApiClient {
response = await _post(Uri.parse(url), body: requestBody, headers: headers0).timeout(const Duration(seconds: 100)); response = await _post(Uri.parse(url), body: requestBody, headers: headers0).timeout(const Duration(seconds: 100));
if (!kReleaseMode) { if (!kReleaseMode) {
debugPrint("Url:$url"); log("Url:$url");
debugPrint("body:$requestBody"); log("body:$requestBody");
debugPrint("res: ${response.body}"); log("res: ${response.body}");
} }
if (response.statusCode >= 200 && response.statusCode < 500) { if (response.statusCode >= 200 && response.statusCode < 500) {
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
@ -151,7 +152,7 @@ class ApiClientImp implements ApiClient {
} }
} on SocketException catch (e) { } on SocketException catch (e) {
if (retryTimes > 0) { if (retryTimes > 0) {
debugPrint('will retry after 3 seconds...'); log('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else { } else {
@ -159,7 +160,7 @@ class ApiClientImp implements ApiClient {
} }
} on HttpException catch (e) { } on HttpException catch (e) {
if (retryTimes > 0) { if (retryTimes > 0) {
debugPrint('will retry after 3 seconds...'); log('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else { } else {
@ -169,14 +170,14 @@ class ApiClientImp implements ApiClient {
throw APIException(APIException.TIMEOUT, arguments: e); throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) { } on ClientException catch (e) {
if (retryTimes > 0) { if (retryTimes > 0) {
debugPrint('will retry after 3 seconds...'); log('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else { } else {
throw APIException(APIException.OTHER, arguments: e); throw APIException(APIException.OTHER, arguments: e);
} }
} catch (ex) { } catch (ex) {
debugPrint("exception1:$ex"); log("exception1:$ex");
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
} }
} }
@ -204,14 +205,10 @@ class ApiClientImp implements ApiClient {
} }
var response = await getJsonForResponse(url, token: token, queryParameters: queryParameters, headers: headers0, retryTimes: retryTimes); var response = await getJsonForResponse(url, token: token, queryParameters: queryParameters, headers: headers0, retryTimes: retryTimes);
try { try {
logger.wtf(url);
if (!kReleaseMode) {
debugPrint("res:${response.body}");
}
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
return factoryConstructor(jsonData); return factoryConstructor(jsonData);
} catch (ex) { } catch (ex) {
debugPrint("exception:${response.body}"); log("exception:${response.body}");
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
} }
} }
@ -244,14 +241,14 @@ class ApiClientImp implements ApiClient {
} }
if (!kReleaseMode) { if (!kReleaseMode) {
debugPrint("Url:$url"); log("Url:$url");
debugPrint("queryParameters:$queryParameters"); log("queryParameters:$queryParameters");
} }
var response = await _get(Uri.parse(url), headers: headers0).timeout(const Duration(seconds: 60)); var response = await _get(Uri.parse(url), headers: headers0).timeout(const Duration(seconds: 60));
if (!kReleaseMode) { if (!kReleaseMode) {
debugPrint("res: ${response.body}"); log("res: ${response.body}");
debugPrint("resCode: ${response.statusCode}"); log("resCode: ${response.statusCode}");
} }
if (response.statusCode >= 200 && response.statusCode < 500) { if (response.statusCode >= 200 && response.statusCode < 500) {
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
@ -266,7 +263,7 @@ class ApiClientImp implements ApiClient {
} }
} on SocketException catch (e) { } on SocketException catch (e) {
if (retryTimes > 0) { if (retryTimes > 0) {
debugPrint('will retry after 3 seconds...'); log('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else { } else {
@ -274,7 +271,7 @@ class ApiClientImp implements ApiClient {
} }
} on HttpException catch (e) { } on HttpException catch (e) {
if (retryTimes > 0) { if (retryTimes > 0) {
debugPrint('will retry after 3 seconds...'); log('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else { } else {
@ -319,9 +316,9 @@ class ApiClientImp implements ApiClient {
SharedPrefManager.setRefreshToken(refresh.data!.refreshToken ?? ""); SharedPrefManager.setRefreshToken(refresh.data!.refreshToken ?? "");
String mdata = await SharedPrefManager.getData(); String mdata = await SharedPrefManager.getData();
UserInfo info = UserInfo.fromJson(jsonDecode(mdata)); UserInfo info = UserInfo.fromJson(jsonDecode(mdata));
User user = User(); User user = User();
user.data = UserData(accessToken: refresh.data!.accessToken ?? "", refreshToken: refresh.data!.refreshToken ?? "", userInfo: info); user.data = UserData(accessToken: refresh.data!.accessToken ?? "", refreshToken: refresh.data!.refreshToken ?? "", userInfo: info);
AppState().setUser = user; AppState().setUser = user;
return refresh.data!.accessToken ?? ""; return refresh.data!.accessToken??"";
} }
} }

@ -50,6 +50,11 @@ class ApiConsts {
static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get"; static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get";
static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get"; static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get";
//Appointment APIs
static String serviceProvidersAppointmentGet = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointment_Get";
static String serviceCategoryGet = "${baseUrlServices}api/Master/ServiceCategory_Get";
static String servicesGet = "${baseUrlServices}api/ServiceProviders/Services_Get";
//Services & items //Services & items
static String createService = "${baseUrlServices}api/ServiceProviders/Service_Create"; static String createService = "${baseUrlServices}api/ServiceProviders/Service_Create";
static String createItems = "${baseUrlServices}api/ServiceProviders/ServiceItem_Create"; static String createItems = "${baseUrlServices}api/ServiceProviders/ServiceItem_Create";
@ -80,6 +85,8 @@ class ApiConsts {
static String vehicleAdsSpecialServicesGet = "${baseUrlServices}api/Common/SpecialService_Get"; static String vehicleAdsSpecialServicesGet = "${baseUrlServices}api/Common/SpecialService_Get";
static String vehicleAdsSingleStepCreate = "${baseUrlServices}api/Advertisement/AdsSingleStep_Create"; static String vehicleAdsSingleStepCreate = "${baseUrlServices}api/Advertisement/AdsSingleStep_Create";
static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get"; static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get";
static String adsCarCheckupSPBranchScheduleSlotGet = "${baseUrlServices}api/Advertisement/AdsCarCheckupSPBranchScheduleSlot_Get";
static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get";
//Subscription //Subscription
static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get"; static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get";
@ -101,6 +108,9 @@ class GlobalConsts {
static String attachImageError = "You must add at least 3 images"; static String attachImageError = "You must add at least 3 images";
static String attachDamagePartImage = "Please add part image"; static String attachDamagePartImage = "Please add part image";
static String adDurationDateError = "Ad Duration start date cannot be empty"; static String adDurationDateError = "Ad Duration start date cannot be empty";
static String adReservablePriceErrorConst = "Ad Reservable price 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.";
} }
class MyAssets { class MyAssets {
@ -177,6 +187,14 @@ class MyAssets {
static String icWhatsAppPng = "${assetPath}icons/ic_whatsapp.png"; static String icWhatsAppPng = "${assetPath}icons/ic_whatsapp.png";
static String icSmsPng = "${assetPath}icons/ic_sms.png"; static String icSmsPng = "${assetPath}icons/ic_sms.png";
static String icFingerprintPng = "${assetPath}icons/ic_fingerprint.png"; static String icFingerprintPng = "${assetPath}icons/ic_fingerprint.png";
static String applePayPng = "${assetPath}icons/payments/apple_pay.png";
static String installmentsPng = "${assetPath}icons/payments/installments.png";
static String madaPng = "${assetPath}icons/payments/mada.png";
static String mastercardPng = "${assetPath}icons/payments/mastercard.png";
static String tamaraArPng = "${assetPath}icons/payments/tamara_ar.png";
static String tamaraEngPng = "${assetPath}icons/payments/tamara_en.png";
static String visaPng = "${assetPath}icons/payments/visa.png";
} }
RegExp numReg = RegExp(r".*[0-9].*"); RegExp numReg = RegExp(r".*[0-9].*");

@ -4,6 +4,7 @@
import 'package:injector/injector.dart'; import 'package:injector/injector.dart';
import 'package:mc_common_app/api/api_client.dart'; import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/services.dart'; import 'package:mc_common_app/services/services.dart';
@ -20,5 +21,6 @@ class AppDependencies {
//repos //repos
injector.registerSingleton<UserRepo>(() => UserRepoImp()); injector.registerSingleton<UserRepo>(() => UserRepoImp());
injector.registerSingleton<CommonRepo>(() => CommonRepoImp()); injector.registerSingleton<CommonRepo>(() => CommonRepoImp());
injector.registerSingleton<AdsRepo>(() => AdsRepoImp());
} }
} }

@ -55,6 +55,8 @@ class AppRoutes {
static const String appointmentDetailView = "/appointmentDetailView"; static const String appointmentDetailView = "/appointmentDetailView";
static const String adsDetailView = "/adsDetailView"; static const String adsDetailView = "/adsDetailView";
static const String createAdView = "/createAdView"; static const String createAdView = "/createAdView";
static const String bookAppointmenServicesView = "/bookAppointmenServicesView";
static const String paymentMethodsView = "/paymentMethodsView";
//Subcriptions //Subcriptions

@ -1,7 +1,8 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:mc_common_app/utils/enums.dart';
extension EmailValidator on String { extension EmailValidator on String {
Widget toText( Widget toText(
@ -18,6 +19,7 @@ extension EmailValidator on String {
this, this,
textAlign: textAlign, textAlign: textAlign,
maxLines: maxLines, maxLines: maxLines,
style: TextStyle( style: TextStyle(
height: height, height: height,
decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none, decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none,
@ -36,14 +38,73 @@ extension EmailValidator on String {
return RegExp(r'^[0-9]+$').hasMatch(this); return RegExp(r'^[0-9]+$').hasMatch(this);
} }
String toFormattedDate() { getMonth(int month) {
String date = split("T")[0]; switch (month) {
String time = split("T")[1]; case 1:
var dates = date.split("-"); return "January";
return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}"; case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
}
} }
}
getMonth(int month) { extension FormatDate on String {
/// get month by
/// [month] convert month number in to month name
/// get month by
/// [month] convert month number in to month name in Arabic
static String getMonthArabic(int month) {
switch (month) {
case 1:
return "يناير";
case 2:
return " فبراير";
case 3:
return "مارس";
case 4:
return "أبريل";
case 5:
return "مايو";
case 6:
return "يونيو";
case 7:
return "يوليو";
case 8:
return "أغسطس";
case 9:
return "سبتمبر";
case 10:
return " اكتوبر";
case 11:
return " نوفمبر";
case 12:
return "ديسمبر";
default:
return "";
}
}
static String getMonth(int month) {
switch (month) { switch (month) {
case 1: case 1:
return "January"; return "January";
@ -69,6 +130,78 @@ extension EmailValidator on String {
return "November"; return "November";
case 12: case 12:
return "December"; return "December";
default:
return "";
}
}
String toFormattedDate() {
String date = split("T")[0];
String time = split("T")[1];
var dates = date.split("-");
return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a', "en_US").format(DateFormat('hh:mm:ss', "en_US").parse(time))}";
}
String toFormattedDateWithoutTime() {
String date = split("T")[0];
var dates = date.split("-");
return "${dates[2]} ${getMonth(int.parse(dates[1]))}, ${dates[0]}";
}
}
extension AdPostEnum on int {
AdPostStatus toAdPostEnum() {
if (this == 1) {
return AdPostStatus.pendingForReview;
} else if (this == 2) {
return AdPostStatus.pendingForPayment;
} else if (this == 3) {
return AdPostStatus.rejected;
} else if (this == 4) {
return AdPostStatus.cancelled;
} else if (this == 5) {
return AdPostStatus.pendingForPost;
} else if (this == 6) {
return AdPostStatus.active;
} else if (this == 7) {
return AdPostStatus.expired;
} else if (this == 8) {
return AdPostStatus.sold;
} else if (this == 9) {
return AdPostStatus.reserved;
} else if (this == 10) {
return AdPostStatus.buyingService;
} else if (this == 11) {
return AdPostStatus.reserveCancel;
} else {
return AdPostStatus.pendingForPost;
}
}
}
extension DateTimeConversions on DateTime {
String getTimeAgo({bool numericDates = true}) {
final date2 = DateTime.now();
final difference = date2.difference(this);
if ((difference.inDays / 7).floor() >= 1) {
return (numericDates) ? '1 week ago' : 'Last week';
} else if (difference.inDays >= 2) {
return '${difference.inDays} days ago';
} else if (difference.inDays >= 1) {
return (numericDates) ? '1 day ago' : 'Yesterday';
} else if (difference.inHours >= 2) {
return '${difference.inHours} hours ago';
} else if (difference.inHours >= 1) {
return (numericDates) ? '1 hour ago' : 'An hour ago';
} else if (difference.inMinutes >= 2) {
return '${difference.inMinutes} minutes ago';
} else if (difference.inMinutes >= 1) {
return (numericDates) ? '1 minute ago' : 'A minute ago';
} else if (difference.inSeconds >= 3) {
return '${difference.inSeconds} seconds ago';
} else {
return 'Just now';
} }
} }
} }

@ -1,4 +1,6 @@
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/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/utils/enums.dart';
class AdDetailsModel { class AdDetailsModel {
int? id; int? id;
@ -6,6 +8,7 @@ class AdDetailsModel {
String? enddate; String? enddate;
Vehicle? vehicle; Vehicle? vehicle;
List<SpecialServiceModel>? specialservice; List<SpecialServiceModel>? specialservice;
// List<Null>? reserved; // List<Null>? reserved;
int? statusID; int? statusID;
String? statuslabel; String? statuslabel;
@ -32,46 +35,47 @@ class AdDetailsModel {
double? reservePrice; double? reservePrice;
bool? isMCHandled; bool? isMCHandled;
String? modifiedOn; String? modifiedOn;
AdPostStatus? adPostStatus;
AdDetailsModel( AdDetailsModel(
{this.id, {this.id,
this.startdate, this.startdate,
this.enddate, this.enddate,
this.vehicle, this.vehicle,
this.specialservice, this.specialservice,
// this.reserved, // this.reserved,
this.statusID, this.statusID,
this.statuslabel, this.statuslabel,
this.adsDurationPrice, this.adsDurationPrice,
this.adsDurationDiscount, this.adsDurationDiscount,
this.adsDurationDiscountPrice, this.adsDurationDiscountPrice,
this.comment, this.comment,
this.active, this.active,
this.isPaid, this.isPaid,
this.isSubscription, this.isSubscription,
this.isVerified, this.isVerified,
this.netPrice, this.netPrice,
this.specialServiceTotalPrice, this.specialServiceTotalPrice,
this.taxPrice, this.taxPrice,
this.totalPrice, this.totalPrice,
this.userID, this.userID,
this.vehiclePostingID, this.vehiclePostingID,
this.qrCodePath, this.qrCodePath,
this.isCustomerAcknowledged, this.isCustomerAcknowledged,
this.createdByRole, this.createdByRole,
this.totalViews, this.totalViews,
this.createdOn, this.createdOn,
this.priceExcludingDiscount, this.priceExcludingDiscount,
this.reservePrice, this.reservePrice,
this.isMCHandled, this.isMCHandled,
this.modifiedOn}); this.adPostStatus,
this.modifiedOn});
AdDetailsModel.fromJson(Map<String, dynamic> json) { AdDetailsModel.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
startdate = json['startdate']; startdate = json['startdate'];
enddate = json['enddate']; enddate = json['enddate'];
vehicle = vehicle = json['vehicle'] != null ? Vehicle.fromJson(json['vehicle']) : null;
json['vehicle'] != null ? Vehicle.fromJson(json['vehicle']) : null;
if (json['specialservice'] != null) { if (json['specialservice'] != null) {
specialservice = <SpecialServiceModel>[]; specialservice = <SpecialServiceModel>[];
json['specialservice'].forEach((v) { json['specialservice'].forEach((v) {
@ -109,6 +113,7 @@ class AdDetailsModel {
reservePrice = json['reservePrice']; reservePrice = json['reservePrice'];
isMCHandled = json['isMCHandled']; isMCHandled = json['isMCHandled'];
modifiedOn = json['modifiedOn']; modifiedOn = json['modifiedOn'];
adPostStatus = (json['statusID'] as int).toAdPostEnum();
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -120,8 +125,7 @@ class AdDetailsModel {
data['vehicle'] = vehicle!.toJson(); data['vehicle'] = vehicle!.toJson();
} }
if (specialservice != null) { if (specialservice != null) {
data['specialservice'] = data['specialservice'] = specialservice!.map((v) => v.toJson()).toList();
specialservice!.map((v) => v.toJson()).toList();
} }
// if (reserved != null) { // if (reserved != null) {
// data['reserved'] = reserved!.map((v) => v.toJson()).toList(); // data['reserved'] = reserved!.map((v) => v.toJson()).toList();
@ -184,30 +188,30 @@ class Vehicle {
Vehicle( Vehicle(
{this.id, {this.id,
this.cityID, this.cityID,
this.cityName, this.cityName,
this.demandAmount, this.demandAmount,
this.isActive, this.isActive,
this.isFinanceAvailable, this.isFinanceAvailable,
this.status, this.status,
this.statustext, this.statustext,
this.category, this.category,
this.color, this.color,
this.condition, this.condition,
this.mileage, this.mileage,
this.model, this.model,
this.modelyear, this.modelyear,
this.sellertype, this.sellertype,
this.transmission, this.transmission,
this.duration, this.duration,
this.image, this.image,
this.damagereport, this.damagereport,
this.vehicleDescription, this.vehicleDescription,
this.vehicleTitle, this.vehicleTitle,
this.vehicleType, this.vehicleType,
this.vehicleVIN, this.vehicleVIN,
this.countryID, this.countryID,
this.currency}); this.currency});
Vehicle.fromJson(Map<String, dynamic> json) { Vehicle.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
@ -218,29 +222,15 @@ class Vehicle {
isFinanceAvailable = json['isFinanceAvailable']; isFinanceAvailable = json['isFinanceAvailable'];
status = json['status']; status = json['status'];
statustext = json['statustext']; statustext = json['statustext'];
category = json['category'] != null category = json['category'] != null ? Category.fromJson(json['category']) : null;
? Category.fromJson(json['category'])
: null;
color = json['color'] != null ? Category.fromJson(json['color']) : null; color = json['color'] != null ? Category.fromJson(json['color']) : null;
condition = json['condition'] != null condition = json['condition'] != null ? Condition.fromJson(json['condition']) : null;
? Condition.fromJson(json['condition']) mileage = json['mileage'] != null ? Mileage.fromJson(json['mileage']) : null;
: null; model = json['model'] != null ? Condition.fromJson(json['model']) : null;
mileage = modelyear = json['modelyear'] != null ? ModelYear.fromJson(json['modelyear']) : null;
json['mileage'] != null ? Mileage.fromJson(json['mileage']) : null; sellertype = json['sellertype'] != null ? Condition.fromJson(json['sellertype']) : null;
model = transmission = json['transmission'] != null ? Condition.fromJson(json['transmission']) : null;
json['model'] != null ? Condition.fromJson(json['model']) : null; duration = json['duration'] != null ? Duration.fromJson(json['duration']) : null;
modelyear = json['modelyear'] != null
? ModelYear.fromJson(json['modelyear'])
: null;
sellertype = json['sellertype'] != null
? Condition.fromJson(json['sellertype'])
: null;
transmission = json['transmission'] != null
? Condition.fromJson(json['transmission'])
: null;
duration = json['duration'] != null
? Duration.fromJson(json['duration'])
: null;
if (json['image'] != null) { if (json['image'] != null) {
image = <AdImage>[]; image = <AdImage>[];
json['image'].forEach((v) { json['image'].forEach((v) {
@ -419,9 +409,7 @@ class Duration {
label = json['label']; label = json['label'];
days = json['days']; days = json['days'];
price = json['price']; price = json['price'];
country = json['country'] != null country = json['country'] != null ? ModelYear.fromJson(json['country']) : null;
? ModelYear.fromJson(json['country'])
: null;
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -470,13 +458,7 @@ class DamageReport {
int? vehicleDamagePartID; int? vehicleDamagePartID;
String? partName; String? partName;
DamageReport( DamageReport({this.id, this.comment, this.imageUrl, this.isActive, this.vehicleDamagePartID, this.partName});
{this.id,
this.comment,
this.imageUrl,
this.isActive,
this.vehicleDamagePartID,
this.partName});
DamageReport.fromJson(Map<String, dynamic> json) { DamageReport.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];

@ -12,23 +12,21 @@ class SpecialServiceModel {
List<Office>? office; List<Office>? office;
bool? isDelivery; bool? isDelivery;
bool? isSelected; bool? isSelected;
bool? isChecked;
SpecialServiceModel( SpecialServiceModel(
{this.id, {this.id,
this.name, this.name,
this.description, this.description,
this.price, this.price,
this.specialServiceType, this.specialServiceType,
this.specialServiceTypeName, this.specialServiceTypeName,
this.isActive, this.isActive,
this.startDate, this.startDate,
this.endDate, this.endDate,
this.details, this.details,
this.office, this.office,
this.isSelected = false, this.isSelected,
this.isChecked = false, this.isDelivery});
this.isDelivery});
SpecialServiceModel.fromJson(Map<String, dynamic> json) { SpecialServiceModel.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
@ -54,7 +52,6 @@ class SpecialServiceModel {
} }
isDelivery = json['isDelivery']; isDelivery = json['isDelivery'];
isSelected = false; isSelected = false;
isChecked = false;
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -86,7 +83,8 @@ class Details {
int? tocity; int? tocity;
int? price; int? price;
Details({this.id, this.specialServiceID, this.fromcity, this.tocity, this.price}); Details(
{this.id, this.specialServiceID, this.fromcity, this.tocity, this.price});
Details.fromJson(Map<String, dynamic> json) { Details.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
@ -115,7 +113,13 @@ class Office {
String? city; String? city;
int? specialServiceID; int? specialServiceID;
Office({this.id, this.officeAreaName, this.officeAreaNameN, this.cityID, this.city, this.specialServiceID}); Office(
{this.id,
this.officeAreaName,
this.officeAreaNameN,
this.cityID,
this.city,
this.specialServiceID});
Office.fromJson(Map<String, dynamic> json) { Office.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];

@ -0,0 +1,117 @@
class SSCarCheckScheduleModel {
int? serviceProviderID;
int? serviceProviderBranchID;
int? branchAppointmentScheduleID;
String? branchName;
String? address;
String? latitude;
String? longitude;
List<ScheduleServices>? scheduleServices;
List<BranchScheduleSlots>? branchScheduleSlots;
int? totalItemsCount;
int? distanceKM;
SSCarCheckScheduleModel(
{this.serviceProviderID,
this.serviceProviderBranchID,
this.branchAppointmentScheduleID,
this.branchName,
this.address,
this.latitude,
this.longitude,
this.scheduleServices,
this.branchScheduleSlots,
this.distanceKM,
this.totalItemsCount});
SSCarCheckScheduleModel.fromJson(Map<String, dynamic> json) {
serviceProviderID = json['serviceProviderID'];
serviceProviderBranchID = json['serviceProviderBranchID'];
branchAppointmentScheduleID = json['branchAppointmentScheduleID'];
branchName = json['branchName'];
address = json['address'];
latitude = json['latitude'];
longitude = json['longitude'];
if (json['scheduleServices'] != null) {
scheduleServices = <ScheduleServices>[];
json['scheduleServices'].forEach((v) {
scheduleServices!.add(ScheduleServices.fromJson(v));
});
}
if (json['branchScheduleSlots'] != null) {
branchScheduleSlots = <BranchScheduleSlots>[];
json['branchScheduleSlots'].forEach((v) {
branchScheduleSlots!.add(BranchScheduleSlots.fromJson(v));
});
}
totalItemsCount = json['totalItemsCount'];
//TODO: We will update this when Backend team will add this value
distanceKM = 0;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['serviceProviderID'] = serviceProviderID;
data['serviceProviderBranchID'] = serviceProviderBranchID;
data['branchAppointmentScheduleID'] = branchAppointmentScheduleID;
data['branchName'] = branchName;
data['address'] = address;
data['latitude'] = latitude;
data['longitude'] = longitude;
if (scheduleServices != null) {
data['scheduleServices'] = scheduleServices!.map((v) => v.toJson()).toList();
}
if (branchScheduleSlots != null) {
data['branchScheduleSlots'] = branchScheduleSlots!.map((v) => v.toJson()).toList();
}
data['totalItemsCount'] = totalItemsCount;
data['distanceKM'] = distanceKM;
return data;
}
}
class ScheduleServices {
int? providerServiceID;
String? providerServiceName;
ScheduleServices({this.providerServiceID, this.providerServiceName});
ScheduleServices.fromJson(Map<String, dynamic> json) {
providerServiceID = json['providerServiceID'];
providerServiceName = json['providerServiceName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['providerServiceID'] = providerServiceID;
data['providerServiceName'] = providerServiceName;
return data;
}
}
class BranchScheduleSlots {
int? id;
String? slotDate;
String? startTime;
String? endTime;
BranchScheduleSlots({this.id, this.slotDate, this.startTime, this.endTime});
BranchScheduleSlots.fromJson(Map<String, dynamic> json) {
id = json['id'];
slotDate = json['slotDate'];
startTime = json['startTime'];
endTime = json['endTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['slotDate'] = slotDate;
data['startTime'] = startTime;
data['endTime'] = endTime;
return data;
}
}

@ -0,0 +1,95 @@
class SSPhotoScheduleModel {
int? photoOfficeID;
String? fromDate;
String? toDate;
int? photoOfficeAppointmentScheduleID;
String? photoOfficeName;
String? description;
String? areaName;
String? latitude;
String? longitude;
int? distanceKM;
int? totalItemsCount;
List<PhotoOfficeScheduleSlots>? photoOfficeScheduleSlots;
SSPhotoScheduleModel(
{this.photoOfficeID,
this.fromDate,
this.toDate,
this.photoOfficeAppointmentScheduleID,
this.photoOfficeName,
this.description,
this.areaName,
this.latitude,
this.longitude,
this.distanceKM,
this.totalItemsCount,
this.photoOfficeScheduleSlots});
SSPhotoScheduleModel.fromJson(Map<String, dynamic> json) {
photoOfficeID = json['photoOfficeID'];
fromDate = json['fromDate'];
toDate = json['toDate'];
photoOfficeAppointmentScheduleID = json['photoOfficeAppointmentScheduleID'];
photoOfficeName = json['photoOfficeName'];
description = json['description'];
areaName = json['areaName'];
latitude = json['latitude'];
longitude = json['longitude'];
distanceKM = json['distanceKM'];
totalItemsCount = json['totalItemsCount'];
if (json['photoOfficeScheduleSlots'] != null) {
photoOfficeScheduleSlots = <PhotoOfficeScheduleSlots>[];
json['photoOfficeScheduleSlots'].forEach((v) {
photoOfficeScheduleSlots!.add(PhotoOfficeScheduleSlots.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['photoOfficeID'] = photoOfficeID;
data['fromDate'] = fromDate;
data['toDate'] = toDate;
data['photoOfficeAppointmentScheduleID'] =
photoOfficeAppointmentScheduleID;
data['photoOfficeName'] = photoOfficeName;
data['description'] = description;
data['areaName'] = areaName;
data['latitude'] = latitude;
data['longitude'] = longitude;
data['distanceKM'] = distanceKM;
data['totalItemsCount'] = totalItemsCount;
if (photoOfficeScheduleSlots != null) {
data['photoOfficeScheduleSlots'] =
photoOfficeScheduleSlots!.map((v) => v.toJson()).toList();
}
return data;
}
}
class PhotoOfficeScheduleSlots {
int? id;
String? slotDate;
String? startTime;
String? endTime;
PhotoOfficeScheduleSlots(
{this.id, this.slotDate, this.startTime, this.endTime});
PhotoOfficeScheduleSlots.fromJson(Map<String, dynamic> json) {
id = json['id'];
slotDate = json['slotDate'];
startTime = json['startTime'];
endTime = json['endTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['slotDate'] = slotDate;
data['startTime'] = startTime;
data['endTime'] = endTime;
return data;
}
}

@ -0,0 +1,109 @@
class AppointmentListModel {
int? id;
int? serviceSlotID;
int? appointmentStatusID;
String? appointmentStatusText;
int? serviceProviderID;
int? customerID;
bool? isActive;
bool? isPaymentRequired;
int? paymentStatus;
String? paymentStatusText;
String? customerName;
String? providerName;
String? duration;
String? appointmentDate;
List<ServiceAppointmentItems>? serviceAppointmentItems;
AppointmentListModel(
{this.id,
this.serviceSlotID,
this.appointmentStatusID,
this.appointmentStatusText,
this.serviceProviderID,
this.customerID,
this.isActive,
this.isPaymentRequired,
this.paymentStatus,
this.paymentStatusText,
this.customerName,
this.providerName,
this.duration,
this.appointmentDate,
this.serviceAppointmentItems});
AppointmentListModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
serviceSlotID = json['serviceSlotID'];
appointmentStatusID = json['appointmentStatusID'];
appointmentStatusText = json['appointmentStatusText'];
serviceProviderID = json['serviceProviderID'];
customerID = json['customerID'];
isActive = json['isActive'];
isPaymentRequired = json['isPaymentRequired'];
paymentStatus = json['paymentStatus'];
paymentStatusText = json['paymentStatusText'];
customerName = json['customerName'];
providerName = json['providerName'];
duration = json['duration'];
appointmentDate = json['appointmentDate'];
if (json['serviceAppointmentItems'] != null) {
serviceAppointmentItems = <ServiceAppointmentItems>[];
json['serviceAppointmentItems'].forEach((v) {
serviceAppointmentItems!.add(ServiceAppointmentItems.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['serviceSlotID'] = serviceSlotID;
data['appointmentStatusID'] = appointmentStatusID;
data['appointmentStatusText'] = appointmentStatusText;
data['serviceProviderID'] = serviceProviderID;
data['customerID'] = customerID;
data['isActive'] = isActive;
data['isPaymentRequired'] = isPaymentRequired;
data['paymentStatus'] = paymentStatus;
data['paymentStatusText'] = paymentStatusText;
data['customerName'] = customerName;
data['providerName'] = providerName;
data['duration'] = duration;
data['appointmentDate'] = appointmentDate;
if (serviceAppointmentItems != null) {
data['serviceAppointmentItems'] =
serviceAppointmentItems!.map((v) => v.toJson()).toList();
}
return data;
}
}
class ServiceAppointmentItems {
int? id;
int? serviceItemID;
String? serviceItemName;
String? serviceItemDescription;
ServiceAppointmentItems(
{this.id,
this.serviceItemID,
this.serviceItemName,
this.serviceItemDescription});
ServiceAppointmentItems.fromJson(Map<String, dynamic> json) {
id = json['id'];
serviceItemID = json['serviceItemID'];
serviceItemName = json['serviceItemName'];
serviceItemDescription = json['serviceItemDescription'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['serviceItemID'] = serviceItemID;
data['serviceItemName'] = serviceItemName;
data['serviceItemDescription'] = serviceItemDescription;
return data;
}
}

@ -1,5 +1,5 @@
class AdsGenericModel { class GenericRespModel {
AdsGenericModel({ GenericRespModel({
this.data, this.data,
this.messageStatus, this.messageStatus,
this.totalItemsCount, this.totalItemsCount,
@ -9,7 +9,7 @@ class AdsGenericModel {
int? messageStatus; int? messageStatus;
int? totalItemsCount; int? totalItemsCount;
factory AdsGenericModel.fromJson(Map<String, dynamic> json) => AdsGenericModel( factory GenericRespModel.fromJson(Map<String, dynamic> json) => GenericRespModel(
data: json["data"], data: json["data"],
messageStatus: json["messageStatus"], messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"], totalItemsCount: json["totalItemsCount"],

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

@ -0,0 +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}';
}
}

@ -1,6 +1,34 @@
class FilterListModel { class FilterListModel {
String title; String title;
int id;
bool isSelected; bool isSelected;
FilterListModel({required this.isSelected, required this.title}); FilterListModel({required this.id, required this.isSelected, required this.title});
} }
class SelectionModel {
String selectedOption;
int selectedId;
String errorValue;
String itemPrice;
SelectionModel({
this.selectedOption = "",
this.errorValue = "",
this.selectedId = 0,
this.itemPrice = "",
});
}
class TimeSlotModel {
int slotId;
bool isSelected;
String slot;
TimeSlotModel({
this.slot = "",
this.slotId = 0,
this.isSelected = false,
});
}

@ -0,0 +1,337 @@
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/vehicle_details_models.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
abstract class AdsRepo {
Future<List<VehicleTypeModel>> getVehicleTypes();
Future<List<VehicleModel>> getVehicleModels({required int vehicleTypeId});
Future<List<VehicleYearModel>> getVehicleModelYears({required int vehicleTypeId});
Future<List<VehicleColorModel>> getVehicleColors({required int vehicleTypeId});
Future<List<VehicleConditionModel>> getVehicleConditions({required int vehicleTypeId});
Future<List<VehicleCategoryModel>> getVehicleCategories({required int vehicleTypeId});
Future<List<VehicleMileageModel>> getVehicleMileages({required int vehicleTypeId});
Future<List<VehicleTransmissionModel>> getVehicleTransmission({required int vehicleTypeId});
Future<List<VehicleSellerTypeModel>> getVehicleSellerTypes({required int vehicleTypeId});
Future<List<VehicleCountryModel>> getVehicleCountries();
Future<List<VehicleCityModel>> getVehicleCities({required int countryId});
Future<List<VehiclePartModel>> getVehicleDamageParts();
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId});
Future<List<AdsDurationModel>> getAdsDuration();
Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceId});
Future<GenericRespModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel});
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds});
Future<List<AdDetailsModel>> getMyAds();
}
class AdsRepoImp implements AdsRepo {
ApiClient apiClient = injector.get<ApiClient>();
AppState appState = injector.get<AppState>();
@override
Future<List<VehicleTypeModel>> getVehicleTypes() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTypeGet);
List<VehicleTypeModel> vehicleTypes = List.generate(adsGenericModel.data.length, (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleTypes;
}
@override
Future<List<VehicleCategoryModel>> getVehicleCategories({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCategoryGet, queryParameters: postParams);
List<VehicleCategoryModel> vehicleCategories = List.generate(adsGenericModel.data.length, (index) => VehicleCategoryModel.fromJson(adsGenericModel.data[index]));
return vehicleCategories;
}
@override
Future<List<VehicleCityModel>> getVehicleCities({required int countryId}) async {
var postParams = {
"CountryID": countryId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams);
List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
return vehicleCities;
}
@override
Future<List<VehicleColorModel>> getVehicleColors({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleColorGet, queryParameters: postParams);
List<VehicleColorModel> vehicleColors = List.generate(adsGenericModel.data.length, (index) => VehicleColorModel.fromJson(adsGenericModel.data[index]));
return vehicleColors;
}
@override
Future<List<VehicleConditionModel>> getVehicleConditions({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleConditionGet, queryParameters: postParams);
List<VehicleConditionModel> vehicleConditions = List.generate(adsGenericModel.data.length, (index) => VehicleConditionModel.fromJson(adsGenericModel.data[index]));
return vehicleConditions;
}
@override
Future<List<VehicleCountryModel>> getVehicleCountries() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleCountryGet,
);
List<VehicleCountryModel> vehicleConditions = List.generate(adsGenericModel.data.length, (index) => VehicleCountryModel.fromJson(adsGenericModel.data[index]));
return vehicleConditions;
}
@override
Future<List<VehicleMileageModel>> getVehicleMileages({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleMileageGet, queryParameters: postParams);
List<VehicleMileageModel> vehicleMileages = List.generate(adsGenericModel.data.length, (index) => VehicleMileageModel.fromJson(adsGenericModel.data[index]));
return vehicleMileages;
}
@override
Future<List<VehicleYearModel>> getVehicleModelYears({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelYearGet, queryParameters: postParams);
List<VehicleYearModel> vehicleModelYears = List.generate(adsGenericModel.data.length, (index) => VehicleYearModel.fromJson(adsGenericModel.data[index]));
return vehicleModelYears;
}
@override
Future<List<VehicleModel>> getVehicleModels({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelGet, queryParameters: postParams);
List<VehicleModel> vehicleModels = List.generate(adsGenericModel.data.length, (index) => VehicleModel.fromJson(adsGenericModel.data[index]));
return vehicleModels;
}
@override
Future<List<VehicleSellerTypeModel>> getVehicleSellerTypes({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleSellerTypeGet, queryParameters: postParams);
List<VehicleSellerTypeModel> vehicleSellerTypes = List.generate(adsGenericModel.data.length, (index) => VehicleSellerTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleSellerTypes;
}
@override
Future<List<VehicleTransmissionModel>> getVehicleTransmission({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTransmissionGet, queryParameters: postParams);
List<VehicleTransmissionModel> vehicleTransmissions = List.generate(adsGenericModel.data.length, (index) => VehicleTransmissionModel.fromJson(adsGenericModel.data[index]));
return vehicleTransmissions;
}
@override
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId}) async {
var postParams = {
"vehicleType": vehicleTypeId.toString(),
"isVehicleBrand": "true",
"vehicleBrand": "0",
"isVehicleCategory": "true",
"isVehicleColor": "true",
"isVehicleCondition": "true",
"isVehicleMileage": "true",
"isVehicleModel": "true",
"isVehicleModelYear": "true",
"isVehiclePriceRange": "true",
"isVehiclePricingMethod": "true",
"isVehcileSellerType": "true",
"isVehicleTransmission": "true",
"isCountry": "true"
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleDetailsMaster,
postParams,
token: token,
);
VehicleDetailsModel vehicleDetails = VehicleDetailsModel.fromJson(adsGenericModel.data);
return vehicleDetails;
}
@override
Future<List<VehiclePartModel>> getVehicleDamageParts() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleDamagePartGet,
);
List<VehiclePartModel> vehicleParts = List.generate(adsGenericModel.data.length, (index) => VehiclePartModel.fromJson(adsGenericModel.data[index]));
return vehicleParts;
}
@override
Future<List<AdsDurationModel>> getAdsDuration() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsDurationGet,
);
List<AdsDurationModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => AdsDurationModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDuration;
}
@override
Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceId}) async {
var params = {
"SpecialServiceType": specialServiceId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params);
List<SpecialServiceModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => SpecialServiceModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDuration;
}
@override
Future<GenericRespModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel}) async {
List vehiclePostingImages = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) {
var imageMap = {
"id": 0,
"imageName": element.imageName,
"imageUrl": element.imageUrl,
"imageStr": element.imageStr,
"vehiclePostingID": 0,
"vehiclePosting": null,
};
vehiclePostingImages.add(imageMap);
});
List vehiclePostingDamageParts = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
var imageMap = {
"id": 0,
"comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingID": 0,
"isActive": true
};
vehiclePostingDamageParts.add(imageMap);
});
var postParams = {
"ads": {
"id": 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId,
"specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs,
"isMCHandled": false
},
"vehiclePosting": {
"id": 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
"vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID,
"vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID,
"vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID,
"vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
"vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
"vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
"vehicleSellerTypeID": adsCreationPayloadModel.vehiclePosting!.vehicleSellerTypeID,
"cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
"price": adsCreationPayloadModel.vehiclePosting!.price,
"vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
"vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle,
"vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable,
"warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears,
"demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount,
// "adStatus": 1,
"vehiclePostingImages": vehiclePostingImages,
"vehiclePostingDamageParts": vehiclePostingDamageParts
}
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsSingleStepCreate,
postParams,
token: token,
);
return Future.value(adsGenericModel);
}
@override
Future<List<AdDetailsModel>> getAllAds({required isMyAds}) async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsGet,
queryParameters: isMyAds ? params : null,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
}
@override
Future<List<AdDetailsModel>> getMyAds() async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
queryParameters: params,
ApiConsts.vehicleAdsGet,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
}
}

@ -4,9 +4,14 @@ import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.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/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_generic_model.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_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/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/cities.dart';
import 'package:mc_common_app/models/user/country.dart'; import 'package:mc_common_app/models/user/country.dart';
import 'package:mc_common_app/models/user/role.dart'; import 'package:mc_common_app/models/user/role.dart';
@ -18,41 +23,16 @@ abstract class CommonRepo {
Future<Role> getRoles(); Future<Role> getRoles();
Future<List<VehicleTypeModel>> getVehicleTypes();
Future<List<VehicleModel>> getVehicleModels({required int vehicleTypeId}); Future<List<AppointmentListModel>> getMyAppointments();
Future<List<VehicleYearModel>> getVehicleModelYears({required int vehicleTypeId}); Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long});
Future<List<VehicleColorModel>> getVehicleColors({required int vehicleTypeId}); Future<SSPhotoScheduleModel> getPhotographyServiceScheduleDetails({required double lat, required double long});
Future<List<VehicleConditionModel>> getVehicleConditions({required int vehicleTypeId}); Future<List<ProviderCategoryModel>> getProviderServiceCategories();
Future<List<VehicleCategoryModel>> getVehicleCategories({required int vehicleTypeId}); Future<List<ProviderServiceModel>> getProviderServices({required int categoryId});
Future<List<VehicleMileageModel>> getVehicleMileages({required int vehicleTypeId});
Future<List<VehicleTransmissionModel>> getVehicleTransmission({required int vehicleTypeId});
Future<List<VehicleSellerTypeModel>> getVehicleSellerTypes({required int vehicleTypeId});
Future<List<VehicleCountryModel>> getVehicleCountries();
Future<List<VehicleCityModel>> getVehicleCities({required int countryId});
Future<List<VehiclePartModel>> getVehicleDamageParts();
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId});
Future<List<AdsDurationModel>> getAdsDuration();
Future<List<SpecialServiceModel>> getSpecialServices();
Future<AdsGenericModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel});
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds});
Future<List<AdDetailsModel>> getMyAds();
} }
class CommonRepoImp implements CommonRepo { class CommonRepoImp implements CommonRepo {
@ -77,288 +57,69 @@ class CommonRepoImp implements CommonRepo {
return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles); return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles);
} }
@override
Future<List<VehicleTypeModel>> getVehicleTypes() async {
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleTypeGet);
List<VehicleTypeModel> vehicleTypes = List.generate(adsGenericModel.data.length, (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleTypes;
}
@override
Future<List<VehicleCategoryModel>> getVehicleCategories({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleCategoryGet, queryParameters: postParams);
List<VehicleCategoryModel> vehicleCategories = List.generate(adsGenericModel.data.length, (index) => VehicleCategoryModel.fromJson(adsGenericModel.data[index]));
return vehicleCategories;
}
@override
Future<List<VehicleCityModel>> getVehicleCities({required int countryId}) async {
var postParams = {
"CountryID": countryId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams);
List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
return vehicleCities;
}
@override
Future<List<VehicleColorModel>> getVehicleColors({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleColorGet, queryParameters: postParams);
List<VehicleColorModel> vehicleColors = List.generate(adsGenericModel.data.length, (index) => VehicleColorModel.fromJson(adsGenericModel.data[index]));
return vehicleColors;
}
@override @override
Future<List<VehicleConditionModel>> getVehicleConditions({required int vehicleTypeId}) async { Future<List<AppointmentListModel>> getMyAppointments() async {
var postParams = { var params = {
"VehicleType": vehicleTypeId.toString(), "userID": appState.getUser.data!.userInfo!.userId ?? "",
}; };
AdsGenericModel adsGenericModel = GenericRespModel genericRespModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleConditionGet, queryParameters: postParams);
List<VehicleConditionModel> vehicleConditions = List.generate(adsGenericModel.data.length, (index) => VehicleConditionModel.fromJson(adsGenericModel.data[index]));
return vehicleConditions;
}
@override
Future<List<VehicleCountryModel>> getVehicleCountries() async {
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
(json) => AdsGenericModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleCountryGet, queryParameters: params,
ApiConsts.serviceProvidersAppointmentGet,
); );
List<VehicleCountryModel> vehicleConditions = List.generate(adsGenericModel.data.length, (index) => VehicleCountryModel.fromJson(adsGenericModel.data[index])); List<AppointmentListModel> appointmentList = List.generate(genericRespModel.data.length, (index) => AppointmentListModel.fromJson(genericRespModel.data[index]));
return vehicleConditions; return appointmentList;
}
@override
Future<List<VehicleMileageModel>> getVehicleMileages({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleMileageGet, queryParameters: postParams);
List<VehicleMileageModel> vehicleMileages = List.generate(adsGenericModel.data.length, (index) => VehicleMileageModel.fromJson(adsGenericModel.data[index]));
return vehicleMileages;
}
@override
Future<List<VehicleYearModel>> getVehicleModelYears({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleModelYearGet, queryParameters: postParams);
List<VehicleYearModel> vehicleModelYears = List.generate(adsGenericModel.data.length, (index) => VehicleYearModel.fromJson(adsGenericModel.data[index]));
return vehicleModelYears;
}
@override
Future<List<VehicleModel>> getVehicleModels({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleModelGet, queryParameters: postParams);
List<VehicleModel> vehicleModels = List.generate(adsGenericModel.data.length, (index) => VehicleModel.fromJson(adsGenericModel.data[index]));
return vehicleModels;
}
@override
Future<List<VehicleSellerTypeModel>> getVehicleSellerTypes({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleSellerTypeGet, queryParameters: postParams);
List<VehicleSellerTypeModel> vehicleSellerTypes = List.generate(adsGenericModel.data.length, (index) => VehicleSellerTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleSellerTypes;
}
@override
Future<List<VehicleTransmissionModel>> getVehicleTransmission({required int vehicleTypeId}) async {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
AdsGenericModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => AdsGenericModel.fromJson(json), ApiConsts.vehicleTransmissionGet, queryParameters: postParams);
List<VehicleTransmissionModel> vehicleTransmissions = List.generate(adsGenericModel.data.length, (index) => VehicleTransmissionModel.fromJson(adsGenericModel.data[index]));
return vehicleTransmissions;
} }
@override @override
Future<VehicleDetailsModel> getVehicleDetails({required int vehicleTypeId}) async { Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long}) async {
var postParams = { var params = {
"vehicleType": vehicleTypeId.toString(), "Latitude": lat.toString(),
"isVehicleBrand": "true", "Longitude": long.toString(),
"vehicleBrand": "0",
"isVehicleCategory": "true",
"isVehicleColor": "true",
"isVehicleCondition": "true",
"isVehicleMileage": "true",
"isVehicleModel": "true",
"isVehicleModelYear": "true",
"isVehiclePriceRange": "true",
"isVehiclePricingMethod": "true",
"isVehcileSellerType": "true",
"isVehicleTransmission": "true",
"isCountry": "true"
}; };
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
String token = appState.getUser.data!.accessToken ?? "";
AdsGenericModel adsGenericModel = await apiClient.postJsonForObject(
(json) => AdsGenericModel.fromJson(json),
ApiConsts.vehicleDetailsMaster,
postParams,
token: token,
);
VehicleDetailsModel vehicleDetails = VehicleDetailsModel.fromJson(adsGenericModel.data);
return vehicleDetails;
}
@override
Future<List<VehiclePartModel>> getVehicleDamageParts() async {
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
(json) => AdsGenericModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleDamagePartGet, queryParameters: params,
ApiConsts.adsCarCheckupSPBranchScheduleSlotGet,
); );
List<VehiclePartModel> vehicleParts = List.generate(adsGenericModel.data.length, (index) => VehiclePartModel.fromJson(adsGenericModel.data[index])); SSCarCheckScheduleModel ssCarCheckScheduleModel = SSCarCheckScheduleModel.fromJson(genericRespModel.data[0]);
return vehicleParts; return ssCarCheckScheduleModel;
} }
@override @override
Future<List<AdsDurationModel>> getAdsDuration() async { Future<SSPhotoScheduleModel> getPhotographyServiceScheduleDetails({required double lat, required double long}) async {
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject( var params = {
"Latitude": lat.toString(),
"Longitude": long.toString(),
};
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
(json) => AdsGenericModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsDurationGet, queryParameters: params,
ApiConsts.adsPhotoOfficeAppointmentScheduleSlotGet,
); );
List<AdsDurationModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => AdsDurationModel.fromJson(adsGenericModel.data[index])); SSPhotoScheduleModel ssPhotoScheduleModel = SSPhotoScheduleModel.fromJson(genericRespModel.data[0]);
return vehicleAdsDuration; return ssPhotoScheduleModel;
} }
@override @override
Future<List<SpecialServiceModel>> getSpecialServices() async { Future<List<ProviderCategoryModel>> getProviderServiceCategories() async {
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject( GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet);
token: appState.getUser.data!.accessToken, List<ProviderCategoryModel> providerCategories = List.generate(adsGenericModel.data.length, (index) => ProviderCategoryModel.fromJson(adsGenericModel.data[index]));
(json) => AdsGenericModel.fromJson(json), return providerCategories;
ApiConsts.vehicleAdsSpecialServicesGet,
);
List<SpecialServiceModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => SpecialServiceModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDuration;
} }
@override @override
Future<AdsGenericModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel}) async { Future<List<ProviderServiceModel>> getProviderServices({required int categoryId}) async {
List vehiclePostingImages = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) {
var imageMap = {
"id": 0,
"imageName": element.imageName,
"imageUrl": element.imageUrl,
"imageStr": element.imageStr,
"vehiclePostingID": 0,
"vehiclePosting": null,
};
vehiclePostingImages.add(imageMap);
});
List vehiclePostingDamageParts = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
var imageMap = {
"id": 0,
"comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingID": 0,
"isActive": true
};
vehiclePostingDamageParts.add(imageMap);
});
var postParams = { var postParams = {
"ads": { "ServiceCategoryID": categoryId.toString(),
"id": 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId,
"specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs,
"isMCHandled": false
},
"vehiclePosting": {
"id": 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
"vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID,
"vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID,
"vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID,
"vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
"vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
"vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
"vehicleSellerTypeID": adsCreationPayloadModel.vehiclePosting!.vehicleSellerTypeID,
"cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
"price": adsCreationPayloadModel.vehiclePosting!.price,
"vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
"vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle,
"vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable,
"warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears,
"demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount,
// "adStatus": 1,
"vehiclePostingImages": vehiclePostingImages,
"vehiclePostingDamageParts": vehiclePostingDamageParts
}
};
String token = appState.getUser.data!.accessToken ?? "";
AdsGenericModel adsGenericModel = await apiClient.postJsonForObject(
(json) => AdsGenericModel.fromJson(json),
ApiConsts.vehicleAdsSingleStepCreate,
postParams,
token: token,
);
return Future.value(adsGenericModel);
}
@override
Future<List<AdDetailsModel>> getAllAds({required isMyAds}) async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
}; };
GenericRespModel adsGenericModel =
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject( await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet, queryParameters: postParams);
token: appState.getUser.data!.accessToken, List<ProviderServiceModel> providerServices = List.generate(adsGenericModel.data.length, (index) => ProviderServiceModel.fromJson(adsGenericModel.data[index]));
(json) => AdsGenericModel.fromJson(json), return providerServices;
ApiConsts.vehicleAdsGet,
queryParameters: isMyAds ? params : null,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
}
@override
Future<List<AdDetailsModel>> getMyAds() async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
};
AdsGenericModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => AdsGenericModel.fromJson(json),
queryParameters: params,
ApiConsts.vehicleAdsGet,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
} }
} }

@ -35,6 +35,7 @@ class MyColors {
static const Color white = Color(0xffffffff); static const Color white = Color(0xffffffff);
static const Color green = Color(0xffffffff); static const Color green = Color(0xffffffff);
static const Color borderColor = Color(0xffE8E8E8); static const Color borderColor = Color(0xffE8E8E8);
static const Color greyAddBorderColor = Color(0xffEEEEEE);
static Decoration gradient = BoxDecoration( static Decoration gradient = BoxDecoration(
gradient: const LinearGradient(colors: [ gradient: const LinearGradient(colors: [

@ -5,6 +5,20 @@
// unverified, // unverified,
// } // }
enum AdPostStatus {
pendingForReview,
pendingForPayment,
rejected,
cancelled,
pendingForPost,
active,
expired,
sold,
reserved,
buyingService,
reserveCancel,
}
enum AdCreationStepsEnum { enum AdCreationStepsEnum {
vehicleDetails, vehicleDetails,
damageParts, damageParts,

@ -175,6 +175,7 @@ class Utils {
); );
} }
static InputDecoration txtField(String label) { static InputDecoration txtField(String label) {
return InputDecoration( return InputDecoration(
border: InputBorder.none, border: InputBorder.none,

@ -6,24 +6,31 @@ import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.dart'; 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/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_generic_model.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_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/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
import 'package:mc_common_app/models/widgets_models.dart'; import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/services.dart'; import 'package:mc_common_app/services/services.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
class AdVM extends BaseVM { class AdVM extends BaseVM {
final CommonRepo commonRepo; final CommonRepo commonRepo;
final AdsRepo adsRepo;
final CommonServices commonServices; final CommonServices commonServices;
AdVM({required this.commonServices, required this.commonRepo}); AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo});
AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails; AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails;
@ -39,10 +46,13 @@ class AdVM extends BaseVM {
List<VehicleTransmissionModel> vehicleTransmissions = []; List<VehicleTransmissionModel> vehicleTransmissions = [];
List<VehicleSellerTypeModel> vehicleSellerTypes = []; List<VehicleSellerTypeModel> vehicleSellerTypes = [];
List<VehiclePartModel> vehicleDamageParts = []; List<VehiclePartModel> vehicleDamageParts = [];
List<VehiclePartModel> vehiclePartsSearchResults = [];
List<VehicleCountryModel> vehicleCountries = []; List<VehicleCountryModel> vehicleCountries = [];
List<VehicleCityModel> vehicleCities = []; List<VehicleCityModel> vehicleCities = [];
List<AdsDurationModel> vehicleAdsDurations = []; List<AdsDurationModel> vehicleAdsDurations = [];
List<SpecialServiceModel> vehicleAdsSpecialServices = []; List<SpecialServiceModel> vehicleAdsSpecialServices = [];
SSCarCheckScheduleModel? ssCarCheckScheduleModel;
SSPhotoScheduleModel? ssPhotoScheduleModel;
String demandAmountError = ""; String demandAmountError = "";
String vehicleVinError = ""; String vehicleVinError = "";
@ -52,9 +62,12 @@ class AdVM extends BaseVM {
String vehicleImageError = ""; String vehicleImageError = "";
String vehicleDamageImageError = ""; String vehicleDamageImageError = "";
String adStartDateError = ""; String adStartDateError = "";
String damagePartSearchValue = "";
String adReservePriceError = "";
List<AdDetailsModel> allAds = []; List<AdDetailsModel> exploreAds = [];
List<AdDetailsModel> adsFilteredList = []; List<AdDetailsModel> exploreAdsFilteredList = [];
List<AdDetailsModel> myAdsFilteredList = [];
List<AdDetailsModel> myAds = []; List<AdDetailsModel> myAds = [];
List<VehicleDamageCard> vehicleDamageCards = []; List<VehicleDamageCard> vehicleDamageCards = [];
@ -97,68 +110,119 @@ class AdVM extends BaseVM {
void clearSpecialServiceCard() { void clearSpecialServiceCard() {
specialServiceCards.clear(); specialServiceCards.clear();
notifyListeners();
}
void onSearchChangedForDamagePart(String text) {
vehiclePartsSearchResults.clear();
damagePartSearchValue = text;
if (text.isEmpty) {
notifyListeners();
return;
}
for (var damagePartDetail in vehicleDamageParts) {
if (damagePartDetail.partName!.toLowerCase().contains(text.toLowerCase())) {
vehiclePartsSearchResults.add(damagePartDetail);
notifyListeners();
}
}
} }
bool isExploreAdsTapped = true; bool isExploreAdsTapped = true;
void updateIsExploreAds(bool value) async { void updateIsExploreAds(bool value) async {
isExploreAdsTapped = value; isExploreAdsTapped = value;
//To show the Active Ads
applyFilterOnMyAds(index: 0, selectedFilterId: 6);
// if (value) { // if (value) {
// await getAllAds(); // await getAllAds();
// } // }
notifyListeners(); notifyListeners();
} }
List<FilterListModel> adsFilterOptions = []; List<FilterListModel> exploreAdsFilterOptions = [];
List<FilterListModel> myAdsFilterOptions = [];
populateAdsFilterList() { populateAdsFilterList() {
adsFilterOptions.clear(); exploreAdsFilterOptions.clear();
adsFilterOptions = [ exploreAdsFilterOptions.clear();
FilterListModel(title: "All Ads", isSelected: true), exploreAdsFilterOptions = [
FilterListModel(title: "Customer Ads", isSelected: false), FilterListModel(title: "All Ads", isSelected: true, id: -1),
FilterListModel(title: "Provider Ads", isSelected: false), FilterListModel(title: "Customer Ads", isSelected: false, id: 0),
FilterListModel(title: "Mowater Ads", isSelected: false), FilterListModel(title: "Provider Ads", isSelected: false, id: 1),
FilterListModel(title: "Mowater Ads", isSelected: false, id: 2),
];
myAdsFilterOptions = [
// FilterListModel(title: "All Ads", isSelected: true, id: -1),
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: "Rejected", isSelected: false, id: 3),
FilterListModel(title: "Pending For Post", isSelected: false, id: 5),
FilterListModel(title: "Reserved", isSelected: false, id: 9),
]; ];
notifyListeners(); notifyListeners();
} }
applyFilterOnAds({required int index}) { applyFilterOnExploreAds({required int index}) {
if (adsFilterOptions.isEmpty) return; if (exploreAdsFilterOptions.isEmpty) return;
for (var value in adsFilterOptions) { for (var value in exploreAdsFilterOptions) {
value.isSelected = false; value.isSelected = false;
} }
adsFilterOptions[index].isSelected = true; exploreAdsFilterOptions[index].isSelected = true;
// TODO: --> here we will filter the allAds list // TODO: --> here we will filter the allAds list
// TODO: --> and get the updated list into this new list everytime filter changes // TODO: --> and get the updated list into this new list everytime filter changes
adsFilteredList = allAds; exploreAdsFilteredList = exploreAds;
notifyListeners();
}
applyFilterOnMyAds({required int index, required int selectedFilterId}) {
if (myAdsFilterOptions.isEmpty) return;
for (var value in myAdsFilterOptions) {
value.isSelected = false;
}
myAdsFilterOptions[index].isSelected = true;
if (selectedFilterId == -1) {
myAdsFilteredList = myAds;
notifyListeners();
return;
}
myAdsFilteredList = myAds.where((element) => element.statusID! == selectedFilterId).toList();
notifyListeners(); notifyListeners();
} }
Future<void> getMyAds() async { Future<void> getMyAds() async {
isFetchingLists = true; isFetchingLists = true;
myAds = await commonRepo.getAllAds(isMyAds: true); myAds = await adsRepo.getAllAds(isMyAds: true);
isFetchingLists = true; isFetchingLists = true;
notifyListeners(); notifyListeners();
} }
Future<void> getAllAds() async { Future<void> getExploreAds() async {
allAds = await commonRepo.getAllAds(isMyAds: false); exploreAds = await adsRepo.getAllAds(isMyAds: false);
notifyListeners(); notifyListeners();
} }
Future<void> getVehicleTypes() async { Future<void> getVehicleTypes() async {
vehicleTypes = await commonRepo.getVehicleTypes(); vehicleTypes = await adsRepo.getVehicleTypes();
notifyListeners(); notifyListeners();
} }
Future<void> getVehicleAdsDuration() async { Future<void> getVehicleAdsDuration() async {
vehicleAdsDurations = await commonRepo.getAdsDuration(); vehicleAdsDurations = await adsRepo.getAdsDuration();
notifyListeners(); notifyListeners();
} }
Future<void> getVehicleAdsSpecialServices() async { Future<void> getVehicleAdsSpecialServices() async {
vehicleAdsSpecialServices = await commonRepo.getSpecialServices(); vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceId: 1);
notifyListeners(); notifyListeners();
} }
@ -171,14 +235,14 @@ class AdVM extends BaseVM {
} }
isFetchingLists = true; isFetchingLists = true;
notifyListeners(); notifyListeners();
vehicleModels = await commonRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId); vehicleModels = await adsRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId);
vehicleModelYears = await commonRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId); vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId);
vehicleColors = await commonRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId); vehicleColors = await adsRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId);
vehicleConditions = await commonRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId); vehicleConditions = await adsRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId);
vehicleCategories = await commonRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId); vehicleCategories = await adsRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId);
vehicleMileages = await commonRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId); vehicleMileages = await adsRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId);
vehicleTransmissions = await commonRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId); vehicleTransmissions = await adsRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId);
vehicleCountries = await commonRepo.getVehicleCountries(); vehicleCountries = await adsRepo.getVehicleCountries();
isFetchingLists = false; isFetchingLists = false;
notifyListeners(); notifyListeners();
} }
@ -189,7 +253,7 @@ class AdVM extends BaseVM {
} }
isFetchingLists = true; isFetchingLists = true;
notifyListeners(); notifyListeners();
vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId); vehicleDetails = await adsRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId);
if (vehicleDetails != null) { if (vehicleDetails != null) {
vehicleModels = vehicleDetails!.vehicleModels!; vehicleModels = vehicleDetails!.vehicleModels!;
@ -214,6 +278,14 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
String adReserveAmount = "";
void updateAdReservePriceAmount(String date) {
adReserveAmount = date;
if (adReserveAmount.isNotEmpty) adReservePriceError = "";
notifyListeners();
}
String adSpecialServiceDate = ""; String adSpecialServiceDate = "";
void updateAdSpecialServiceDate(String date) { void updateAdSpecialServiceDate(String date) {
@ -318,7 +390,7 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
// SelectionModel vehicleDamagePartId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); // SelectionModel vehicleDamagePartId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleDamagePartId(SelectionModel id, int index) { void updateSelectionVehicleDamagePartId(SelectionModel id, int index) {
vehicleDamageCards[index].partSelectedId = id; vehicleDamageCards[index].partSelectedId = id;
@ -335,7 +407,7 @@ class AdVM extends BaseVM {
vehicleCountryId = id; vehicleCountryId = id;
isCountryFetching = true; isCountryFetching = true;
notifyListeners(); notifyListeners();
vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId); vehicleCities = await adsRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
isCountryFetching = false; isCountryFetching = false;
notifyListeners(); notifyListeners();
} }
@ -354,13 +426,132 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleAdReservableId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateVehicleAdReservableId(SelectionModel id) {
vehicleAdReservableId = id;
notifyListeners();
}
SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateVehicleAdsSpecialServicesId(SelectionModel id) { void updateVehicleAdsSpecialServicesId(SelectionModel id) async {
vehicleAdsSpecialServicesId = id; 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;
notifyListeners();
}
List<TimeSlotModel> adSSTimeSlots = [];
int? slotSelectedIndex;
void updateIsSelectedInSlots(int index) {
for (var value in adSSTimeSlots) {
value.isSelected = false;
}
slotSelectedIndex = index;
notifyListeners();
adSSTimeSlots[index].isSelected = true;
}
SelectionModel vehicleAdsPhotoServiceDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateVehicleVehicleAdsPhotoServiceDate(SelectionModel id) {
vehicleAdsPhotoServiceDate = id;
adSSTimeSlots.clear();
slotSelectedIndex = null;
for (var value in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) {
if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsPhotoServiceDate.selectedOption) {
adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!));
}
}
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleAdsCarCheckServicesDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateVehicleAdsCarCheckServicesDate(SelectionModel id) {
vehicleAdsCarCheckServicesDate = id;
adSSTimeSlots.clear();
slotSelectedIndex = null;
for (var value in ssCarCheckScheduleModel!.branchScheduleSlots!) {
if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsCarCheckServicesDate.selectedOption) {
adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!));
}
}
notifyListeners();
}
String selectedTimeSlotForEngineCarCheck = "";
void updateSelectedTimeSlotForEngineCarCheck(String timeSlot) {
selectedTimeSlotForEngineCarCheck = timeSlot;
notifyListeners();
}
bool isPresentInThisList({required List list, required String item}) {
bool isPresent = false;
for (var element in list) {
if (element == item) {
isPresent = true;
break;
}
}
return isPresent;
}
List<DropValue> populateScheduleDatesForAdPhotoService() {
List<DropValue> vehicleAdsSpecialServiceDates = [];
List<String> slotDates = [];
if (ssPhotoScheduleModel!.photoOfficeScheduleSlots == null) {
return [];
}
for (var element in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) {
if (!slotDates.contains(element.slotDate!)) {
slotDates.add(element.slotDate!);
vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), ""));
}
}
return vehicleAdsSpecialServiceDates;
}
List<DropValue> populateScheduleDatesForAdCarCheckService() {
List<DropValue> vehicleAdsSpecialServiceDates = [];
List<String> slotDates = [];
if (ssCarCheckScheduleModel!.branchScheduleSlots == null) {
return [];
}
for (var element in ssCarCheckScheduleModel!.branchScheduleSlots!) {
if (!slotDates.contains(element.slotDate!)) {
slotDates.add(element.slotDate!);
vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), ""));
}
}
return vehicleAdsSpecialServiceDates;
}
bool isVehicleDetailsValidated() { bool isVehicleDetailsValidated() {
bool isValidated = true; bool isValidated = true;
if (vehicleTypeId.selectedId == -1) { if (vehicleTypeId.selectedId == -1) {
@ -485,23 +676,23 @@ class AdVM extends BaseVM {
bool isDamagePartsValidated() { bool isDamagePartsValidated() {
bool isValidated = true; bool isValidated = true;
vehicleDamageCards.forEach((element) { for (var element in vehicleDamageCards) {
if (element.partSelectedId!.selectedId == -1) { if (element.partSelectedId!.selectedId == -1) {
element.partSelectedId!.errorValue = "Please select vehicle part"; element.partSelectedId!.errorValue = "Please select vehicle part";
isValidated = false; isValidated = false;
} else { } else {
element.partSelectedId!.errorValue = ""; element.partSelectedId!.errorValue = "";
} }
}); }
vehicleDamageCards.forEach((element) { for (var element in vehicleDamageCards) {
if (element.partImages == null || element.partImages!.isEmpty) { if (element.partImages == null || element.partImages!.isEmpty) {
element.partImageErrorValue = GlobalConsts.attachDamagePartImage; element.partImageErrorValue = GlobalConsts.attachDamagePartImage;
isValidated = false; isValidated = false;
} else { } else {
element.partImageErrorValue = ""; element.partImageErrorValue = "";
} }
}); }
// if (pickedDamageImages.isEmpty || pickedDamageImages.length < 3) { // if (pickedDamageImages.isEmpty || pickedDamageImages.length < 3) {
// vehicleDamageImageError = GlobalConsts.attachImageError; // vehicleDamageImageError = GlobalConsts.attachImageError;
@ -530,6 +721,20 @@ class AdVM extends BaseVM {
adStartDateError = ""; adStartDateError = "";
} }
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(); notifyListeners();
return isValidated; return isValidated;
} }
@ -591,6 +796,7 @@ class AdVM extends BaseVM {
Utils.showToast("A new ads has been created."); Utils.showToast("A new ads has been created.");
currentProgressStep = AdCreationStepsEnum.vehicleDetails; currentProgressStep = AdCreationStepsEnum.vehicleDetails;
resetValues(); resetValues();
updateIsExploreAds(false);
navigateReplaceWithName(context, AppRoutes.dashboard); navigateReplaceWithName(context, AppRoutes.dashboard);
} catch (e) { } catch (e) {
Utils.hideLoading(context); Utils.hideLoading(context);
@ -626,8 +832,8 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
// sourceFlag for Camera = 0 // sourceFlag for Camera = 0
// sourceFlag for Gallery = 1 // sourceFlag for Gallery = 1
void pickDamagePartImage(int index) async { void pickDamagePartImage(int index) async {
List<File> images = await commonServices.pickMultipleImages(); List<File> images = await commonServices.pickMultipleImages();
@ -716,7 +922,7 @@ class AdVM extends BaseVM {
} }
Future<void> getVehicleDamagePartsList() async { Future<void> getVehicleDamagePartsList() async {
vehicleDamageParts = await commonRepo.getVehicleDamageParts(); vehicleDamageParts = await adsRepo.getVehicleDamageParts();
notifyListeners(); notifyListeners();
} }
@ -742,7 +948,7 @@ class AdVM extends BaseVM {
List<VehiclePostingDamageParts> vehicleDamageImages = []; List<VehiclePostingDamageParts> vehicleDamageImages = [];
for (var card in vehicleDamageCards) { for (var card in vehicleDamageCards) {
if (card.partImages != null && card.partImages!.length > 0) { if (card.partImages != null && card.partImages!.isNotEmpty) {
for (var image in card.partImages!) { for (var image in card.partImages!) {
VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts( VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
file: image, file: image,
@ -778,7 +984,7 @@ class AdVM extends BaseVM {
); );
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
AdsGenericModel respModel = await commonRepo.createNewAd(adsCreationPayloadModel: adsCreationPayloadModel); GenericRespModel respModel = await adsRepo.createNewAd(adsCreationPayloadModel: adsCreationPayloadModel);
return Future.value(respModel.messageStatus); return Future.value(respModel.messageStatus);
} }
@ -806,20 +1012,6 @@ class AdVM extends BaseVM {
} }
} }
class SelectionModel {
String selectedOption;
int selectedId;
String errorValue;
String itemPrice;
SelectionModel({
this.selectedOption = "",
this.errorValue = "",
this.selectedId = 0,
this.itemPrice = "",
});
}
class VehicleDamageCard { class VehicleDamageCard {
List<File>? partImages; List<File>? partImages;
SelectionModel? partSelectedId; SelectionModel? partSelectedId;
@ -838,6 +1030,9 @@ class SpecialServiceCard {
String? serviceDateError; String? serviceDateError;
String? serviceTime; String? serviceTime;
String? serviceTimeError; String? serviceTimeError;
String? description;
String? duration;
String? address;
SpecialServiceCard({ SpecialServiceCard({
this.serviceSelectedId, this.serviceSelectedId,
@ -845,6 +1040,8 @@ class SpecialServiceCard {
this.serviceDateError = "", this.serviceDateError = "",
this.serviceTime = "", this.serviceTime = "",
this.serviceTimeError = "", this.serviceTimeError = "",
this.description = "",
this.duration = "",
this.address = "",
}); });
} }

@ -1,11 +1,14 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; 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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
@ -20,7 +23,17 @@ class AdDuration extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return BottomSheetServiceContent(); return const BottomSheetAdSpecialServiceContent();
});
}
void reservePriceInfoClicked(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(title: "Reserve Ad Price Info", description: GlobalConsts.reserveAdPriceInfo);
}); });
} }
@ -62,6 +75,41 @@ class AdDuration extends StatelessWidget {
adVM.updateSelectionDurationStartDate(formattedDate); adVM.updateSelectionDurationStartDate(formattedDate);
}, },
), ),
],
).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),
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)), ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)),
Column( Column(
@ -77,16 +125,13 @@ class AdDuration extends StatelessWidget {
icon: Container( icon: Container(
height: 24, height: 24,
width: 24, width: 24,
decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: Icon( child: const Icon(Icons.add, color: MyColors.white),
Icons.add,
color: MyColors.white,
),
), ),
), ),
20.height, 20.height,
ListView.builder( ListView.builder(
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: adVM.specialServiceCards.length, itemCount: adVM.specialServiceCards.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
@ -100,30 +145,82 @@ class AdDuration extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: specialServicesCard.serviceSelectedId!.selectedOption.toText(fontSize: 18, isBold: true), child: specialServicesCard.serviceSelectedId!.selectedOption.toText(fontSize: 16, isBold: true),
),
InkWell(
onTap: () => adVM.removeSpecialServiceCard(index),
child: Icon(Icons.delete_outline_rounded),
), ),
Align(
alignment: Alignment.topRight,
child: MyAssets.closeWithOrangeBg.buildSvg(
fit: BoxFit.fill,
height: 30,
width: 30,
),
).onPress(() => adVM.removeSpecialServiceCard(index))
], ],
), ),
Column( Builder(builder: (context) {
crossAxisAlignment: CrossAxisAlignment.start, return Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
"12 July, 2023 - 09:30AM".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), children: [
Row( if (specialServicesCard.serviceSelectedId!.selectedId != 1 && specialServicesCard.serviceSelectedId!.selectedId != 3) ...[
crossAxisAlignment: CrossAxisAlignment.end, // Row(
children: [ // crossAxisAlignment: CrossAxisAlignment.start,
(specialServicesCard.serviceSelectedId!.itemPrice).toText(fontSize: 20, isBold: true), // children: [
2.width, // "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"SAR".toText(color: MyColors.lightTextColor, fontSize: 14), // (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,
5.height, children: [
Divider(thickness: 1.5) 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,
children: [
(specialServicesCard.serviceSelectedId!.itemPrice).toText(fontSize: 20, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 14),
],
),
],
);
}),
3.height,
const Divider(thickness: 1.5)
], ],
), ),
10.height, 10.height,

@ -1,9 +1,9 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -57,7 +57,7 @@ class VehicleDetailsReview extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
flex: 5, flex: 7,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -75,6 +75,8 @@ class VehicleDetailsReview extends StatelessWidget {
16.height, 16.height,
SingleDetailWidget(text: adVM.vehicleVin, type: "Vehicle VIN"), SingleDetailWidget(text: adVM.vehicleVin, type: "Vehicle VIN"),
16.height, 16.height,
SingleDetailWidget(text: "${adVM.warrantyDuration} Years", type: "Warranty Available"),
16.height,
], ],
), ),
), ),
@ -97,17 +99,15 @@ class VehicleDetailsReview extends StatelessWidget {
16.height, 16.height,
SingleDetailWidget(text: adVM.vehicleTitle, type: "Vehicle Title"), SingleDetailWidget(text: adVM.vehicleTitle, type: "Vehicle Title"),
16.height, 16.height,
SingleDetailWidget(text: adVM.financeAvailableStatus ? "Yes" : "No", type: "Finance Available"),
16.height,
], ],
), ),
), ),
], ],
), ),
SingleDetailWidget(text: adVM.warrantyDuration, type: "Warranty Available"),
8.height,
SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"), SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"),
8.height, 8.height,
SingleDetailWidget(text: adVM.financeAvailableStatus ? "Yes" : "No", type: "Finance Available"),
8.height,
"Vehicle Pictures:".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), "Vehicle Pictures:".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
if (adVM.pickedVehicleImages.isNotEmpty) ...[ if (adVM.pickedVehicleImages.isNotEmpty) ...[
// 10.height, // 10.height,
@ -149,7 +149,7 @@ class DamagePartsReview extends StatelessWidget {
onAddImagePressed: () {}, onAddImagePressed: () {},
), ),
], ],
Divider(thickness: 2), if (index != adVM.vehicleDamageCards.length - 1) const Divider(thickness: 2),
], ],
)); ));
@ -188,23 +188,30 @@ class AdDurationReview extends StatelessWidget {
8.height, 8.height,
Row( Row(
children: [ children: [
Expanded(
flex: 7,
child: SingleDetailWidget(type: "Duration", text: adVM.vehicleAdDurationId.selectedOption),
),
Expanded( Expanded(
flex: 5, flex: 5,
child: Column( child: SingleDetailWidget(type: "Start Date", text: adVM.selectionDurationStartDate),
crossAxisAlignment: CrossAxisAlignment.start, ),
children: [ ],
SingleDetailWidget(type: "Duration", text: adVM.vehicleAdDurationId.selectedOption), ),
], 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( Expanded(
flex: 5, flex: 5,
child: Column( child: adVM.vehicleAdReservableId.selectedId == 1
crossAxisAlignment: CrossAxisAlignment.start, ? SingleDetailWidget(type: "Reserve Price", text: adVM.adReserveAmount)
children: [ : const SizedBox(),
SingleDetailWidget(type: "Start Date", text: adVM.selectionDurationStartDate),
],
),
), ),
], ],
), ),
@ -212,35 +219,66 @@ class AdDurationReview extends StatelessWidget {
15.height, 15.height,
"Special Services".toText(fontSize: 18, isBold: true), "Special Services".toText(fontSize: 18, isBold: true),
ListView.separated( ListView.separated(
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 2),
return Row( itemCount: adVM.specialServiceCards.length,
children: [ itemBuilder: (BuildContext context, int index) {
Expanded( return Column(
flex: 5, children: [
child: Column( 8.height,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ Row(
8.height, children: [
SingleDetailWidget(type: "Special Service", text: adVM.specialServiceCards[index].serviceSelectedId!.selectedOption), Expanded(
], flex: 7,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleDetailWidget(type: "Special Service", text: adVM.specialServiceCards[index].serviceSelectedId!.selectedOption),
],
),
), ),
), Expanded(
Expanded( flex: 5,
flex: 5, child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ SingleDetailWidget(type: "Amount", text: adVM.specialServiceCards[index].serviceSelectedId!.itemPrice),
SingleDetailWidget(type: "Amount", text: adVM.specialServiceCards[index].serviceSelectedId!.itemPrice), ],
], ),
), ),
), ],
),
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}"),
],
),
),
],
)
], ],
); ],
}, );
separatorBuilder: (BuildContext context, int index) => Divider(thickness: 2), },
itemCount: adVM.specialServiceCards.length) )
], ],
], ],
).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: 10));

@ -1,11 +1,12 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -28,10 +29,12 @@ class DamageParts extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return BottomSheetListContent(adVM: adVM); return const BottomSheetListContent();
}); });
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer( return Consumer(
@ -47,15 +50,12 @@ class DamageParts extends StatelessWidget {
icon: Container( icon: Container(
height: 24, height: 24,
width: 24, width: 24,
decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: Icon( child: const Icon(Icons.add, color: MyColors.white),
Icons.add,
color: MyColors.white,
),
)).horPaddingMain(), )).horPaddingMain(),
9.height, 9.height,
ListView.builder( ListView.builder(
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: adVM.vehicleDamageCards.length, itemCount: adVM.vehicleDamageCards.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
@ -67,7 +67,14 @@ class DamageParts extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
vehicleDamageCard.partSelectedId!.selectedOption.toText(fontSize: 18, isBold: true), vehicleDamageCard.partSelectedId!.selectedOption.toText(fontSize: 18, isBold: true),
InkWell(onTap: () => adVM.removeDamagePartCard(index), child: Icon(Icons.delete_outline_rounded)), Align(
alignment: Alignment.topRight,
child: MyAssets.closeWithOrangeBg.buildSvg(
fit: BoxFit.fill,
height: 30,
width: 30,
),
).onPress(() => adVM.removeDamagePartCard(index))
], ],
), ),
10.height, 10.height,

@ -1,12 +1,13 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; 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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
@ -200,6 +201,7 @@ class VehicleDetails extends StatelessWidget {
TxtField( TxtField(
value: adVM.vehicleDemandAmount, value: adVM.vehicleDemandAmount,
errorValue: adVM.demandAmountError, errorValue: adVM.demandAmountError,
keyboardType: TextInputType.number,
hint: "Demand Amount", hint: "Demand Amount",
onChanged: (v) => adVM.updateVehicleDemandAmount(v), onChanged: (v) => adVM.updateVehicleDemandAmount(v),
), ),
@ -207,6 +209,7 @@ class VehicleDetails extends StatelessWidget {
TxtField( TxtField(
value: adVM.vehicleVin, value: adVM.vehicleVin,
errorValue: adVM.vehicleVinError, errorValue: adVM.vehicleVinError,
keyboardType: TextInputType.number,
hint: "Vehicle VIN", hint: "Vehicle VIN",
onChanged: (v) => adVM.updateVehicleVin(v), onChanged: (v) => adVM.updateVehicleVin(v),
), ),
@ -221,6 +224,7 @@ class VehicleDetails extends StatelessWidget {
TxtField( TxtField(
value: adVM.warrantyDuration, value: adVM.warrantyDuration,
errorValue: adVM.warrantyError, errorValue: adVM.warrantyError,
keyboardType: TextInputType.number,
hint: "Warranty Available (No. of Years)", hint: "Warranty Available (No. of Years)",
onChanged: (v) => adVM.updateVehicleWarrantyDuration(v), onChanged: (v) => adVM.updateVehicleWarrantyDuration(v),
), ),

@ -1,10 +1,12 @@
import 'package:mc_common_app/views/advertisement/ads_images_slider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.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/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.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/ad_details_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.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/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
@ -18,7 +20,6 @@ class AdsDetailView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
backgroundColor: MyColors.backgroundColor,
title: "Ads", title: "Ads",
profileImageUrl: MyAssets.bnCar, profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false, isRemoveBackButton: false,
@ -109,7 +110,9 @@ class AdsDetailView extends StatelessWidget {
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Reserve Ad", title: "Reserve Ad",
onPressed: () {}, onPressed: () {
navigateWithName(context, AppRoutes.paymentMethodsView);
},
), ),
), ),
12.width, 12.width,

@ -11,21 +11,28 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class BuildAdsList extends StatelessWidget { class BuildAdsList extends StatelessWidget {
final List<AdDetailsModel> adsList; final List<AdDetailsModel> adsList;
final ScrollPhysics? scrollPhysics; final ScrollPhysics? scrollPhysics;
final bool isAdsFragment;
const BuildAdsList({Key? key, required this.adsList, this.scrollPhysics}) : super(key: key); const BuildAdsList({Key? key, required this.adsList, this.scrollPhysics, this.isAdsFragment = false}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (isAdsFragment && adsList.isEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Ads to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
],
);
}
return ListView.builder( return ListView.builder(
itemCount: adsList.length, itemCount: adsList.length,
shrinkWrap: true, shrinkWrap: true,
physics: scrollPhysics, physics: scrollPhysics,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: 15), padding: const EdgeInsets.only(bottom: 8),
child: AdCard( child: AdCard(adDetails: adsList[index]),
adDetails: adsList[index],
),
).onPress(() { ).onPress(() {
navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]); navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]);
}); });
@ -105,7 +112,7 @@ class AdCard extends StatelessWidget {
? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText( ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
) )
: SizedBox(), : const SizedBox(),
], ],
), ),
], ],
@ -120,7 +127,7 @@ class AdCard extends StatelessWidget {
children: [ children: [
(adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 16, isBold: true), (adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 16, isBold: true),
2.width, 2.width,
"SAR:".toText( "SAR".toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
], ],
@ -155,6 +162,6 @@ class AdCard extends StatelessWidget {
else else
const SizedBox(), const SizedBox(),
], ],
).toWhiteContainer(width: double.infinity, allPading: 12); ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21));
} }
} }

@ -1,10 +1,10 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/advertisment_models/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/theme/colors.dart';
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/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
@ -13,9 +13,7 @@ import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class BottomSheetListContent extends StatefulWidget { class BottomSheetListContent extends StatefulWidget {
final AdVM adVM; const BottomSheetListContent({Key? key}) : super(key: key);
const BottomSheetListContent({Key? key, required this.adVM}) : super(key: key);
@override @override
State<BottomSheetListContent> createState() => _BottomSheetListContentState(); State<BottomSheetListContent> createState() => _BottomSheetListContentState();
@ -26,6 +24,7 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AdVM adVM = context.watch<AdVM>();
return SizedBox( return SizedBox(
height: MediaQuery.of(context).size.height * 0.85, height: MediaQuery.of(context).size.height * 0.85,
child: Column( child: Column(
@ -45,18 +44,21 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
), ),
8.height, 8.height,
TxtField( TxtField(
value: "", value: adVM.damagePartSearchValue,
errorValue: "", errorValue: "",
hint: "Search Part", hint: "Search Part",
onChanged: (value) {}, onChanged: (value) {
adVM.onSearchChangedForDamagePart(value);
},
), ),
8.height, 8.height,
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
shrinkWrap: true, shrinkWrap: true,
itemCount: widget.adVM.vehicleDamageParts.length, itemCount: adVM.vehiclePartsSearchResults.isEmpty ? adVM.vehicleDamageParts.length : adVM.vehiclePartsSearchResults.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
VehiclePartModel vehiclePart = widget.adVM.vehicleDamageParts[index]; VehiclePartModel vehiclePart = adVM.vehiclePartsSearchResults.isEmpty ? adVM.vehicleDamageParts[index] : adVM.vehiclePartsSearchResults[index];
return Column( return Column(
children: [ children: [
// CheckboxListTile( // CheckboxListTile(
@ -75,7 +77,7 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
if (vehiclePart.isSelected!) { if (vehiclePart.isSelected!) {
return; return;
} }
widget.adVM.vehicleDamageParts[index].isChecked = !(widget.adVM.vehicleDamageParts[index].isChecked!); adVM.vehicleDamageParts[index].isChecked = !(adVM.vehicleDamageParts[index].isChecked!);
setState(() {}); setState(() {});
}, },
child: Row( child: Row(
@ -88,7 +90,13 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
child: Checkbox( child: Checkbox(
value: vehiclePart.isSelected! ? true : vehiclePart.isChecked, value: vehiclePart.isSelected! ? true : vehiclePart.isChecked,
activeColor: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.primaryColor, activeColor: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.primaryColor,
onChanged: (value) {}, onChanged: (value) {
if (vehiclePart.isSelected!) {
return;
}
adVM.vehicleDamageParts[index].isChecked = !(adVM.vehicleDamageParts[index].isChecked!);
setState(() {});
},
), ),
), ),
), ),
@ -112,9 +120,9 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
child: ShowFillButton( child: ShowFillButton(
title: "Add Damage Part", title: "Add Damage Part",
onPressed: () { onPressed: () {
for (var value in widget.adVM.vehicleDamageParts) { for (var value in adVM.vehicleDamageParts) {
if (value.isChecked! && !value.isSelected!) { if (value.isChecked! && !value.isSelected!) {
widget.adVM.addNewDamagePartCard( adVM.addNewDamagePartCard(
damageCard: VehicleDamageCard( damageCard: VehicleDamageCard(
partImageErrorValue: "", partImageErrorValue: "",
partImages: null, partImages: null,
@ -135,17 +143,36 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
} }
} }
class BottomSheetServiceContent extends StatelessWidget { class BottomSheetAdSpecialServiceContent extends StatelessWidget {
const BottomSheetServiceContent({Key? key}) : super(key: key); const BottomSheetAdSpecialServiceContent({Key? key}) : super(key: key);
bool isButtonTappable(AdVM adVM) { bool isButtonTappable(AdVM adVM) {
bool status = (adVM.vehicleAdsSpecialServicesId.selectedId != -1) && (adVM.vehicleAdsSpecialServicesId.selectedOption != ""); bool status = (adVM.vehicleAdsSpecialServicesId.selectedId != -1) && (adVM.vehicleAdsSpecialServicesId.selectedOption != "" && adVM.slotSelectedIndex != null);
if (status) { if (status) {
return true; return true;
} }
return false; return false;
} }
Widget descriptionCard({required String description}) {
return Container(
height: 100,
decoration: BoxDecoration(color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: description.toText(
fontSize: 15,
isBold: true,
color: MyColors.lightTextColor,
),
),
],
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer( return Consumer(
@ -167,60 +194,101 @@ class BottomSheetServiceContent extends StatelessWidget {
children: [ children: [
"Add Special Service".toText(fontSize: 24, isBold: true), "Add Special Service".toText(fontSize: 24, isBold: true),
8.height, 8.height,
Builder(builder: (context) { Builder(
List<DropValue> vehicleAdsSpecialServices = []; builder: (context) {
for (var element in adVM.vehicleAdsSpecialServices) { List<DropValue> vehicleAdsSpecialServices = [];
if (!element.isSelected!) { for (var element in adVM.vehicleAdsSpecialServices) {
vehicleAdsSpecialServices.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", element.price == null ? "" : element.price!.toInt().toString())); if (!element.isSelected!) {
vehicleAdsSpecialServices.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", element.price == null ? "" : element.price!.toInt().toString()));
}
} }
} return DropdownField(
return DropdownField( (DropValue value) => adVM.updateVehicleAdsSpecialServicesId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
(DropValue value) => adVM.updateVehicleAdsSpecialServicesId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)), list: vehicleAdsSpecialServices,
list: vehicleAdsSpecialServices, hint: "Select Service",
hint: "Select Service", dropdownValue:
dropdownValue: adVM.vehicleAdsSpecialServicesId.selectedId != -1 ? DropValue(adVM.vehicleAdsSpecialServicesId.selectedId, adVM.vehicleAdsSpecialServicesId.selectedOption, "") : null,
adVM.vehicleAdsSpecialServicesId.selectedId != -1 ? DropValue(adVM.vehicleAdsSpecialServicesId.selectedId, adVM.vehicleAdsSpecialServicesId.selectedOption, "") : null, );
);
}),
8.height,
TxtField(
errorValue: adVM.adStartDateError,
hint: 'Date',
value: adVM.adSpecialServiceDate,
isNeedClickAll: true,
postfixData: Icons.calendar_month_rounded,
postFixDataColor: MyColors.lightTextColor,
onTap: () async {
final formattedDate = await Utils.pickDateFromDatePicker(context);
adVM.updateAdSpecialServiceDate(formattedDate);
}, },
), ),
22.height,
"Available slots".toText(fontSize: 15, isBold: true),
8.height,
const BuildTimeSlots(),
22.height,
"Service Amount".toText(fontSize: 16, isBold: true, color: MyColors.lightTextColor),
if (adVM.vehicleAdsSpecialServicesId.selectedId != -1) ...[ if (adVM.vehicleAdsSpecialServicesId.selectedId != -1) ...[
adVM.vehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true), if (adVM.isFetchingLists) ...[
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), Center(child: const CircularProgressIndicator().paddingAll(20)),
], ] else ...[
8.height,
if ((adVM.vehicleAdsSpecialServicesId.selectedId == 1 && adVM.ssPhotoScheduleModel != null)) ...[
Builder(
builder: (context) {
List<DropValue> vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdPhotoService();
// 5.height, return DropdownField(
// Divider(thickness: 1.2), (DropValue value) => adVM.updateVehicleVehicleAdsPhotoServiceDate(SelectionModel(
// 5.height, selectedId: value.id,
// DottedRectContainer( selectedOption: value.value,
// onTap: () => null, )),
// text: "Add Service", list: vehicleAdsSpecialServiceDates,
// icon: MyAssets.attachmentIcon.buildSvg(), 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,
],
if (adVM.vehicleAdsSpecialServicesId.selectedId != 3 && adVM.vehicleAdsSpecialServicesId.selectedId != 1) ...[
descriptionCard(
description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "",
),
],
if (adVM.adSSTimeSlots.isNotEmpty) ...[
"Available slots".toText(fontSize: 15, isBold: true),
8.height,
BuildTimeSlots(
timeSlots: adVM.adSSTimeSlots,
onPressed: (index) => adVM.updateIsSelectedInSlots(index),
),
],
22.height,
"Service Amount".toText(fontSize: 16, isBold: true, color: MyColors.lightTextColor),
adVM.vehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true),
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
],
], ],
), ),
), ),
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: ShowFillButton( child: ShowFillButton(
backgroundColor: !isButtonTappable(adVM) ? MyColors.lightTextColor : MyColors.primaryColor, backgroundColor: !isButtonTappable(adVM) ? MyColors.lightTextColor.withOpacity(0.6) : MyColors.primaryColor,
title: "Add Service", title: "Add Service",
onPressed: () { onPressed: () {
if (!isButtonTappable(adVM)) { if (!isButtonTappable(adVM)) {
@ -230,26 +298,28 @@ class BottomSheetServiceContent extends StatelessWidget {
adVM.addNewSpecialServiceCard( adVM.addNewSpecialServiceCard(
specialServiceCard: SpecialServiceCard( specialServiceCard: SpecialServiceCard(
serviceDate: "", serviceDate: adVM.vehicleAdsSpecialServicesId.selectedId == 1
? adVM.vehicleAdsPhotoServiceDate.selectedOption
: adVM.vehicleAdsSpecialServicesId.selectedId == 3
? adVM.vehicleAdsCarCheckServicesDate.selectedOption
: "",
serviceDateError: "", serviceDateError: "",
serviceSelectedId: adVM.vehicleAdsSpecialServicesId, serviceSelectedId: adVM.vehicleAdsSpecialServicesId,
serviceTimeError: "", serviceTimeError: "",
serviceTime: "", 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,
), ),
); );
// for (var value in widget.adVM.vehicleDamageParts) {
// if (value.isChecked! && !value.isSelected!) {
// widget.adVM.addNewDamagePartCard(
// damageCard: VehicleDamageCard(
// partImageErrorValue: "",
// partImages: null,
// partSelectedId: SelectionModel(selectedOption: value.partName!, selectedId: value.id!, errorValue: ""),
// ),
// );
// value.isChecked = false;
// value.isSelected = true;
// }
// }
}, },
).paddingOnly(bottom: 10), ).paddingOnly(bottom: 10),
), ),

@ -1,10 +1,10 @@
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.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';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -40,6 +40,11 @@ class CreateAdProgressSteps extends StatelessWidget {
); );
} }
bool isStepCompleted({required AdCreationStepsEnum currentStep}) {
return true;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AdVM adVM = context.watch<AdVM>(); AdVM adVM = context.watch<AdVM>();

@ -14,13 +14,13 @@ class CustomAddButton extends StatelessWidget {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
height: 86, height: 110,
decoration: BoxDecoration(border: Border.all(width: 2, color: MyColors.primaryColor)), decoration: BoxDecoration(color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
icon, icon,
SizedBox(width: 10), const SizedBox(width: 10),
text.toText( text.toText(
fontSize: 15, fontSize: 15,
isBold: true, isBold: true,

@ -26,7 +26,7 @@ class PickedImagesContainer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GridView.count( return GridView.count(
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
crossAxisCount: 4, crossAxisCount: 4,
crossAxisSpacing: 4.0, crossAxisSpacing: 4.0,
@ -36,17 +36,14 @@ class PickedImagesContainer extends StatelessWidget {
(index) { (index) {
if (index == pickedImages.length && !isReview) { if (index == pickedImages.length && !isReview) {
return Container( return Container(
margin: EdgeInsets.all(8), decoration: BoxDecoration( color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)),
color: MyColors.lightTextColor.withOpacity(0.4), margin: const EdgeInsets.all(8),
alignment: Alignment.center, alignment: Alignment.center,
child: Container( child: Container(
height: 24, height: 24,
width: 24, width: 24,
decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: Icon( child: const Icon(Icons.add, color: MyColors.white),
Icons.add,
color: MyColors.white,
),
), ),
).onPress(onAddImagePressed); ).onPress(onAddImagePressed);
} }
@ -62,17 +59,17 @@ class PickedImagesContainer extends StatelessWidget {
}, },
), ),
); );
return Wrap( // return Wrap(
children: pickedImages // children: pickedImages
.map((file) => BuildImageContainer( // .map((file) => BuildImageContainer(
file: file, // file: file,
onCrossPressedPrimary: onCrossPressedPrimary, // onCrossPressedPrimary: onCrossPressedPrimary,
onCrossPressedSecondary: onCrossPressedSecondary, // onCrossPressedSecondary: onCrossPressedSecondary,
index: index, // index: index,
isReview: isReview, // isReview: isReview,
)) // ))
.toList(), // .toList(),
); // );
} }
} }
@ -122,7 +119,7 @@ class BuildImageContainer extends StatelessWidget {
} }
onCrossPressedPrimary!(file.path); onCrossPressedPrimary!(file.path);
}) })
: SizedBox() : const SizedBox()
], ],
)), )),
], ],

@ -1,20 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:mc_common_app/models/user/country.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/user/country.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/tab/login_email_tab.dart'; import 'package:mc_common_app/widgets/tab/login_email_tab.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class LoginWithPassword extends StatefulWidget { class LoginWithPassword extends StatefulWidget {
@ -53,7 +53,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( isRemoveBackButton: true, title: ""), appBar: CustomAppBar(isRemoveBackButton: true, title: ""),
body: Container( body: Container(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
@ -62,9 +62,12 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
child: Column( child: Column(
children: [ children: [
12.height, 12.height,
LocaleKeys.login.tr().toText(fontSize: 20, letterSpacing: -1.44,), LocaleKeys.login.tr().toText(
fontSize: 20,
letterSpacing: -1.44,
),
// 20.height, // 20.height,
// (type == ClassType.NUMBER ? LocaleKeys.enterPhoneNumber.tr() : LocaleKeys.enterEmail.tr()).toText14( // (type == ClassType.NUMBER ? LocaleKeys.\enterPhoneNumber.tr() : LocaleKeys.enterEmail.tr()).toText14(
// color: MyColors.lightTextColor, // color: MyColors.lightTextColor,
// textAlign: TextAlign.center, // textAlign: TextAlign.center,
// ), // ),
@ -82,6 +85,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
if (type == ClassType.NUMBER) getCountry(context), if (type == ClassType.NUMBER) getCountry(context),
10.height, 10.height,
TxtField( TxtField(
keyboardType: type == ClassType.NUMBER ? TextInputType.phone : null,
hint: type == ClassType.NUMBER ? LocaleKeys.enterPhoneNumber.tr() : LocaleKeys.enterEmail.tr(), hint: type == ClassType.NUMBER ? LocaleKeys.enterPhoneNumber.tr() : LocaleKeys.enterEmail.tr(),
value: phoneNum, value: phoneNum,
isSidePaddingZero: true, isSidePaddingZero: true,
@ -106,7 +110,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
LocaleKeys.forgetPasswordQ.tr().toText( LocaleKeys.forgetPasswordQ.tr().toText(
color: MyColors.textColor, color: MyColors.textColor,
fontSize: 14, fontSize: 14,
height: 23 / 24, height: 23 / 24,
letterSpacing: -0.48, letterSpacing: -0.48,
), ),
ShowFillButton( ShowFillButton(

@ -133,6 +133,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
Navigator.pop(context); Navigator.pop(context);
}, },
).toContainer( ).toContainer(
paddingAll: 0, paddingAll: 0,
borderRadius: 100, borderRadius: 100,
borderColor: MyColors.lightGreyEFColor, borderColor: MyColors.lightGreyEFColor,

@ -5,7 +5,7 @@ import 'package:mc_common_app/theme/colors.dart';
class FiltersList extends StatelessWidget { class FiltersList extends StatelessWidget {
final List<FilterListModel> filterList; final List<FilterListModel> filterList;
final Function(int) onFilterTapped; final Function(int, int) onFilterTapped;
final bool needLeftPadding; final bool needLeftPadding;
const FiltersList({Key? key, required this.filterList, this.needLeftPadding = true, required this.onFilterTapped}) : super(key: key); const FiltersList({Key? key, required this.filterList, this.needLeftPadding = true, required this.onFilterTapped}) : super(key: key);
@ -22,12 +22,12 @@ class FiltersList extends StatelessWidget {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InkWell( return InkWell(
onTap: () { onTap: () {
onFilterTapped(index); onFilterTapped(index, filterList[index].id);
}, },
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
margin: const EdgeInsets.symmetric(horizontal: 8), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: filterList[index].isSelected ? MyColors.darkIconColor : null, color: filterList[index].isSelected ? MyColors.darkIconColor : null,
border: Border.all( border: Border.all(

@ -1,143 +0,0 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomerAppointmentSliderWidget extends StatelessWidget {
const CustomerAppointmentSliderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CarouselSlider.builder(
options: CarouselOptions(
height: 140,
viewportFraction: 1.0,
enlargeCenterPage: false,
enableInfiniteScroll: false,
//
// onPageChanged: (index) {
// setState(() {
// _current = index;
// });
// },
),
itemCount: 10,
itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer(
isForHome: true,
onTapped: () {},
),
);
}
}
class BuildAppointmentContainerForCustomer extends StatelessWidget {
final bool? isForHome;
final Function() onTapped;
const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false, required this.onTapped}) : super(key: key);
Widget showServices(String title, String icon) {
return Row(
children: [
SvgPicture.asset(icon),
8.width,
title.toText(
fontSize: 14,
isBold: true,
),
],
);
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(
bottom: 10,
left: 21,
right: 21,
),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
isForHome != null && isForHome!
? Image.asset(
MyAssets.bnCar,
width: 56,
height: 56,
fit: BoxFit.fill,
).toCircle(borderRadius: 100)
: Image.asset(
MyAssets.bnCar,
width: 80,
height: 85,
fit: BoxFit.cover,
),
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Al Aziz Service Station".toText(color: MyColors.black, isBold: true, fontSize: 16),
Row(
children: [
MyAssets.miniClock.buildSvg(height: 12),
2.width,
"08:00 to 08:30 25 July, 2023".toText(
color: MyColors.lightTextColor,
fontSize: 12,
),
],
),
9.height,
isForHome != null && isForHome!
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Appointment Details".toText(
color: MyColors.primaryColor,
isUnderLine: true,
isBold: true,
fontSize: 14,
),
const Icon(Icons.arrow_forward),
],
)
: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Column(
children: [
showServices("Maintenance", MyAssets.maintenanceIcon),
2.height,
showServices(
"Accessories and Modification",
MyAssets.modificationsIcon,
),
],
),
),
const Icon(
Icons.arrow_forward,
),
],
),
],
),
),
],
),
],
).onPress(onTapped).toWhiteContainer(width: double.infinity, allPading: 12),
);
}
}

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class InfoBottomSheet extends StatelessWidget {
final String title;
final String 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,
child: Column(
children: [
Container(
margin: const EdgeInsets.all(8),
height: 8,
width: 60,
decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
),
12.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
title.toText(fontSize: 24, isBold: true),
],
),
8.height,
Flexible(
child: description.toText(
textAlign: TextAlign.justify,
fontSize: 16,
color: MyColors.lightTextColor,
isBold: true,
)),
],
).horPaddingMain());
}
}

@ -89,7 +89,7 @@ class ProviderDetailsCard extends StatelessWidget {
MyAssets.maintenanceIcon.buildSvg(), MyAssets.maintenanceIcon.buildSvg(),
8.width, 8.width,
LocaleKeys.maintenance.tr().toText( LocaleKeys.maintenance.tr().toText(
fontSize: 14, fontSize: 12,
isBold: true, isBold: true,
), ),
], ],
@ -99,7 +99,7 @@ class ProviderDetailsCard extends StatelessWidget {
MyAssets.modificationsIcon.buildSvg(), MyAssets.modificationsIcon.buildSvg(),
8.width, 8.width,
LocaleKeys.accessories_modifications.tr().toText( LocaleKeys.accessories_modifications.tr().toText(
fontSize: 14, fontSize: 12,
isBold: true, isBold: true,
), ),
], ],

@ -1,8 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
class BuildTimeSlots extends StatelessWidget { class BuildTimeSlots extends StatelessWidget {
const BuildTimeSlots({Key? key}) : super(key: key); final List<TimeSlotModel> timeSlots;
final Function(int) onPressed;
const BuildTimeSlots({Key? key, required this.timeSlots, required this.onPressed}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -10,26 +15,28 @@ class BuildTimeSlots extends StatelessWidget {
height: 37, height: 37,
width: double.infinity, width: double.infinity,
child: ListView.builder( child: ListView.builder(
itemCount: 20, itemCount: timeSlots.length,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InkWell( return InkWell(
onTap: () {}, onTap: () {
onPressed(index);
},
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
margin: const EdgeInsets.only(right: 8), margin: const EdgeInsets.only(right: 8),
width: 50, // width: 50,
padding: const EdgeInsets.symmetric(horizontal: 9),
decoration: BoxDecoration( decoration: BoxDecoration(
color: index < 1 ? MyColors.darkIconColor : null, color: timeSlots[index].isSelected ? MyColors.darkIconColor : null,
border: Border.all( border: Border.all(
color: index < 1 ? MyColors.darkIconColor : MyColors.primaryColor, color: timeSlots[index].isSelected ? MyColors.darkIconColor : MyColors.primaryColor,
width: 2,
), ),
), ),
child: "09:00".toText( child: timeSlots[index].slot.toText(
fontSize: 12, fontSize: 12,
color: index < 1 ? MyColors.white : null, color: timeSlots[index].isSelected ? MyColors.white : null,
), ),
), ),
); );
}), }),

@ -13,6 +13,11 @@ class DropValue {
DropValue(this.id, this.value, this.subValue, {this.isEnabled = true}); DropValue(this.id, this.value, this.subValue, {this.isEnabled = true});
bool operator ==(o) => o is DropValue && o.value == value && o.id == id; bool operator ==(o) => o is DropValue && o.value == value && o.id == id;
@override
String toString() {
return 'DropValue{id: $id, value: $value, subValue: $subValue, isEnabled: $isEnabled}';
}
} }
class DropdownField extends StatefulWidget { class DropdownField extends StatefulWidget {

@ -75,12 +75,12 @@ extension ContainerExt on Widget {
boxShadow: !isShadowEnabled boxShadow: !isShadowEnabled
? null ? null
: [ : [
BoxShadow( BoxShadow(
color: const Color(0xff000000).withOpacity(.05), color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26, blurRadius: 26,
offset: const Offset(0, -3), offset: const Offset(0, -3),
), ),
], ],
), ),
padding: padding ?? EdgeInsets.all(paddingAll), padding: padding ?? EdgeInsets.all(paddingAll),
margin: margin ?? EdgeInsets.all(marginAll), margin: margin ?? EdgeInsets.all(marginAll),
@ -355,104 +355,4 @@ extension WidgetExtensions on Widget {
Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);
} }
extension FormatDate on String {
/// get month by
/// [month] convert month number in to month name
/// get month by
/// [month] convert month number in to month name in Arabic
static String getMonthArabic(int month) {
switch (month) {
case 1:
return "يناير";
case 2:
return " فبراير";
case 3:
return "مارس";
case 4:
return "أبريل";
case 5:
return "مايو";
case 6:
return "يونيو";
case 7:
return "يوليو";
case 8:
return "أغسطس";
case 9:
return "سبتمبر";
case 10:
return " اكتوبر";
case 11:
return " نوفمبر";
case 12:
return "ديسمبر";
default:
return "";
}
}
static String getMonth(int month) {
switch (month) {
case 1:
return "January";
case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
default:
return "";
}
}
String getTimeAgo() {
String date = split("T")[0];
String time = split("T")[1];
var dates = date.split("-");
return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a', "en_US").format(DateFormat('hh:mm:ss', "en_US").parse(time))}";
}
}
extension DateTimeConversions on DateTime {
String getTimeAgo({bool numericDates = true}) {
final date2 = DateTime.now();
final difference = date2.difference(this);
if ((difference.inDays / 7).floor() >= 1) {
return (numericDates) ? '1 week ago' : 'Last week';
} else if (difference.inDays >= 2) {
return '${difference.inDays} days ago';
} else if (difference.inDays >= 1) {
return (numericDates) ? '1 day ago' : 'Yesterday';
} else if (difference.inHours >= 2) {
return '${difference.inHours} hours ago';
} else if (difference.inHours >= 1) {
return (numericDates) ? '1 hour ago' : 'An hour ago';
} else if (difference.inMinutes >= 2) {
return '${difference.inMinutes} minutes ago';
} else if (difference.inMinutes >= 1) {
return (numericDates) ? '1 minute ago' : 'A minute ago';
} else if (difference.inSeconds >= 3) {
return '${difference.inSeconds} seconds ago';
} else {
return 'Just now';
}
}
}

@ -24,8 +24,11 @@ class TxtField extends StatelessWidget {
int? maxLines; int? maxLines;
bool isSidePaddingZero; bool isSidePaddingZero;
bool isNeedBorder; bool isNeedBorder;
bool isSearchBar;
bool? isPasswordEnabled; bool? isPasswordEnabled;
Function(String)? onChanged; Function(String)? onChanged;
Function(String)? onSubmitted;
Function()? onPostFixPressed;
TextInputType? keyboardType; TextInputType? keyboardType;
bool isBackgroundEnabled = false; bool isBackgroundEnabled = false;
Widget? postfixWidget; Widget? postfixWidget;
@ -49,10 +52,13 @@ class TxtField extends StatelessWidget {
this.isSidePaddingZero = false, this.isSidePaddingZero = false,
this.isNeedBorder = true, this.isNeedBorder = true,
this.onChanged, this.onChanged,
this.onSubmitted,
this.isPasswordEnabled, this.isPasswordEnabled,
this.isSearchBar = false,
this.keyboardType, this.keyboardType,
this.isBackgroundEnabled = false, this.isBackgroundEnabled = false,
this.postfixWidget, this.postfixWidget,
this.onPostFixPressed,
}) : super(key: key); }) : super(key: key);
@override @override
@ -78,6 +84,7 @@ class TxtField extends StatelessWidget {
borderRadius: const BorderRadius.all(Radius.circular(0)), borderRadius: const BorderRadius.all(Radius.circular(0)),
), ),
child: TextField( child: TextField(
textInputAction: isSearchBar ? TextInputAction.search : null,
keyboardType: keyboardType, keyboardType: keyboardType,
autofocus: false, autofocus: false,
controller: controller, controller: controller,
@ -86,6 +93,7 @@ class TxtField extends StatelessWidget {
onTap: () {}, onTap: () {},
obscureText: isPasswordEnabled ?? false, obscureText: isPasswordEnabled ?? false,
onChanged: onChanged, onChanged: onChanged,
onSubmitted: onSubmitted,
decoration: InputDecoration( decoration: InputDecoration(
labelText: lable, labelText: lable,
alignLabelWithHint: true, alignLabelWithHint: true,
@ -105,14 +113,14 @@ class TxtField extends StatelessWidget {
borderRadius: BorderRadius.circular(0.0), borderRadius: BorderRadius.circular(0.0),
), ),
suffixIcon: postfixData != null suffixIcon: postfixData != null
? Icon( ? InkWell(
postfixData, onTap: onPostFixPressed,
color: postFixDataColor, child: Icon(postfixData, color: postFixDataColor),
) )
: postfixWidget ?? null, : postfixWidget ?? null,
prefixIcon: prefixData != null ? const Icon(Icons.search, color: borderColor) : null, prefixIcon: prefixData != null ? const Icon(Icons.search, color: borderColor) : null,
labelStyle: TextStyle(color: borderColor, fontSize: 13.sp), labelStyle: TextStyle(color: borderColor, fontSize: 13.sp),
hintStyle: TextStyle(color: borderColor, fontSize: 9.sp), hintStyle: TextStyle(color: borderColor, fontSize: 10.sp),
hintText: hint ?? "", hintText: hint ?? "",
contentPadding: prefixData == null contentPadding: prefixData == null
? EdgeInsets.only( ? EdgeInsets.only(

@ -206,6 +206,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.0" version: "3.3.0"
flutter_inappwebview:
dependency: "direct main"
description:
name: flutter_inappwebview
sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf
url: "https://pub.dev"
source: hosted
version: "5.7.2+3"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:

@ -35,6 +35,7 @@ dependencies:
badges: ^3.0.2 badges: ^3.0.2
carousel_slider: ^4.2.1 carousel_slider: ^4.2.1
dropdown_button2: ^2.0.0 dropdown_button2: ^2.0.0
flutter_inappwebview: ^5.7.2+3
# google # google
google_maps_flutter: ^2.1.1 google_maps_flutter: ^2.1.1
@ -56,6 +57,7 @@ flutter:
- assets/ - assets/
- assets/langs/ - assets/langs/
- assets/icons/ - assets/icons/
- assets/icons/payments/
- assets/images/ - assets/images/
- assets/fonts/Poppins-Medium.ttf - assets/fonts/Poppins-Medium.ttf

Loading…
Cancel
Save