Added AdUpdateFlow

localization_aamir
Faiz Hashmi 2 years ago
parent 08cb3f4a85
commit 0c5a45f5af

@ -74,10 +74,7 @@ class ApiClientImp implements ApiClient {
if (headers != null && headers.isNotEmpty) { if (headers != null && headers.isNotEmpty) {
headers0.addAll(headers); headers0.addAll(headers);
} }
if (!kReleaseMode) {
logger.i(url);
logger.i(jsonEncode(jsonObject.toString()));
}
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) {
@ -129,14 +126,16 @@ class ApiClientImp implements ApiClient {
var queryString = Uri(queryParameters: queryParameters).query; var queryString = Uri(queryParameters: queryParameters).query;
url = '$url?$queryString'; url = '$url?$queryString';
} }
Response response; Response response;
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) {
logger.d("------URL------");
logger.i(url); logger.i(url);
logger.i(requestBody); logger.d("------Payload------");
logger.i(jsonDecode(requestBody));
logger.d("------Response------");
logger.i(jsonDecode(response.body)); logger.i(jsonDecode(response.body));
} }
if (response.statusCode >= 200 && response.statusCode < 500) { if (response.statusCode >= 200 && response.statusCode < 500) {

@ -104,6 +104,7 @@ class ApiConsts {
static String vehicleAdsDurationGet = "${baseUrlServices}api/Advertisement/AdsDuration_Get"; static String vehicleAdsDurationGet = "${baseUrlServices}api/Advertisement/AdsDuration_Get";
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 vehicleAdsSingleStepUpdate = "${baseUrlServices}api/Advertisement/AdsSingleStep_Update";
static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get"; static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get";
static String myAdsReserveGet = "${baseUrlServices}api/Advertisement/AdsReserve_Get"; static String myAdsReserveGet = "${baseUrlServices}api/Advertisement/AdsReserve_Get";
static String reserveAdsBankDetailsGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get"; static String reserveAdsBankDetailsGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get";

@ -5,18 +5,19 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
extension EmailValidator on String { extension EmailValidator on String {
Widget toText({Color? color, Widget toText(
bool isBold = false, {Color? color,
double? fontSize, bool isBold = false,
bool isUnderLine = false, double? fontSize,
bool isItalic = false, bool isUnderLine = false,
TextDecoration? textDecoration, bool isItalic = false,
double letterSpacing = -0.4, TextDecoration? textDecoration,
TextAlign? textAlign, double letterSpacing = -0.4,
FontWeight? fontWeight, TextAlign? textAlign,
double? height, FontWeight? fontWeight,
Color? decorationColor, double? height,
int? maxLines}) => Color? decorationColor,
int? maxLines}) =>
AutoSizeText( AutoSizeText(
this, this,
textAlign: textAlign, textAlign: textAlign,
@ -24,10 +25,8 @@ extension EmailValidator on String {
style: TextStyle( style: TextStyle(
fontStyle: isItalic ? FontStyle.italic : null, fontStyle: isItalic ? FontStyle.italic : null,
height: height, height: height,
decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none,
TextDecoration.none, decorationColor: decorationColor,
decorationColor
: decorationColor,
fontSize: fontSize ?? 10, fontSize: fontSize ?? 10,
fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.w600, fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.w600,
color: color ?? MyColors.darkTextColor, color: color ?? MyColors.darkTextColor,
@ -36,9 +35,7 @@ extension EmailValidator on String {
); );
bool isValidEmail() { bool isValidEmail() {
return RegExp( return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
.hasMatch(this);
} }
bool isNum() { bool isNum() {
@ -146,9 +143,7 @@ extension FormatDate on String {
String date = split("T")[0]; String date = split("T")[0];
String time = split("T")[1]; String time = split("T")[1];
var dates = date.split("-"); var dates = date.split("-");
return "${dates[2]} ${getMonth( 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))}";
int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a', "en_US")
.format(DateFormat('hh:mm:ss', "en_US").parse(time))}";
} }
String toFormattedDateWithoutTime() { String toFormattedDateWithoutTime() {
@ -809,5 +804,3 @@ extension SubscriptionTypeEnumToString on SubscriptionTypeEnum {
} }
} }
} }

@ -260,13 +260,15 @@ class Category {
class Condition { class Condition {
int? id; int? id;
int? vehicleBrandID;
String? label; String? label;
String? labelN; String? labelN;
Condition({this.id, this.label, this.labelN}); Condition({this.id, this.label, this.labelN, this.vehicleBrandID});
Condition.fromJson(Map<String, dynamic> json) { Condition.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
vehicleBrandID = json['vehicleBrandID'];
label = json['label']; label = json['label'];
labelN = json['labelN']; labelN = json['labelN'];
} }

@ -33,7 +33,6 @@ class VehicleDetailsModel {
}); });
VehicleDetailsModel.fromJson(Map<String, dynamic> json) { VehicleDetailsModel.fromJson(Map<String, dynamic> json) {
log("jsonJee: $json");
vehicleBrands = List.generate((json['vehiclebrands']['data']).length, (index) => VehicleBrandsModel.fromJson(json['vehiclebrands']['data'][index])); vehicleBrands = List.generate((json['vehiclebrands']['data']).length, (index) => VehicleBrandsModel.fromJson(json['vehiclebrands']['data'][index]));
vehicleCategories = List.generate((json['vehiclecategories']['data']).length, (index) => VehicleCategoryModel.fromJson(json['vehiclecategories']['data'][index])); vehicleCategories = List.generate((json['vehiclecategories']['data']).length, (index) => VehicleCategoryModel.fromJson(json['vehiclecategories']['data'][index]));
vehicleColors = List.generate((json['vehiclecolors']['data']).length, (index) => VehicleColorModel.fromJson(json['vehiclecolors']['data'][index])); vehicleColors = List.generate((json['vehiclecolors']['data']).length, (index) => VehicleColorModel.fromJson(json['vehiclecolors']['data'][index]));
@ -69,7 +68,6 @@ class VehicleTypeModel {
this.isActive, this.isActive,
this.vehicleTypeEnum = VehicleType.car, this.vehicleTypeEnum = VehicleType.car,
this.isSelected, this.isSelected,
}); });
VehicleTypeModel.fromJson(Map<String, dynamic> json) { VehicleTypeModel.fromJson(Map<String, dynamic> json) {

@ -1,3 +1,5 @@
import 'dart:io';
class GenericRespModel { class GenericRespModel {
GenericRespModel({ GenericRespModel({
this.data, this.data,
@ -219,16 +221,18 @@ class VehiclePosting {
class VehiclePostingImages { class VehiclePostingImages {
int? id; int? id;
File? file;
String? imageName; String? imageName;
String? imageUrl; String? imageUrl;
String? imageStr; String? imageStr;
int? vehiclePostingID; int? vehiclePostingID;
String? vehiclePosting; String? vehiclePosting;
VehiclePostingImages({this.id, this.imageName, this.imageUrl, this.imageStr, this.vehiclePostingID, this.vehiclePosting}); VehiclePostingImages({this.id, this.file, this.imageName, this.imageUrl, this.imageStr, this.vehiclePostingID, this.vehiclePosting});
VehiclePostingImages.fromJson(Map<String, dynamic> json) { VehiclePostingImages.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
file = null;
imageName = json['imageName']; imageName = json['imageName'];
imageUrl = json['imageUrl']; imageUrl = json['imageUrl'];
imageStr = json['imageStr']; imageStr = json['imageStr'];
@ -249,7 +253,7 @@ class VehiclePostingImages {
@override @override
String toString() { String toString() {
return 'VehiclePostingImages{id: $id, imageName: $imageName, imageUrl: $imageUrl, imageStr: $imageStr, vehiclePostingID: $vehiclePostingID, vehiclePosting: $vehiclePosting}'; return 'VehiclePostingImages{id: $id, imageName: $imageName, imageUrl: $imageUrl, imageStr: "", vehiclePostingID: $vehiclePostingID, vehiclePosting: $vehiclePosting}';
} }
} }
@ -282,17 +286,21 @@ class RequestPostingImages {
class VehiclePostingDamageParts { class VehiclePostingDamageParts {
int? id; int? id;
File? file;
String? comment; String? comment;
String? imageUrl;
String? vehicleImageBase64; String? vehicleImageBase64;
int? vehicleDamagePartID; int? vehicleDamagePartID;
int? vehiclePostingID; int? vehiclePostingID;
bool? isActive; bool? isActive;
VehiclePostingDamageParts({this.id, this.comment, this.vehicleImageBase64, this.vehicleDamagePartID, this.vehiclePostingID, this.isActive}); VehiclePostingDamageParts({this.id, this.file, this.comment, this.imageUrl, this.vehicleImageBase64, this.vehicleDamagePartID, this.vehiclePostingID, this.isActive});
VehiclePostingDamageParts.fromJson(Map<String, dynamic> json) { VehiclePostingDamageParts.fromJson(Map<String, dynamic> json) {
id = json['id']; id = json['id'];
file = null;
comment = json['comment']; comment = json['comment'];
imageUrl = json['imageUrl'];
vehicleImageBase64 = json['vehicleImageBase64']; vehicleImageBase64 = json['vehicleImageBase64'];
vehicleDamagePartID = json['vehicleDamagePartID']; vehicleDamagePartID = json['vehicleDamagePartID'];
vehiclePostingID = json['vehiclePostingID']; vehiclePostingID = json['vehiclePostingID'];
@ -303,6 +311,7 @@ class VehiclePostingDamageParts {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id; data['id'] = id;
data['comment'] = comment; data['comment'] = comment;
data['imageUrl'] = imageUrl;
data['vehicleImageBase64'] = vehicleImageBase64; data['vehicleImageBase64'] = vehicleImageBase64;
data['vehicleDamagePartID'] = vehicleDamagePartID; data['vehicleDamagePartID'] = vehicleDamagePartID;
data['vehiclePostingID'] = vehiclePostingID; data['vehiclePostingID'] = vehiclePostingID;
@ -310,8 +319,8 @@ class VehiclePostingDamageParts {
return data; return data;
} }
// @override @override
// String toString() { String toString() {
// return 'VehiclePostingDamageParts{id: $id, comment: $comment, vehicleImageBase64: $vehicleImageBase64, vehicleDamagePartID: $vehicleDamagePartID, vehiclePostingID: $vehiclePostingID, isActive: $isActive}'; return 'VehiclePostingDamageParts{id: $id, comment: $comment, vehicleImageBase64: $vehicleImageBase64, vehicleDamagePartID: $vehicleDamagePartID, vehiclePostingID: $vehiclePostingID, isActive: $isActive}';
// } }
} }

@ -22,7 +22,7 @@ abstract class AdsRepo {
Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceId}); Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceId});
Future<GenericRespModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel}); Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew});
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds}); Future<List<AdDetailsModel>> getAllAds({required bool isMyAds});
@ -72,15 +72,15 @@ class AdsRepoImp implements AdsRepo {
} }
@override @override
Future<GenericRespModel> createNewAd({required AdsCreationPayloadModel adsCreationPayloadModel}) async { Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew}) async {
List vehiclePostingImages = []; List vehiclePostingImages = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) { adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) {
var imageMap = { var imageMap = {
"id": 0, "id": element.id ?? 0,
"imageName": element.imageName, "imageName": element.imageName,
"imageUrl": element.imageUrl, "imageUrl": element.imageUrl,
"imageStr": element.imageStr, "imageStr": element.imageStr,
"vehiclePostingID": 0, "vehiclePostingID": element.vehiclePostingID ?? 0,
"vehiclePosting": null, "vehiclePosting": null,
}; };
vehiclePostingImages.add(imageMap); vehiclePostingImages.add(imageMap);
@ -89,18 +89,18 @@ class AdsRepoImp implements AdsRepo {
List vehiclePostingDamageParts = []; List vehiclePostingDamageParts = [];
adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) { adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
var imageMap = { var imageMap = {
"id": 0, "id": element.id ?? 0,
"comment": element.comment, "comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64, "vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID, "vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingID": 0, "vehiclePostingID": element.vehiclePostingID ?? 0,
"isActive": true "isActive": true
}; };
vehiclePostingDamageParts.add(imageMap); vehiclePostingDamageParts.add(imageMap);
}); });
var postParams = { var postParams = {
"ads": { "ads": {
"id": 0, "id": adsCreationPayloadModel.ads!.id ?? 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID, "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate, "startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId, "countryId": adsCreationPayloadModel.ads!.countryId,
@ -108,7 +108,7 @@ class AdsRepoImp implements AdsRepo {
"isMCHandled": false "isMCHandled": false
}, },
"vehiclePosting": { "vehiclePosting": {
"id": 0, "id": adsCreationPayloadModel.vehiclePosting!.id ?? 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID, "userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType, "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID, "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
@ -134,11 +134,10 @@ class AdsRepoImp implements AdsRepo {
} }
}; };
logger.i(jsonEncode(postParams.toString()));
String token = appState.getUser.data!.accessToken ?? ""; String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject( GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsSingleStepCreate, isCreateNew ? ApiConsts.vehicleAdsSingleStepCreate : ApiConsts.vehicleAdsSingleStepUpdate,
postParams, postParams,
token: token, token: token,
); );

@ -31,14 +31,11 @@ class ChatRepoImp implements ChatRepo {
HubConnection hub; HubConnection hub;
hub = HubConnectionBuilder() hub = HubConnectionBuilder()
.withUrl( .withUrl(
hubUrl, hubUrl,
HttpConnectionOptions( HttpConnectionOptions(
client: IOClient(HttpClient() client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true),
..badCertificateCallback = (x, y, z) => true), logging: (level, message) {},
logging: (level, message) { ))
log(message);
},
))
.build(); .build();
return hub; return hub;
} }
@ -49,7 +46,7 @@ class ChatRepoImp implements ChatRepo {
"id": messageId.toString(), "id": messageId.toString(),
}; };
await apiClient.postJsonForObject( await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.messageIsReadUpdate, ApiConsts.messageIsReadUpdate,
queryParameters, queryParameters,
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
@ -68,7 +65,7 @@ class ChatRepoImp implements ChatRepo {
"PageIndex": pageIndex.toString(), "PageIndex": pageIndex.toString(),
}; };
GenericRespModel genericRespModel = await apiClient.getJsonForObject( GenericRespModel genericRespModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.getChatMessages, ApiConsts.getChatMessages,
queryParameters: queryParameters, queryParameters: queryParameters,
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
@ -76,7 +73,7 @@ class ChatRepoImp implements ChatRepo {
if (genericRespModel.messageStatus == 1 && genericRespModel.data != null) { if (genericRespModel.messageStatus == 1 && genericRespModel.data != null) {
List<ChatMessageModel> chatMessages = List.generate( List<ChatMessageModel> chatMessages = List.generate(
genericRespModel.data.length, genericRespModel.data.length,
(index) => ChatMessageModel.fromJson(genericRespModel.data[index]), (index) => ChatMessageModel.fromJson(genericRespModel.data[index]),
); );
return chatMessages; return chatMessages;
} }

@ -1,6 +1,10 @@
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class DateHelper { class DateHelper {
static String formatDateT(String dateString) {
return dateString.split('T')[0];
}
static DateTime parseStringToDate(String dateString) { static DateTime parseStringToDate(String dateString) {
final formatter = DateFormat('yyyy-MM-dd'); final formatter = DateFormat('yyyy-MM-dd');
return formatter.parse(dateString); return formatter.parse(dateString);

@ -21,6 +21,7 @@ import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/ads_repo.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/common_services.dart'; import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/date_helper.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';
@ -71,7 +72,8 @@ class AdVM extends BaseVM {
String adPhoneNumberError = ""; String adPhoneNumberError = "";
// Edit Variables Amir // Edit Variables Amir
bool isAdEdit = false; bool isAdEditEnabled = false;
AdDetailsModel? previousAdDetails;
List<AdDetailsModel> exploreAds = []; List<AdDetailsModel> exploreAds = [];
List<AdDetailsModel> exploreAdsFilteredList = []; List<AdDetailsModel> exploreAdsFilteredList = [];
@ -385,18 +387,22 @@ class AdVM extends BaseVM {
// notifyListeners(); // notifyListeners();
// } // }
getVehicleBrandsByVehicleTypeId() async { Future<void> getVehicleBrandsByVehicleTypeId({int vehicleIdForEditAd = -1}) async {
if (vehicleTypeId.selectedId == -1 || vehicleBrands.isNotEmpty) { // if (vehicleTypeId.selectedId == -1 || vehicleBrands.isNotEmpty) {
return; // return;
} // }
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleTypeId.selectedId); isFetchingLists = true;
notifyListeners();
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId);
isFetchingLists = false;
notifyListeners(); notifyListeners();
} }
Future<void> getVehicleDetailsByVehicleBrandId() async { Future<void> getVehicleDetailsByVehicleBrandId() async {
if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) { // if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) {
return; // return;
} // }
isFetchingLists = true; isFetchingLists = true;
notifyListeners(); notifyListeners();
vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId, vehicleBrandId: vehicleBrandId.selectedId); vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId, vehicleBrandId: vehicleBrandId.selectedId);
@ -461,13 +467,13 @@ class AdVM extends BaseVM {
void updateSelectionVehicleTypeId(SelectionModel id) async { void updateSelectionVehicleTypeId(SelectionModel id) async {
vehicleTypeId = id; vehicleTypeId = id;
getVehicleBrandsByVehicleTypeId(); await getVehicleBrandsByVehicleTypeId();
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) { Future<void> updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) { if (isForSearch) {
VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId); VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId);
DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", ""); DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", "");
@ -478,7 +484,8 @@ class AdVM extends BaseVM {
return; return;
} }
vehicleBrandId = id; vehicleBrandId = id;
getVehicleDetailsByVehicleBrandId(); logger.i("message: ${vehicleBrandId.selectedOption}");
await getVehicleDetailsByVehicleBrandId();
notifyListeners(); notifyListeners();
} }
@ -881,7 +888,7 @@ class AdVM extends BaseVM {
} else { } else {
vehicleDescError = ""; vehicleDescError = "";
} }
if (pickedVehicleImages.isEmpty || pickedVehicleImages.length < 3) { if ((pickedPostingImages.isEmpty || pickedPostingImages.length < 3) && !isAdEditEnabled) {
vehicleImageError = GlobalConsts.attachImageError; vehicleImageError = GlobalConsts.attachImageError;
isValidated = false; isValidated = false;
} else { } else {
@ -1010,8 +1017,14 @@ class AdVM extends BaseVM {
case AdCreationSteps.damageParts: case AdCreationSteps.damageParts:
if (isDamagePartsValidated()) { if (isDamagePartsValidated()) {
currentProgressStep = AdCreationSteps.adDuration; currentProgressStep = AdCreationSteps.adDuration;
getVehicleAdsDuration(); if (vehicleAdsDurations.isEmpty) {
getVehicleAdsSpecialServices(); getVehicleAdsDuration();
}
if (vehicleAdsSpecialServices.isEmpty) {
getVehicleAdsSpecialServices();
}
notifyListeners(); notifyListeners();
} }
break; break;
@ -1029,6 +1042,7 @@ class AdVM extends BaseVM {
Utils.hideLoading(context); Utils.hideLoading(context);
return; return;
} }
isAdEditEnabled = false;
Utils.hideLoading(context); Utils.hideLoading(context);
currentProgressStep = AdCreationSteps.vehicleDetails; currentProgressStep = AdCreationSteps.vehicleDetails;
resetValues(); resetValues();
@ -1065,30 +1079,35 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
List<File> pickedVehicleImages = []; List<ImageModel> pickedPostingImages = [];
void removeImageFromList(String filePath) { void removeImageFromList(String filePath) {
int index = pickedVehicleImages.indexWhere((element) => element.path == filePath); int index = pickedPostingImages.indexWhere((element) => element.filePath == filePath);
if (index == -1) { if (index == -1) {
return; return;
} }
pickedVehicleImages.removeAt(index); pickedPostingImages.removeAt(index);
notifyListeners(); notifyListeners();
} }
void pickMultipleImages() async { void pickMultipleImages() async {
List<ImageModel> imageModels = [];
List<File> images = await commonServices.pickMultipleImages(); List<File> images = await commonServices.pickMultipleImages();
pickedVehicleImages.addAll(images);
if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
pickedPostingImages.addAll(imageModels);
if (pickedPostingImages.isNotEmpty) vehicleImageError = "";
notifyListeners(); notifyListeners();
} }
List<File> pickedReceiptPdfFiles = []; List<ImageModel> pickedReceiptPdfFiles = [];
String receiptPdfFileError = ""; String receiptPdfFileError = "";
void removePdfFileFromList(String filePath) { void removePdfFileFromList(String filePath) {
int index = pickedReceiptPdfFiles.indexWhere((element) => element.path == filePath); int index = pickedReceiptPdfFiles.indexWhere((element) => element.filePath == filePath);
if (index == -1) { if (index == -1) {
return; return;
} }
@ -1097,8 +1116,13 @@ class AdVM extends BaseVM {
} }
void pickPdfReceiptFile(BuildContext context) async { void pickPdfReceiptFile(BuildContext context) async {
List<ImageModel> imageModels = [];
List<File>? files = await commonServices.pickMultipleFiles(context); List<File>? files = await commonServices.pickMultipleFiles(context);
pickedReceiptPdfFiles.addAll(files!); if (files == null) return;
for (var element in files) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
pickedReceiptPdfFiles.addAll(imageModels);
if (pickedReceiptPdfFiles.isNotEmpty) receiptPdfFileError = ""; if (pickedReceiptPdfFiles.isNotEmpty) receiptPdfFileError = "";
notifyListeners(); notifyListeners();
} }
@ -1106,13 +1130,16 @@ class AdVM extends BaseVM {
// 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<ImageModel> imageModels = [];
List<File> images = await commonServices.pickMultipleImages(); List<File> images = await commonServices.pickMultipleImages();
for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
if (images.isNotEmpty) { if (images.isNotEmpty) {
if (vehicleDamageCards[index].partImages == null) { if (vehicleDamageCards[index].partImages == null) {
vehicleDamageCards[index].partImages = images; vehicleDamageCards[index].partImages = imageModels;
} else { } else {
vehicleDamageCards[index].partImages!.addAll(images); vehicleDamageCards[index].partImages!.addAll(imageModels);
} }
vehicleDamageCards[index].partImageErrorValue = ""; vehicleDamageCards[index].partImageErrorValue = "";
notifyListeners(); notifyListeners();
@ -1147,7 +1174,7 @@ class AdVM extends BaseVM {
void removeDamageImageFromCard(int imageIndex, String filePath, int cardIndex) { void removeDamageImageFromCard(int imageIndex, String filePath, int cardIndex) {
VehicleDamageCard card = vehicleDamageCards.elementAt(cardIndex); VehicleDamageCard card = vehicleDamageCards.elementAt(cardIndex);
if (card.partImages == null) return; if (card.partImages == null) return;
int index = card.partImages!.indexWhere((element) => element.path == filePath); int index = card.partImages!.indexWhere((element) => element.filePath == filePath);
if (index == -1) { if (index == -1) {
return; return;
} }
@ -1164,9 +1191,10 @@ class AdVM extends BaseVM {
void resetValues() { void resetValues() {
pickedDamageImages.clear(); pickedDamageImages.clear();
pickedVehicleImages.clear(); pickedPostingImages.clear();
vehicleDamageCards.clear(); vehicleDamageCards.clear();
specialServiceCards.clear(); specialServiceCards.clear();
vehicleAdsSpecialServices.clear();
currentProgressStep = AdCreationSteps.vehicleDetails; currentProgressStep = AdCreationSteps.vehicleDetails;
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
@ -1181,14 +1209,13 @@ class AdVM extends BaseVM {
vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleDemandAmount = ""; vehicleDemandAmount = "";
vehicleVin = ""; vehicleVin = "";
vehicleTitle = ""; vehicleTitle = "";
warrantyDuration = ""; warrantyDuration = "";
vehicleDescription = ""; vehicleDescription = "";
selectionDurationStartDate = ""; selectionDurationStartDate = "";
clearSpecialServiceCard();
updateFinanceAvailableStatus(false); updateFinanceAvailableStatus(false);
notifyListeners(); notifyListeners();
} }
@ -1327,6 +1354,7 @@ class AdVM extends BaseVM {
adsSelectedServices.add(value.serviceSelectedId!.selectedId); adsSelectedServices.add(value.serviceSelectedId!.selectedId);
} }
Ads ads = Ads( Ads ads = Ads(
id: isAdEditEnabled ? previousAdDetails!.id : null,
adsDurationID: vehicleAdDurationId.selectedId, adsDurationID: vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate, startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId, countryId: vehicleCountryId.selectedId,
@ -1334,8 +1362,8 @@ class AdVM extends BaseVM {
); );
List<VehiclePostingImages> vehicleImages = []; List<VehiclePostingImages> vehicleImages = [];
for (var element in pickedVehicleImages) { for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(file: element)); vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
} }
List<VehiclePostingDamageParts> vehicleDamageImages = []; List<VehiclePostingDamageParts> vehicleDamageImages = [];
@ -1344,7 +1372,7 @@ class AdVM extends BaseVM {
if (card.partImages != null && card.partImages!.isNotEmpty) { 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, imageModel: image,
damagePartId: card.partSelectedId!.selectedId, damagePartId: card.partSelectedId!.selectedId,
); );
vehicleDamageImages.add(stringImage); vehicleDamageImages.add(stringImage);
@ -1353,6 +1381,7 @@ class AdVM extends BaseVM {
} }
VehiclePosting vehiclePosting = VehiclePosting( VehiclePosting vehiclePosting = VehiclePosting(
id: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
userID: appState.getUser.data!.userInfo!.userId, userID: appState.getUser.data!.userInfo!.userId,
vehicleType: vehicleTypeId.selectedId, vehicleType: vehicleTypeId.selectedId,
vehicleModelID: vehicleModelId.selectedId, vehicleModelID: vehicleModelId.selectedId,
@ -1379,32 +1408,57 @@ class AdVM extends BaseVM {
); );
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
GenericRespModel respModel = await adsRepo.createNewAd(adsCreationPayloadModel: adsCreationPayloadModel); GenericRespModel respModel = await adsRepo.createOrUpdateAd(adsCreationPayloadModel: adsCreationPayloadModel, isCreateNew: !isAdEditEnabled);
Utils.showToast(respModel.message.toString()); Utils.showToast(respModel.message.toString());
return Future.value(respModel.messageStatus); return Future.value(respModel.messageStatus);
} }
Future<VehiclePostingImages> convertFileToVehiclePostingImages({required File file}) async { Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async {
List<int> imageBytes = await file.readAsBytes(); VehiclePostingImages vehiclePostingImages;
String image = base64Encode(imageBytes); if (imageModel.isFromNetwork ?? false) {
String fileName = file.path.split('/').last; vehiclePostingImages = VehiclePostingImages(
VehiclePostingImages vehiclePostingImages = VehiclePostingImages( id: imageModel.id,
imageName: fileName, imageUrl: imageModel.filePath,
imageStr: image, );
imageUrl: file.path, } else {
); File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
String fileName = file.path.split('/').last;
vehiclePostingImages = VehiclePostingImages(
imageName: fileName,
imageStr: image,
imageUrl: file.path,
vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
);
}
return vehiclePostingImages; return vehiclePostingImages;
} }
Future<VehiclePostingDamageParts> convertFileToVehiclePostingDamageParts({required File file, required int damagePartId}) async { Future<VehiclePostingDamageParts> convertFileToVehiclePostingDamageParts({required ImageModel imageModel, required int damagePartId}) async {
List<int> imageBytes = await file.readAsBytes(); VehiclePostingDamageParts vehiclePostingDamageParts;
String image = base64Encode(imageBytes);
VehiclePostingDamageParts vehiclePostingDamageParts = VehiclePostingDamageParts( if (imageModel.isFromNetwork ?? false) {
vehicleImageBase64: image, vehiclePostingDamageParts = VehiclePostingDamageParts(
vehicleDamagePartID: damagePartId, id: imageModel.id,
); vehicleDamagePartID: damagePartId,
imageUrl: imageModel.filePath,
vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
);
} else {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
vehiclePostingDamageParts = VehiclePostingDamageParts(
vehicleImageBase64: image,
vehicleDamagePartID: damagePartId,
imageUrl: file.path,
);
}
return vehiclePostingDamageParts; return vehiclePostingDamageParts;
} }
@ -1600,25 +1654,21 @@ class AdVM extends BaseVM {
///// Edit Work Amir ///// Edit Work Amir
void editUpdateAd(BuildContext context, AdDetailsModel previousDetails) { void onEditUpdateAdPressed(BuildContext context, AdDetailsModel previousDetails) {
isAdEdit = true; isAdEditEnabled = true;
previousAdDetails = previousDetails;
autoFillSelectedVehicleType();
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: AppState().currentAppType == AppType.provider ? true : false); navigateWithName(context, AppRoutes.selectAdTypeView, arguments: AppState().currentAppType == AppType.provider ? true : false);
checkVehicleStep1(previousDetails);
checkVehicleStep2(previousDetails);
} }
void clearEditValues() { autoFillSelectedVehicleType() async {
isAdEdit = false; if (vehicleTypes.isEmpty) {
if (vehicleTypes.isNotEmpty) vehicleTypes.unselectAll(); await getVehicleTypes();
if (vehicleAdsDurations.isNotEmpty) vehicleAdsDurations.unselectAll(); return;
} }
checkVehicleStep1(AdDetailsModel previousDetails) {
logger.d("Step 1");
if (vehicleTypes.isNotEmpty) { if (vehicleTypes.isNotEmpty) {
for (var vehicle in vehicleTypes) { for (var vehicle in vehicleTypes) {
if (vehicle.id == previousDetails.vehicle?.vehicleType) { if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) {
vehicle.isSelected = true; vehicle.isSelected = true;
break; break;
} }
@ -1627,55 +1677,137 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
checkVehicleStep2(AdDetailsModel previousDetails) { autoFillSelectedVehicleAdsDuration() async {
logger.d("Step 2"); if (vehicleAdsDurations.isEmpty) {
await getVehicleAdsDuration();
}
if (vehicleAdsDurations.isNotEmpty) { if (vehicleAdsDurations.isNotEmpty) {
for (var adsDuration in vehicleAdsDurations) { int index = vehicleAdsDurations.indexWhere((element) => element.price == previousAdDetails!.adsDurationPrice!);
if (adsDuration.price == previousDetails.adsDurationPrice) { if (index != -1) {
adsDuration.isSelected = true; updateVehicleAdDurationId(
break; SelectionModel(
} selectedId: vehicleAdsDurations[index].id ?? 0,
selectedOption: "${vehicleAdsDurations[index].days} Days",
itemPrice: vehicleAdsDurations[index].price!.toInt().toString(),
),
);
} }
} }
notifyListeners(); notifyListeners();
} }
checkVehicleStep3(AdDetailsModel previousDetails) {
logger.d("Step 3"); List<VehiclePostingDamageParts> vehicleOldDamageImagesList = [];
if (vehicleBrands.isNotEmpty) {
for (var vBrands in vehicleBrands) { void removeVehicleOldDamageImagesList(String imageUrl) {
if (vBrands.id == previousDetails.vehicle.) { int index = vehicleOldDamageImagesList.indexWhere((element) => element.imageUrl == imageUrl);
// BrandsId need to be matched here. if (index == -1) {
vBrands.isSelected = true; return;
break;
}
}
} }
vehicleOldDamageImagesList.removeAt(index);
notifyListeners(); notifyListeners();
} }
updateValues() { autoFillSelectedVehicleAdsDetails() async {
if (isAdEdit) { int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID);
if (vehicleTypes.isNotEmpty) vehicleTypes.unselectAll(); if (index != -1) {
if (vehicleAdsDurations.isNotEmpty) vehicleAdsDurations.unselectAll(); await updateSelectionVehicleBrandId(SelectionModel(selectedId: vehicleBrands[index].id!, selectedOption: vehicleBrands[index].vehicleBrandDescription ?? ""));
notifyListeners(); }
updateSelectionVehicleModelId(SelectionModel(selectedId: previousAdDetails!.vehicle!.model!.id!, selectedOption: previousAdDetails!.vehicle!.model!.label ?? ""));
updateSelectionVehicleModelYearId(SelectionModel(selectedId: previousAdDetails!.vehicle!.modelyear!.id!, selectedOption: previousAdDetails!.vehicle!.modelyear!.label ?? ""));
updateSelectionVehicleColorId(SelectionModel(selectedId: previousAdDetails!.vehicle!.color!.id!, selectedOption: previousAdDetails!.vehicle!.color!.label ?? ""));
updateSelectionVehicleConditionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.condition!.id!, selectedOption: previousAdDetails!.vehicle!.condition!.label ?? ""));
updateSelectionVehicleCategoryId(SelectionModel(selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: previousAdDetails!.vehicle!.category!.label ?? ""));
updateSelectionVehicleMileageId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.mileage!.id!, selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}"));
updateSelectionVehicleTransmissionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.transmission!.id!, selectedOption: previousAdDetails!.vehicle!.transmission!.label ?? ""));
updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: previousAdDetails!.vehicle!.sellertype!.id!, selectedOption: previousAdDetails!.vehicle!.sellertype!.label ?? ""));
int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID);
if (indexCountry != -1) {
updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[index].id!, selectedOption: vehicleCountries[index].countryName ?? ""));
}
updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? ""));
vehicleDemandAmount = previousAdDetails!.vehicle!.demandAmount!.toInt().toString();
vehicleVin = previousAdDetails!.vehicle!.vehicleVIN.toString();
vehicleTitle = previousAdDetails!.vehicle!.vehicleTitle.toString();
vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString();
financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
for (var element in previousAdDetails!.vehicle!.image!) {
if (element.imageUrl != null) {
ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true);
pickedPostingImages.add(imageModel);
}
}
} }
}
}
extension ToggleSelected on List { if (previousAdDetails!.vehicle!.damagereport != null && previousAdDetails!.vehicle!.damagereport!.isNotEmpty) {
void unselectAll() { for (var element in previousAdDetails!.vehicle!.damagereport!) {
for (var element in this) { int index = -1;
if (element.isSelected!) { if (vehicleDamageCards.isNotEmpty) {
element.isSelected = false; index = ifDamagePartAlreadyThere(element.vehicleDamagePartID!);
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
vehicleDamageCards[index].partImages!.add(imageModel);
} else {
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
partImages: [imageModel],
);
addNewDamagePartCard(damageCard: vehicleDamageCard);
}
} }
} }
if (previousAdDetails!.specialservice != null && previousAdDetails!.specialservice!.isNotEmpty) {
for (var element in previousAdDetails!.specialservice!) {
SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedId: element.specialServiceID!, selectedOption: element.name ?? "", itemPrice: element.price.toString());
SpecialServiceCard specialServiceCard = SpecialServiceCard(
serviceSelectedId: vehicleAdsSpecialServicesId,
description: element.description ?? "",
duration: "",
serviceDate: "",
serviceDateError: "",
serviceTimeError: "",
address: "",
serviceTime: "",
);
addNewSpecialServiceCard(specialServiceCard: specialServiceCard);
}
}
selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
isPhoneNumberShown = previousAdDetails!.phoneNo != null;
if (isPhoneNumberShown) {
adPhoneNumber = previousAdDetails!.phoneNo ?? "";
adPhoneNumberDialCode = "+966";
}
isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null;
logger.i("previousAdDetails!: $previousAdDetails");
notifyListeners();
}
int ifDamagePartAlreadyThere(int partId) {
return vehicleDamageCards.indexWhere((element) => element.partSelectedId!.selectedId == partId);
}
int ifSpecialServiceAlreadyThere(int id) {
return specialServiceCards.indexWhere((element) => element.serviceSelectedId!.selectedId == id);
} }
} }
// Edit Work End Amir // Edit Work End Amir
class VehicleDamageCard { class VehicleDamageCard {
List<File>? partImages; List<ImageModel>? partImages;
SelectionModel? partSelectedId; SelectionModel? partSelectedId;
String partImageErrorValue; String partImageErrorValue;
@ -1684,6 +1816,24 @@ class VehicleDamageCard {
this.partSelectedId, this.partSelectedId,
this.partImageErrorValue = "", this.partImageErrorValue = "",
}); });
@override
String toString() {
return 'VehicleDamageCard{partImages: $partImages, partSelectedId: $partSelectedId, partImageErrorValue: $partImageErrorValue}';
}
}
class ImageModel {
int? id;
bool? isFromNetwork;
String? filePath;
ImageModel({this.id, this.filePath, this.isFromNetwork});
@override
String toString() {
return 'ImageModel{id: $id, isFromNetwork: $isFromNetwork, filePath: $filePath}';
}
} }
class SpecialServiceCard { class SpecialServiceCard {

@ -21,6 +21,7 @@ import 'package:mc_common_app/services/common_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/ad_view_model.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/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -97,11 +98,11 @@ class RequestsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
List<File> pickedVehicleImages = []; List<ImageModel> pickedVehicleImages = [];
String vehicleImageError = ""; String vehicleImageError = "";
void removeImageFromList(String filePath) { void removeImageFromList(String filePath) {
int index = pickedVehicleImages.indexWhere((element) => element.path == filePath); int index = pickedVehicleImages.indexWhere((element) => element.filePath == filePath);
if (index == -1) { if (index == -1) {
return; return;
} }
@ -110,8 +111,12 @@ class RequestsVM extends BaseVM {
} }
void pickMultipleImages() async { void pickMultipleImages() async {
List<ImageModel> imageModels = [];
List<File> images = await commonServices.pickMultipleImages(); List<File> images = await commonServices.pickMultipleImages();
pickedVehicleImages.addAll(images); for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
}
pickedVehicleImages.addAll(imageModels);
if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
notifyListeners(); notifyListeners();
} }
@ -251,7 +256,7 @@ class RequestsVM extends BaseVM {
log("requestImages: ${pickedVehicleImages.length}"); log("requestImages: ${pickedVehicleImages.length}");
for (var image in pickedVehicleImages) { for (var image in pickedVehicleImages) {
var value = await convertFileToRequestPostingImages(file: image); var value = await convertFileToRequestPostingImages(file: File(image.filePath!));
requestImages.add(value); requestImages.add(value);
} }

@ -110,10 +110,10 @@ class VehicleDetailsReview extends StatelessWidget {
SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"), SingleDetailWidget(text: adVM.vehicleDescription, type: "Description"),
8.height, 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.pickedPostingImages.isNotEmpty) ...[
// 10.height, // 10.height,
PickedFilesContainer( PickedFilesContainer(
pickedFiles: adVM.pickedVehicleImages, pickedFiles: adVM.pickedPostingImages,
onCrossPressedPrimary: adVM.removeImageFromList, onCrossPressedPrimary: adVM.removeImageFromList,
isReview: true, isReview: true,
onAddFilePressed: () {}, onAddFilePressed: () {},

@ -6,6 +6,7 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.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/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/views/advertisement/network_images_container.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.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';
@ -128,6 +129,7 @@ class DamageParts extends StatelessWidget {
], ],
).paddingOnly(right: 10) ).paddingOnly(right: 10)
], ],
], ],
).toWhiteContainer( ).toWhiteContainer(
width: double.infinity, width: double.infinity,

@ -7,6 +7,7 @@ import 'package:mc_common_app/models/general_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/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/ad_creation_steps/ad_creation_steps_containers.dart';
import 'package:mc_common_app/views/advertisement/network_images_container.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.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';
@ -276,16 +277,27 @@ class VehicleDetails extends StatelessWidget {
], ],
).paddingOnly(right: 10) ).paddingOnly(right: 10)
], ],
if (adVM.pickedVehicleImages.isNotEmpty) ...[ if (adVM.pickedPostingImages.isNotEmpty) ...[
16.height, 16.height,
PickedFilesContainer( PickedFilesContainer(
pickedFiles: adVM.pickedVehicleImages, pickedFiles: adVM.pickedPostingImages,
onCrossPressedPrimary: adVM.removeImageFromList, onCrossPressedPrimary: adVM.removeImageFromList,
onAddFilePressed: () { onAddFilePressed: () {
context.read<AdVM>().pickMultipleImages(); context.read<AdVM>().pickMultipleImages();
}, },
), ),
], ],
// if (adVM.isAdEditEnabled) ...[
// if (adVM.previousAdDetails!.vehicle!.image!.isNotEmpty) ...[
// 16.height,
// "Old Images".toText(fontSize: 16),
// NetworkFilesContainerForVehiclePosting(
// networkFilesForVehiclePosting: adVM.vehicleOldImagesList,
// onCrossPressedPrimary: adVM.removeVehicleOldImagesList,
// onAddFilePressed: () => context.read<AdVM>().pickMultipleImages(),
// ),
// ],
// ],
15.height, 15.height,
], ],
] ]

@ -2,6 +2,7 @@ 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/main.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/general_models/widgets_models.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -71,13 +72,10 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
), ),
], ],
).toWhiteContainer( ).toWhiteContainer(
width: double.infinity, width: double.infinity,
allPading: 12, allPading: 12,
isBorderRequired: adDuration.isSelected! isBorderRequired: adDuration.id == adVM.vehicleAdDurationId.selectedId,
? true ),
: adDuration.id == adVM.vehicleAdDurationId.selectedId
? true
: false),
).onPress(() { ).onPress(() {
if (isFromExtendAd) { if (isFromExtendAd) {
adVM.updateVehicleExtendAdDurationId( adVM.updateVehicleExtendAdDurationId(
@ -96,7 +94,6 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
itemPrice: adDuration.price!.toInt().toString(), itemPrice: adDuration.price!.toInt().toString(),
), ),
); );
adVM.updateValues();
}); });
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
@ -106,15 +103,27 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
), ),
), ),
ShowFillButton( ShowFillButton(
title: "Select", iconWidget: adVM.isFetchingLists ? const Padding(
padding: EdgeInsets.all(8.0),
child: SizedBox(
height: 30,
width: 30,
child: CircularProgressIndicator(color: Colors.white),
),
) : null,
title: adVM.isFetchingLists ? "" : "Select",
maxWidth: double.infinity, maxWidth: double.infinity,
margin: const EdgeInsets.all(21), margin: const EdgeInsets.all(21),
onPressed: () { onPressed: () {
if (isFromExtendAd && !isUpdateAdSelected) { if (adVM.isFetchingLists) {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.extendAds);
return; return;
} else {
if (isFromExtendAd && !isUpdateAdSelected) {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.extendAds);
return;
}
navigateReplaceWithName(context, AppRoutes.createAdView);
} }
navigateReplaceWithName(context, AppRoutes.createAdView);
}, },
).toContainer(paddingAll: 0, backgroundColor: Colors.white), ).toContainer(paddingAll: 0, backgroundColor: Colors.white),
], ],

@ -21,7 +21,6 @@ import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart'; import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart'; import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/ads_images_slider.dart'; import 'package:mc_common_app/views/advertisement/ads_images_slider.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/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart'; import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart';
@ -33,7 +32,6 @@ 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';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
class AdsDetailView extends StatefulWidget { class AdsDetailView extends StatefulWidget {
final AdDetailsModel adDetails; final AdDetailsModel adDetails;
@ -93,14 +91,8 @@ class _AdsDetailViewState extends State<AdsDetailView> {
); );
} }
void editAd() {
AdVM adVM = context.read<AdVM>();
adVM.editUpdateAd(context, widget.adDetails);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
log("ad: ${widget.adDetails.vehicle!.image!.first.imageUrl}");
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Ads", title: "Ads",
@ -109,16 +101,16 @@ class _AdsDetailViewState extends State<AdsDetailView> {
isDrawerEnabled: false, isDrawerEnabled: false,
actions: [ actions: [
((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved) ((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved)
? IconButton( ? IconButton(
icon: const Icon(Icons.delete_outline, color: MyColors.redColor), icon: const Icon(Icons.delete_outline, color: MyColors.redColor),
onPressed: () { onPressed: () {
return deleteAdBottomSheet(context); return deleteAdBottomSheet(context);
}, },
) )
: IconButton( : IconButton(
icon: const Icon(Icons.chat_outlined, color: Colors.black), icon: const Icon(Icons.chat_outlined, color: Colors.black),
onPressed: () {}, onPressed: () {},
)) ))
.toContainer( .toContainer(
margin: const EdgeInsets.fromLTRB(0, 8, 21, 8), margin: const EdgeInsets.fromLTRB(0, 8, 21, 8),
paddingAll: 0, paddingAll: 0,
@ -149,7 +141,7 @@ class _AdsDetailViewState extends State<AdsDetailView> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Flexible( Flexible(
child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | AdID: ${widget.adDetails.id}".toText( child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText(
fontSize: 18, fontSize: 18,
isBold: true, isBold: true,
maxLines: 2, maxLines: 2,
@ -278,29 +270,31 @@ class _AdsDetailViewState extends State<AdsDetailView> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Rejection Comments".toText(fontSize: 18, isBold: true, color: MyColors.lightTextColor), "Rejection Comments".toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor),
Row( Row(
children: [ children: [
Icon( "Edit Ad".toText(fontSize: 10, isBold: true),
Icons.edit,
size: 15,
),
2.width, 2.width,
"Edit Add".toText(fontSize: 10, isBold: true), const Icon(Icons.edit, size: 15),
], ],
).onPress(() { ).onPress(() async {
logger.i(widget.adDetails); Utils.showLoading(context);
editAd(); await context.read<AdVM>().getVehicleTypes();
await context.read<AdVM>().getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: widget.adDetails.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
context.read<AdVM>().onEditUpdateAdPressed(context, widget.adDetails);
}), }),
], ],
).paddingOnly(bottom: 5), ).paddingOnly(bottom: 5),
Row( Row(
children: [ children: [
(widget.adDetails.comment ?? "").toText( Flexible(
color: MyColors.redColor, child: (widget.adDetails.comment ?? "").toText(
fontSize: 12, color: MyColors.redColor,
isItalic: true, fontSize: 12,
), isItalic: true,
),
)
], ],
), ),
], ],
@ -525,36 +519,36 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
Widget defaultActionForProviderAndCustomer(BuildContext context, AdDetailsModel adDetailsModel) { Widget defaultActionForProviderAndCustomer(BuildContext context, AdDetailsModel adDetailsModel) {
return (adDetailsModel.phoneNo == null) return (adDetailsModel.phoneNo == null)
? Row( ? Row(
children: [ children: [
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Contact", title: "Contact",
fontSize: 18, fontSize: 18,
isBold: false, isBold: false,
iconWidget: const Padding( iconWidget: const Padding(
padding: EdgeInsets.only(right: 10), padding: EdgeInsets.only(right: 10),
child: Icon(Icons.phone, color: MyColors.white, size: 24), child: Icon(Icons.phone, color: MyColors.white, size: 24),
), ),
onPressed: () { onPressed: () {
Utils.openNumberViaCaller(phoneNumber: adDetailsModel.phoneNo ?? ""); Utils.openNumberViaCaller(phoneNumber: adDetailsModel.phoneNo ?? "");
}, },
), ),
), ),
if (adDetailsModel.whatsAppNo == null) ...[ if (adDetailsModel.whatsAppNo == null) ...[
8.width, 8.width,
Container( Container(
height: 55, height: 55,
width: 55, width: 55,
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
child: MyAssets.whatsAppIcon.buildSvg(height: 33, width: 35)) child: MyAssets.whatsAppIcon.buildSvg(height: 33, width: 35))
.onPress(() { .onPress(() {
Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? ""); Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? "");
}), }),
], ],
], ],
) )
: const SizedBox.shrink(); : const SizedBox.shrink();
} }
@ -598,23 +592,23 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
adVM.state == ViewState.busy adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: Builder( : Builder(
builder: (context) { builder: (context) {
List<DropValue> vehicleCitiesDrop = []; List<DropValue> vehicleCitiesDrop = [];
for (int i = 0; i < adVM.photoSSSchedulesByOffices.length; i++) { for (int i = 0; i < adVM.photoSSSchedulesByOffices.length; i++) {
var element = adVM.photoSSSchedulesByOffices[i]; var element = adVM.photoSSSchedulesByOffices[i];
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString())); vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString()));
} }
return DropdownField( return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)), (DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
// here the item price is the index of the selected option // here the item price is the index of the selected option
list: vehicleCitiesDrop, list: vehicleCitiesDrop,
dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null, dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null,
hint: "Select Office", hint: "Select Office",
errorValue: adVM.photoOfficeSelectedId.errorValue, errorValue: adVM.photoOfficeSelectedId.errorValue,
); );
}, },
), ),
if (adVM.photoOfficeSelectedId.selectedId != -1) ...[ if (adVM.photoOfficeSelectedId.selectedId != -1) ...[
9.height, 9.height,
CustomCalenderAppointmentWidget( CustomCalenderAppointmentWidget(
@ -959,7 +953,10 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
return InfoBottomSheet( return InfoBottomSheet(
title: "Cancel Reservation".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), title: "Cancel Reservation".toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding: EdgeInsets.only(bottom: MediaQuery
.of(context)
.viewInsets
.bottom),
child: Consumer<AdVM>( child: Consumer<AdVM>(
builder: (BuildContext context, AdVM adVM, Widget? child) { builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column( return Column(
@ -1075,7 +1072,10 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
return InfoBottomSheet( return InfoBottomSheet(
title: "Upload Bank Receipt".toText(fontSize: 26, isBold: true, letterSpacing: -1.44), title: "Upload Bank Receipt".toText(fontSize: 26, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding: EdgeInsets.only(bottom: MediaQuery
.of(context)
.viewInsets
.bottom),
child: Consumer<AdVM>( child: Consumer<AdVM>(
builder: (BuildContext context, AdVM adVM, Widget? child) { builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column( return Column(
@ -1107,27 +1107,28 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
}, },
isPdf: true, isPdf: true,
), ),
] else ...[ ] else
Row( ...[
children: [ Row(
Container( children: [
height: 90, Container(
width: 90, height: 90,
decoration: BoxDecoration(color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)), width: 90,
margin: const EdgeInsets.all(8), decoration: BoxDecoration(color: MyColors.greyButtonColor, border: Border.all(width: 2, color: MyColors.greyAddBorderColor)),
alignment: Alignment.center, margin: const EdgeInsets.all(8),
child: Container( alignment: Alignment.center,
height: 24, child: Container(
width: 24, height: 24,
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), width: 24,
child: const Icon(Icons.add, color: MyColors.white), decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
), child: const Icon(Icons.add, color: MyColors.white),
).onPress(() { ),
context.read<AdVM>().pickPdfReceiptFile(context); ).onPress(() {
}), context.read<AdVM>().pickPdfReceiptFile(context);
], }),
), ],
], ),
],
15.height, 15.height,
ShowFillButton( ShowFillButton(
title: "Submit", title: "Submit",
@ -1256,6 +1257,8 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
return pendingForReviewAction(pendingText: "Waiting for Admins Approval"); return pendingForReviewAction(pendingText: "Waiting for Admins Approval");
case AdPostStatus.sold: case AdPostStatus.sold:
return pendingForReviewAction(pendingText: "Sold");
case AdPostStatus.expired: case AdPostStatus.expired:
return expiredAdAction(context); return expiredAdAction(context);
case AdPostStatus.allAds: case AdPostStatus.allAds:

@ -6,7 +6,7 @@ import 'package:mc_common_app/theme/colors.dart';
class CarouselWithIndicatorDemo extends StatefulWidget { class CarouselWithIndicatorDemo extends StatefulWidget {
final List<AdImage> vehicleImages; final List<AdImage> vehicleImages;
const CarouselWithIndicatorDemo({key, required this.vehicleImages}); const CarouselWithIndicatorDemo({super.key, required this.vehicleImages});
@override @override
State<StatefulWidget> createState() => _CarouselWithIndicatorState(); State<StatefulWidget> createState() => _CarouselWithIndicatorState();
@ -16,21 +16,15 @@ class _CarouselWithIndicatorState extends State<CarouselWithIndicatorDemo> {
int _current = 0; int _current = 0;
final CarouselController _controller = CarouselController(); final CarouselController _controller = CarouselController();
// final imgList = [
// MyAssets.bnCar,
// MyAssets.bnCar,
// MyAssets.bnCar,
// ];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column(children: [ return Column(children: [
CarouselSlider( CarouselSlider(
items: widget.vehicleImages items: widget.vehicleImages
.map((item) => Container( .map((item) => Container(
margin: EdgeInsets.all(5.0), margin: const EdgeInsets.all(5.0),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)), borderRadius: const BorderRadius.all(Radius.circular(5.0)),
child: Image.network( child: Image.network(
item.imageUrl!, item.imageUrl!,
fit: BoxFit.cover, fit: BoxFit.cover,
@ -64,7 +58,7 @@ class _CarouselWithIndicatorState extends State<CarouselWithIndicatorDemo> {
child: Container( child: Container(
width: 12.0, width: 12.0,
height: 12.0, height: 12.0,
margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0), margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: _current == entry.key ? MyColors.darkPrimaryColor : MyColors.lightTextColor.withOpacity(0.5), color: _current == entry.key ? MyColors.darkPrimaryColor : MyColors.lightTextColor.withOpacity(0.5),

@ -34,7 +34,7 @@ class _CreateAdViewState extends State<CreateAdView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: adVM.isAdEdit ? "Update Ad": "Create Ad", title: adVM.isAdEditEnabled ? "Update Ad": "Create Ad",
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => adVM.onBackButtonPressed(context), onBackButtonTapped: () => adVM.onBackButtonPressed(context),

@ -0,0 +1,159 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class NetworkFilesContainerForVehiclePosting extends StatelessWidget {
final List<VehiclePostingImages> networkFilesForVehiclePosting;
final Function(String filePath)? onCrossPressedPrimary;
final Function(int index, String filePath)? onCrossPressedSecondary;
final int? index;
final bool isReview;
final Function() onAddFilePressed;
const NetworkFilesContainerForVehiclePosting({
Key? key,
required this.networkFilesForVehiclePosting,
this.onCrossPressedPrimary,
this.onCrossPressedSecondary,
this.index,
required this.onAddFilePressed,
this.isReview = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.count(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 4,
crossAxisSpacing: 4.0,
mainAxisSpacing: 8.0,
children: List.generate(
networkFilesForVehiclePosting.length,
(index) {
return Center(
child: BuildNetworkContainer(
fileUrl: networkFilesForVehiclePosting[index].imageUrl ?? "",
onCrossPressedPrimary: onCrossPressedPrimary,
onCrossPressedSecondary: onCrossPressedSecondary,
index: index,
isReview: isReview,
));
},
),
);
}
}
class NetworkFilesContainerForDamagedParts extends StatelessWidget {
final List<VehiclePostingDamageParts> networkFilesForDamagedParts;
final Function(String filePath)? onCrossPressedPrimary;
final Function(int index, String filePath)? onCrossPressedSecondary;
final int? index;
final bool isReview;
final Function() onAddFilePressed;
const NetworkFilesContainerForDamagedParts({
Key? key,
required this.networkFilesForDamagedParts,
this.onCrossPressedPrimary,
this.onCrossPressedSecondary,
this.index,
required this.onAddFilePressed,
this.isReview = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.count(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 4,
crossAxisSpacing: 4.0,
mainAxisSpacing: 8.0,
children: List.generate(
networkFilesForDamagedParts.length,
(index) {
return Center(
child: BuildNetworkContainer(
fileUrl: networkFilesForDamagedParts[index].imageUrl ?? "",
onCrossPressedPrimary: onCrossPressedPrimary,
onCrossPressedSecondary: onCrossPressedSecondary,
index: index,
isReview: isReview,
));
},
),
);
}
}
class BuildNetworkContainer extends StatelessWidget {
final String fileUrl;
final Function(String filePath)? onCrossPressedPrimary;
final Function(int index, String filePath)? onCrossPressedSecondary;
final int? index;
final bool isReview;
final bool isPdf;
const BuildNetworkContainer({
Key? key,
required this.fileUrl,
this.onCrossPressedPrimary,
this.onCrossPressedSecondary,
this.index,
this.isReview = false,
this.isPdf = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(
height: 90,
width: 90,
child: Stack(
children: [
isPdf
? Container(
height: 72,
width: 70,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: MyColors.darkPrimaryColor,
)),
child: const Icon(Icons.picture_as_pdf).paddingAll(8),
)
: Image.network(
fileUrl,
fit: BoxFit.fill,
height: 72,
width: 70,
).paddingAll(8),
!isReview
? Align(
alignment: Alignment.topRight,
child: MyAssets.closeWithOrangeBg.buildSvg(
fit: BoxFit.fill,
height: 30,
width: 30,
),
).onPress(() {
if (onCrossPressedPrimary == null) {
onCrossPressedSecondary!(index!, fileUrl);
return;
}
onCrossPressedPrimary!(fileUrl);
})
: const SizedBox()
],
)),
],
);
}
}

@ -3,15 +3,17 @@ import 'dart:io';
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/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/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class PickedFilesContainer extends StatelessWidget { class PickedFilesContainer extends StatelessWidget {
final List<File> pickedFiles; final List<ImageModel> pickedFiles;
final Function(String filePath)? onCrossPressedPrimary; final Function(String filePath)? onCrossPressedPrimary;
final Function(int index, String filePath)? onCrossPressedSecondary; final Function(int index, String filePath)? onCrossPressedSecondary;
final int? index; final int? index;
final bool isReview; final bool isReview;
final bool isPdf; final bool isPdf;
final bool isFromNetwork;
final Function() onAddFilePressed; final Function() onAddFilePressed;
const PickedFilesContainer({ const PickedFilesContainer({
@ -23,6 +25,7 @@ class PickedFilesContainer extends StatelessWidget {
required this.onAddFilePressed, required this.onAddFilePressed,
this.isReview = false, this.isReview = false,
this.isPdf = false, this.isPdf = false,
this.isFromNetwork = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -51,7 +54,7 @@ class PickedFilesContainer extends StatelessWidget {
} }
return Center( return Center(
child: BuildFilesContainer( child: BuildFilesContainer(
file: pickedFiles[index], image: pickedFiles[index],
onCrossPressedPrimary: onCrossPressedPrimary, onCrossPressedPrimary: onCrossPressedPrimary,
onCrossPressedSecondary: onCrossPressedSecondary, onCrossPressedSecondary: onCrossPressedSecondary,
index: index, index: index,
@ -76,7 +79,7 @@ class PickedFilesContainer extends StatelessWidget {
} }
class BuildFilesContainer extends StatelessWidget { class BuildFilesContainer extends StatelessWidget {
final File file; final ImageModel image;
final Function(String filePath)? onCrossPressedPrimary; final Function(String filePath)? onCrossPressedPrimary;
final Function(int index, String filePath)? onCrossPressedSecondary; final Function(int index, String filePath)? onCrossPressedSecondary;
final int? index; final int? index;
@ -85,7 +88,7 @@ class BuildFilesContainer extends StatelessWidget {
const BuildFilesContainer({ const BuildFilesContainer({
Key? key, Key? key,
required this.file, required this.image,
this.onCrossPressedPrimary, this.onCrossPressedPrimary,
this.onCrossPressedSecondary, this.onCrossPressedSecondary,
this.index, this.index,
@ -114,12 +117,19 @@ class BuildFilesContainer extends StatelessWidget {
)), )),
child: const Icon(Icons.picture_as_pdf).paddingAll(8), child: const Icon(Icons.picture_as_pdf).paddingAll(8),
) )
: Image.file( : image.isFromNetwork!
file, ? Image.network(
fit: BoxFit.fill, image.filePath!,
height: 72, fit: BoxFit.fill,
width: 70, height: 72,
).paddingAll(8), width: 70,
).paddingAll(8)
: Image.file(
File(image.filePath!),
fit: BoxFit.fill,
height: 72,
width: 70,
).paddingAll(8),
!isReview !isReview
? Align( ? Align(
alignment: Alignment.topRight, alignment: Alignment.topRight,
@ -130,10 +140,10 @@ class BuildFilesContainer extends StatelessWidget {
), ),
).onPress(() { ).onPress(() {
if (onCrossPressedPrimary == null) { if (onCrossPressedPrimary == null) {
onCrossPressedSecondary!(index!, file.path); onCrossPressedSecondary!(index!, image.filePath!);
return; return;
} }
onCrossPressedPrimary!(file.path); onCrossPressedPrimary!(image.filePath!);
}) })
: const SizedBox() : const SizedBox()
], ],

@ -59,134 +59,129 @@ class SelectAdTypeView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( return Scaffold(
onWillPop: () async { appBar: CustomAppBar(
logger.d("Clead All Values"); title: "Select Ad Type",
// clearAll(context); profileImageUrl: MyAssets.bnCar,
AdVM adVM = context.read<AdVM>(); isRemoveBackButton: false,
adVM.clearEditValues(); isDrawerEnabled: false,
return true; ),
}, body: Column(
child: Scaffold( children: [
appBar: CustomAppBar( Expanded(
title: "Select Ad Type", child: Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
profileImageUrl: MyAssets.bnCar, return ListView.separated(
isRemoveBackButton: false, itemCount: adVM.vehicleTypes.length,
isDrawerEnabled: false, itemBuilder: (BuildContext context, int index) {
), VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index];
body: Column( return InkWell(
children: [ onTap: () {
Expanded( adVM.updateSelectionVehicleTypeId(
child: Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) { SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""),
return ListView.separated( );
itemCount: adVM.vehicleTypes.length, if (adVM.isAdEditEnabled) {
itemBuilder: (BuildContext context, int index) { adVM.autoFillSelectedVehicleAdsDuration();
VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index]; adVM.autoFillSelectedVehicleAdsDetails();
return InkWell( }
onTap: () { showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isUpdateAdSelected: false, isFromExtendAd: false));
adVM.updateSelectionVehicleTypeId( },
SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""), child: SizedBox(
); width: double.infinity,
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isUpdateAdSelected: false, isFromExtendAd: false)); child: Row(
}, crossAxisAlignment: CrossAxisAlignment.start,
child: SizedBox( mainAxisAlignment: MainAxisAlignment.start,
width: double.infinity, children: [
child: Row( Expanded(
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ mainAxisAlignment: MainAxisAlignment.start,
Expanded( children: [
child: Column( Row(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.start, children: [
children: [ vehicleTypeModel.vehicleTypeName.toString().toText(fontSize: 18, isBold: true),
getVehicleAdTypeIcon(vehicleTypeModel.vehicleTypeEnum!),
],
),
if (isProvider) ...[
Row(
children: [
"Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"Valid Until Subscription Expiration".toText(fontSize: 13, isBold: true),
],
).paddingOnly(top: 5, bottom: 5),
] else ...[
Row(
children: [
"Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
adVM.vehicleAdDurationId.selectedOption.toText(fontSize: 13, isBold: true),
const Icon(Icons.keyboard_arrow_down_sharp, color: MyColors.darkPrimaryColor, size: 20),
],
).paddingOnly(top: 5, bottom: 5),
],
if (!isProvider) ...[
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
vehicleTypeModel.vehicleTypeName.toString().toText(fontSize: 18, isBold: true), adVM.vehicleAdDurationId.itemPrice.toText(fontSize: 22, isBold: true),
getVehicleAdTypeIcon(vehicleTypeModel.vehicleTypeEnum!), 2.width,
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
], ],
), ),
if (isProvider) ...[
Row(
children: [
"Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"Valid Until Subscription Expiration".toText(fontSize: 13, isBold: true),
],
).paddingOnly(top: 5, bottom: 5),
] else ...[
Row(
children: [
"Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
adVM.vehicleAdDurationId.selectedOption.toText(fontSize: 13, isBold: true),
const Icon(Icons.keyboard_arrow_down_sharp, color: MyColors.darkPrimaryColor, size: 20),
],
).paddingOnly(top: 5, bottom: 5),
],
if (!isProvider) ...[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
adVM.vehicleAdDurationId.itemPrice.toText(fontSize: 22, isBold: true),
2.width,
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
],
),
],
], ],
), ],
), ),
], ),
), ],
),
).toWhiteContainer(width: double.infinity, isBorderRequired: vehicleTypeModel.isSelected! ? true : false, pading: const EdgeInsets.symmetric(horizontal: 20, vertical: 10)), ).toWhiteContainer(width: double.infinity, isBorderRequired: vehicleTypeModel.isSelected! ? true : false, pading: const EdgeInsets.symmetric(horizontal: 20, vertical: 10)),
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return 9.height; return 9.height;
}, },
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
); );
}), }),
), ),
if (isProvider) ...[ if (isProvider) ...[
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
children: [
"5 of 10 ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1),
"Ads Remaining ".toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true),
],
),
const Text.rich(
TextSpan(
children: [ children: [
"5 of 10 ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1), TextSpan(
"Ads Remaining ".toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), text: "You have left with 05 out of 50 ads given in the subscription. ",
style: TextStyle(
fontSize: 14,
color: MyColors.lightTextColor,
)),
TextSpan(
text: "Update Subscription",
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 14,
fontWeight: FontWeight.w600,
color: MyColors.darkPrimaryColor,
))
], ],
), ),
const Text.rich( ),
TextSpan( 10.height,
children: [ ],
TextSpan( ).toContainer(paddingAll: 20, backgroundColor: Colors.white),
text: "You have left with 05 out of 50 ads given in the subscription. ", ]
style: TextStyle( ],
fontSize: 14,
color: MyColors.lightTextColor,
)),
TextSpan(
text: "Update Subscription",
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 14,
fontWeight: FontWeight.w600,
color: MyColors.darkPrimaryColor,
))
],
),
),
10.height,
],
).toContainer(paddingAll: 20, backgroundColor: Colors.white),
]
],
),
), ),
); );
} }

Loading…
Cancel
Save