Added Damage Pictures in ad_detail_view and extend edit ad

master_new_changes
Faiz Hashmi 2 years ago
parent 424942bf58
commit dfa57dbe55

@ -580,5 +580,7 @@
"acceptOfferConfirmation": "هل تريد قبول هذا العرض؟", "acceptOfferConfirmation": "هل تريد قبول هذا العرض؟",
"acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.", "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.",
"noUpcomingAppointments": "لا يوجد موعد قادم متاح", "noUpcomingAppointments": "لا يوجد موعد قادم متاح",
"addNewAppointment": "إضافة موعد جديد" "addNewAppointment": "إضافة موعد جديد",
"myNearbyBranches": "فروعي القريبة",
"myRecentBranches": "فروعي الأخيرة"
} }

@ -581,5 +581,7 @@
"whendoyouWanttoRenew": "When do you want to renew", "whendoyouWanttoRenew": "When do you want to renew",
"renewVar": "Renew", "renewVar": "Renew",
"noUpcomingAppointments": "No Upcoming Appointment Available.", "noUpcomingAppointments": "No Upcoming Appointment Available.",
"addNewAppointment": "Add New Appointment" "addNewAppointment": "Add New Appointment",
"myNearbyBranches": "My Nearby Branches",
"myRecentBranches": "My Recent Branches"
} }

@ -55,6 +55,9 @@ class ApiConsts {
static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get"; static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get";
static String serviceProviderDDLGet = "${baseUrlServices}api/ServiceProviders/ServiceProviderDDL_Get"; static String serviceProviderDDLGet = "${baseUrlServices}api/ServiceProviders/ServiceProviderDDL_Get";
static String GetAllNearBranches = "${baseUrlServices}api/ServiceProviders/ServiceProviderBranchDetail_Get"; static String GetAllNearBranches = "${baseUrlServices}api/ServiceProviders/ServiceProviderBranchDetail_Get";
static String getMyRecentBranches = "${baseUrlServices}api/ServiceProviders/ServiceProviderBranchRecent_Get";
static String getBranchRatings = "${baseUrlServices}api/ServiceProviders/BranchRating_Get";
static String createBranchRatings = "${baseUrlServices}api/ServiceProviders/BranchRating_Create";
//Appointment APIs //Appointment APIs
static String serviceProvidersAppointmentGet = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointment_Get"; static String serviceProvidersAppointmentGet = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointment_Get";
@ -153,6 +156,7 @@ class ApiConsts {
static String getRequestOffers = "${baseUrlServices}api/RequestManagement/ReqOffer_Get"; static String getRequestOffers = "${baseUrlServices}api/RequestManagement/ReqOffer_Get";
static String updateRequestOffer = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateStatus"; static String updateRequestOffer = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateStatus";
static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get"; static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get";
static String getServiceRequestsForProvider = "${baseUrlServices}api/RequestManagement/Request_ServiceProvider";
//Chat //Chat
static String chatHubUrl = "$baseUrlServices/McHub"; static String chatHubUrl = "$baseUrlServices/McHub";

@ -4,7 +4,7 @@ import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'
import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/user_models/register_user.dart'; import 'package:mc_common_app/models/user_models/register_user.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/advertisement/ads_buyer_chats_list_view.dart'; import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart'; import 'package:mc_common_app/views/advertisement/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/ads_filter_view.dart'; import 'package:mc_common_app/views/advertisement/ads_filter_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
@ -83,9 +83,9 @@ class AppRoutes {
static const String paymentMethodsView = "/paymentMethodsView"; static const String paymentMethodsView = "/paymentMethodsView";
//Customer APP: Provider & Services //Customer APP: Provider & Services
static const String branchDetailPage = "/branchDetailPage"; static const String branchDetailView = "/branchDetailPage";
static const String branchSearchFilterPage = "/branchSearchFilterPage"; static const String branchSearchFilterPage = "/branchSearchFilterPage";
static const String providerProfilePage = "/providerProfilePage"; static const String providerProfileView = "/providerProfilePage";
// Subscriptions // Subscriptions
static const String mySubscriptionsPage = "/mySubscriptionsPage"; static const String mySubscriptionsPage = "/mySubscriptionsPage";
@ -145,10 +145,10 @@ class AppRoutes {
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel), AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(), AppRoutes.createAdView: (context) => const CreateAdView(),
AppRoutes.adsFilterView: (context) => const AdsFilterView(), AppRoutes.adsFilterView: (context) => const AdsFilterView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(isProvider: ModalRoute.of(context)!.settings.arguments as bool), AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<bool>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments), AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsListView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>), AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),
AppRoutes.createRequestPage: (context) => const CreateRequestPage(), AppRoutes.createRequestPage: (context) => const CreateRequestPage(),
AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(), AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(),
AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(), AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(),

@ -12,7 +12,7 @@ extension EmailValidator on String {
bool isUnderLine = false, bool isUnderLine = false,
bool isItalic = false, bool isItalic = false,
TextDecoration? textDecoration, TextDecoration? textDecoration,
double letterSpacing = -0.4, double letterSpacing = 0,
TextAlign? textAlign, TextAlign? textAlign,
FontWeight? fontWeight, FontWeight? fontWeight,
double? height, double? height,

@ -596,7 +596,9 @@ class CodegenLoader extends AssetLoader{
"acceptOfferConfirmation": "هل تريد قبول هذا العرض؟", "acceptOfferConfirmation": "هل تريد قبول هذا العرض؟",
"acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.", "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.",
"noUpcomingAppointments": "لا يوجد موعد قادم متاح", "noUpcomingAppointments": "لا يوجد موعد قادم متاح",
"addNewAppointment": "إضافة موعد جديد" "addNewAppointment": "إضافة موعد جديد",
"myNearbyBranches": "فروعي القريبة",
"myRecentBranches": "فروعي الأخيرة"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1181,7 +1183,9 @@ static const Map<String,dynamic> en_US = {
"whendoyouWanttoRenew": "When do you want to renew", "whendoyouWanttoRenew": "When do you want to renew",
"renewVar": "Renew", "renewVar": "Renew",
"noUpcomingAppointments": "No Upcoming Appointment Available.", "noUpcomingAppointments": "No Upcoming Appointment Available.",
"addNewAppointment": "Add New Appointment" "addNewAppointment": "Add New Appointment",
"myNearbyBranches": "My Nearby Branches",
"myRecentBranches": "My Recent Branches"
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -560,5 +560,7 @@ abstract class LocaleKeys {
static const acceptOfferConfirmationMessage = 'acceptOfferConfirmationMessage'; static const acceptOfferConfirmationMessage = 'acceptOfferConfirmationMessage';
static const noUpcomingAppointments = 'noUpcomingAppointments'; static const noUpcomingAppointments = 'noUpcomingAppointments';
static const addNewAppointment = 'addNewAppointment'; static const addNewAppointment = 'addNewAppointment';
static const myNearbyBranches = 'myNearbyBranches';
static const myRecentBranches = 'myRecentBranches';
} }

@ -1,95 +1,34 @@
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/theme/app_theme.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:sizer/sizer.dart';
//testing push
final navigatorKey = GlobalKey<NavigatorState>();
Logger logger = Logger(
printer: PrettyPrinter(printEmojis: false, colors: true,printTime: false),
);
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
}
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
// AppState().setPostParamsInitConfig();
HttpOverrides.global = MyHttpOverrides();
runApp( Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false));
EasyLocalization(
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('ar', 'SA'),
],
path: 'resources',
// assetLoader: const CodegenLoader(),
child: MultiProvider(
providers: const <SingleChildWidget>[
// ChangeNotifierProvider<LoginProviderModel>(
// create: (_) => LoginProviderModel(),
// ),
],
child: const MyApp(),
),
),
);
}
// todo terminal command to genertate translation files
// flutter pub run easy_localization:generate --source-dir ./assets/langs
// todo terminal command to genertate translation keys
// flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart
// command to generate languages data from json
class MyApp extends StatelessWidget { // class MyHttpOverrides extends HttpOverrides {
const MyApp({super.key}); // @override
// HttpClient createHttpClient(SecurityContext? context) {
// return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
// }
// }
@override // Future<void> main() async {
Widget build(BuildContext context) { // WidgetsFlutterBinding.ensureInitialized();
return LayoutBuilder(builder: (context, constraints) { //
return Sizer( // await EasyLocalization.ensureInitialized();
builder: ( // // AppState().setPostParamsInitConfig();
BuildContext context, // HttpOverrides.global = MyHttpOverrides();
Orientation orientation, //
DeviceType deviceType, // runApp(
) { // EasyLocalization(
List<LocalizationsDelegate<dynamic>> delegates = context.localizationDelegates; // supportedLocales: const <Locale>[
// AppState().setPostParamsModel( // Locale('en', 'US'),
// PostParamsModel( // Locale('ar', 'SA'),
// languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, // ],
// ), // path: 'resources',
// ); // // assetLoader: const CodegenLoader(),
return MaterialApp( // child: const MyApp(),
// key: navigatorKey, // ),
navigatorKey: navigatorKey, // );
theme: AppTheme.getTheme( // }
isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar",
),
debugShowCheckedModeBanner: false,
localizationsDelegates: delegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
);
},
);
});
}
}
// class MyApp extends StatelessWidget { // class MyApp extends StatelessWidget {
// const MyApp({super.key}); // const MyApp({super.key});
@ -104,13 +43,9 @@ class MyApp extends StatelessWidget {
// DeviceType deviceType, // DeviceType deviceType,
// ) { // ) {
// List<LocalizationsDelegate<dynamic>> delegates = context.localizationDelegates; // List<LocalizationsDelegate<dynamic>> delegates = context.localizationDelegates;
// // AppState().setPostParamsModel(
// // PostParamsModel(
// // languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
// // ),
// // );
// return MaterialApp( // return MaterialApp(
// // key: navigatorKey, // // key: navigatorKey,
// navigatorKey: navigatorKey,
// theme: AppTheme.getTheme( // theme: AppTheme.getTheme(
// isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar", // isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar",
// ), // ),
@ -124,45 +59,9 @@ class MyApp extends StatelessWidget {
// }); // });
// } // }
// } // }
//
// // class MyApp extends StatelessWidget { // todo terminal command to genertate translation files
// // MyApp({super.key}) { // flutter pub run easy_localization:generate --source-dir ./assets/langs
// // AppDependencies.addDependencies(); // todo terminal command to genertate translation keys
// // AppState = Injector.appInstance.get<AppState>(); // flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart
// // // AppState.setPostParamsInitConfig(); // command to generate languages data from json
// // }
// //
// // @override
// // Widget build(BuildContext context) {
// // return LayoutBuilder(builder: (context, constraints) {
// // return Sizer(
// // builder: (
// // BuildContext context,
// // Orientation orientation,
// // DeviceType deviceType,
// // ) {
// // SizeConfig().init(constraints, orientation);
// // List<LocalizationsDelegate<dynamic>> delegates = context.localizationDelegates;
// // // AppState().setPostParamsModel(
// // // PostParamsModel(
// // // languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
// // // ),
// // // );
// // return MaterialApp(
// // // key: navigatorKey,
// // navigatorKey: navigatorKey,
// // theme: AppTheme.getTheme(
// // EasyLocalization.of(context)?.locale.languageCode == "ar",
// // ),
// // debugShowCheckedModeBanner: false,
// // localizationsDelegates: delegates,
// // supportedLocales: context.supportedLocales,
// // locale: context.locale,
// // initialRoute: AppRoutes.initialPage,
// // routes: AppRoutes.routes,
// // );
// // },
// // );
// // });
// // }
// // }

@ -44,6 +44,7 @@ class AdDetailsModel {
bool? isReservedByMe; bool? isReservedByMe;
String? phoneNo; String? phoneNo;
String? whatsAppNo; String? whatsAppNo;
String? adOwnerName;
CreatedByRoleEnum? createdByRoleEnum; CreatedByRoleEnum? createdByRoleEnum;
List<ChatMessageModel>? adMessages; List<ChatMessageModel>? adMessages;
@ -84,6 +85,7 @@ class AdDetailsModel {
this.isReservedByMe, this.isReservedByMe,
this.phoneNo, this.phoneNo,
this.whatsAppNo, this.whatsAppNo,
this.adOwnerName,
this.createdByRoleEnum, this.createdByRoleEnum,
this.modifiedOn, this.modifiedOn,
this.adMessages, this.adMessages,
@ -131,13 +133,11 @@ class AdDetailsModel {
reservePrice = json['reservePrice']; reservePrice = json['reservePrice'];
isMCHandled = json['isMCHandled']; isMCHandled = json['isMCHandled'];
modifiedOn = json['modifiedOn']; modifiedOn = json['modifiedOn'];
whatsAppNo = json['phoneNo']; phoneNo = json['phoneNo'];
modifiedOn = json['whatsAppNo']; whatsAppNo = json['whatsAppNo'];
// adPostStatus = AdPostStatus.expired; adOwnerName = json['adOwnerName'] ?? "";
adPostStatus = (json['statusID'] as int).toAdPostEnum(); adPostStatus = (json['statusID'] as int).toAdPostEnum();
//TODO: THIS ID SHOULD BE UPDATED!
adReserveStatus = AdReserveStatus.defaultStatus; adReserveStatus = AdReserveStatus.defaultStatus;
// createdByRoleEnum = CreatedByRoleEnum.admin;
createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum(); createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum();
isMyAd = isMyAds; isMyAd = isMyAds;
isReservedByMe = false; isReservedByMe = false;

@ -18,6 +18,11 @@ class SelectionModel {
this.selectedId = 0, this.selectedId = 0,
this.itemPrice = "", this.itemPrice = "",
}); });
@override
String toString() {
return 'SelectionModel{selectedOption: $selectedOption, selectedId: $selectedId, errorValue: $errorValue, itemPrice: $itemPrice}';
}
} }
class TimeSlotModel { class TimeSlotModel {

@ -19,12 +19,14 @@ class BranchDetailModel {
final String? closeTime; final String? closeTime;
final BranchStatusEnum? branchStatus; final BranchStatusEnum? branchStatus;
final int? statusId; final int? statusId;
final dynamic statusText; final String? statusText;
final double? branchRateAvg;
final List<ServiceModel>? branchServices; final List<ServiceModel>? branchServices;
List<CategoryData>? categories; List<CategoryData>? categories;
int? countryID; int? countryID;
String? countryName; String? countryName;
bool isExpanded; bool isExpanded;
bool? isFavorite;
BranchDetailModel({ BranchDetailModel({
this.id, this.id,
@ -41,17 +43,18 @@ class BranchDetailModel {
this.openTime, this.openTime,
this.closeTime, this.closeTime,
this.branchStatus, this.branchStatus,
this.branchRateAvg,
this.statusId, this.statusId,
this.statusText, this.statusText,
this.branchServices, this.branchServices,
this.categories, this.categories,
this.countryID, this.countryID,
this.countryName, this.countryName,
this.isFavorite,
required this.isExpanded, required this.isExpanded,
}); });
factory BranchDetailModel.fromJson(Map<String, dynamic> json) => factory BranchDetailModel.fromJson(Map<String, dynamic> json) => BranchDetailModel(
BranchDetailModel(
id: json["id"], id: json["id"],
serviceProviderId: json["serviceProviderID"], serviceProviderId: json["serviceProviderID"],
serviceProviderName: json["serviceProviderName"], serviceProviderName: json["serviceProviderName"],
@ -65,33 +68,13 @@ class BranchDetailModel {
distanceKm: json["distanceKM"]?.toDouble(), distanceKm: json["distanceKM"]?.toDouble(),
openTime: json["openTime"], openTime: json["openTime"],
closeTime: json["closeTime"], closeTime: json["closeTime"],
branchStatus: json.containsKey("branchStatus")?(json['branchStatus'] as int).toBranchStatusEnum():null, branchStatus: json.containsKey("branchStatus") ? (json['branchStatus'] as int).toBranchStatusEnum() : null,
statusId: json["branchStatus"], statusId: json["branchStatus"],
statusText: json["statusText"], statusText: json["statusText"],
branchServices: json["serviceProviderServices"] == null ? [] : List< branchRateAvg: json["branchRateAvg"],
ServiceModel>.from(json["serviceProviderServices"]!.map((x) => branchServices: json["serviceProviderServices"] == null ? [] : List<ServiceModel>.from(json["serviceProviderServices"]!.map((x) => ServiceModel.fromJson(x))),
ServiceModel.fromJson(x))),
categories: [], categories: [],
isExpanded: false, isExpanded: false,
isFavorite: false,
); );
Map<String, dynamic> toJson() =>
{
"id": id,
"serviceProviderID": serviceProviderId,
"serviceProviderName": serviceProviderName,
"branchName": branchName,
"branchDescription": branchDescription,
"cityID": cityId,
"address": address,
"latitude": latitude,
"longitude": longitude,
"distanceKM": distanceKm,
"openTime": openTime,
"closeTime": closeTime,
"status": statusId,
"statusText": statusText,
"serviceProviderServices": branchServices == null ? [] : List<
dynamic>.from(branchServices!.map((x) => x.toJson())),
};
} }

@ -0,0 +1,36 @@
class BranchRatingModel {
int? id;
String? title;
String? review;
int? ratNo;
int? serviceProviderBranchID;
String? serviceProviderBranchName;
int? customerID;
String? customerName;
BranchRatingModel({this.id, this.title, this.review, this.ratNo, this.serviceProviderBranchID, this.serviceProviderBranchName, this.customerID, this.customerName});
BranchRatingModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
review = json['review'];
ratNo = json['ratNo'];
serviceProviderBranchID = json['serviceProviderBranchID'];
serviceProviderBranchName = json['serviceProviderBranchName'];
customerID = json['customerID'];
customerName = json['customerName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['title'] = title;
data['review'] = review;
data['ratNo'] = ratNo;
data['serviceProviderBranchID'] = serviceProviderBranchID;
data['serviceProviderBranchName'] = serviceProviderBranchName;
data['customerID'] = customerID;
data['customerName'] = customerName;
return data;
}
}

@ -22,17 +22,17 @@ class Branch {
String? message; String? message;
factory Branch.fromJson(Map<String, dynamic> json) => Branch( factory Branch.fromJson(Map<String, dynamic> json) => Branch(
totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : List<BranchData>.from(json["data"].map((x) => BranchData.fromJson(x))), data: json["data"] == null ? null : List<BranchData>.from(json["data"].map((x) => BranchData.fromJson(x))),
messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], messageStatus: json["messageStatus"],
message: json["message"] == null ? null : json["message"], message: json["message"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"totalItemsCount": totalItemsCount == null ? null : totalItemsCount, "totalItemsCount": totalItemsCount,
"data": data == null ? null : List<dynamic>.from(data!.map((x) => x.toJson())), "data": data == null ? null : List<dynamic>.from(data!.map((x) => x.toJson())),
"messageStatus": messageStatus == null ? null : messageStatus, "messageStatus": messageStatus,
"message": message == null ? null : message, "message": message,
}; };
} }
@ -60,26 +60,26 @@ class BranchData {
int? status; int? status;
factory BranchData.fromJson(Map<String, dynamic> json) => BranchData( factory BranchData.fromJson(Map<String, dynamic> json) => BranchData(
id: json["id"] == null ? null : json["id"], id: json["id"],
serviceProviderId: json["serviceProviderID"] == null ? null : json["serviceProviderID"], serviceProviderId: json["serviceProviderID"],
branchName: json["branchName"] == null ? null : json["branchName"], branchName: json["branchName"],
branchDescription: json["branchDescription"] == null ? null : json["branchDescription"], branchDescription: json["branchDescription"],
cityId: json["cityID"] == null ? null : json["cityID"], cityId: json["cityID"],
address: json["address"] == null ? null : json["address"], address: json["address"],
latitude: json["latitude"] == null ? null : json["latitude"], latitude: json["latitude"],
longitude: json["longitude"] == null ? null : json["longitude"], longitude: json["longitude"],
status: json["status"] == null ? null : json["status"], status: json["status"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id == null ? null : id, "id": id,
"serviceProviderID": serviceProviderId == null ? null : serviceProviderId, "serviceProviderID": serviceProviderId,
"branchName": branchName == null ? null : branchName, "branchName": branchName,
"branchDescription": branchDescription == null ? null : branchDescription, "branchDescription": branchDescription,
"cityID": cityId == null ? null : cityId, "cityID": cityId,
"address": address == null ? null : address, "address": address,
"latitude": latitude == null ? null : latitude, "latitude": latitude,
"longitude": longitude == null ? null : longitude, "longitude": longitude,
"status": status == null ? null : status, "status": status,
}; };
} }

@ -8,8 +8,6 @@ import 'package:mc_common_app/models/provider_branches_models/branch_detail_mode
ProviderModel branch2FromJson(String str) => ProviderModel.fromJson(json.decode(str)); ProviderModel branch2FromJson(String str) => ProviderModel.fromJson(json.decode(str));
String branch2ToJson(ProviderModel data) => json.encode(data.toJson());
class ProviderModel { class ProviderModel {
ProviderModel({ ProviderModel({
this.messageStatus, this.messageStatus,
@ -29,13 +27,6 @@ class ProviderModel {
data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]), data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]),
message: json["message"], message: json["message"],
); );
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? null : data!.toJson(),
"message": message,
};
} }
class ProviderModelData { class ProviderModelData {
@ -72,16 +63,6 @@ class ProviderModelData {
userId: json["userID"], userId: json["userID"],
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))), serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
); );
Map<String, dynamic> toJson() => {
"id": id,
"companyName": companyName,
"companyDescription": companyDescription,
"allDocStatus": allDocStatus,
"isValidSubscription": isValidSubscription,
"userID": userId,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x.toJson())),
};
} }
class ProviderBasicDataModel { class ProviderBasicDataModel {

@ -1,10 +1,5 @@
// To parse this JSON data, do
//
// final branch2 = branch2FromJson(jsonString);
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
class ProviderProfileModel { class ProviderProfileModel {
ProviderProfileModel({ ProviderProfileModel({
this.id, this.id,
@ -16,6 +11,7 @@ class ProviderProfileModel {
this.userId, this.userId,
this.serviceProviderBranch, this.serviceProviderBranch,
this.countryID, this.countryID,
this.isFavorite,
}); });
final int? id; final int? id;
@ -25,10 +21,12 @@ class ProviderProfileModel {
final String? companyDescription; final String? companyDescription;
final int? allDocStatus; final int? allDocStatus;
final bool? isValidSubscription; final bool? isValidSubscription;
final bool? isFavorite;
final String? userId; final String? userId;
final List<BranchDetailModel>? serviceProviderBranch; final List<BranchDetailModel>? serviceProviderBranch;
factory ProviderProfileModel.fromJson(Map<String, dynamic> json) => ProviderProfileModel( factory ProviderProfileModel.fromJson(Map<String, dynamic> json) =>
ProviderProfileModel(
id: json["id"], id: json["id"],
companyName: json["companyName"], companyName: json["companyName"],
countryName: json["countryName"], countryName: json["countryName"],
@ -37,17 +35,7 @@ class ProviderProfileModel {
allDocStatus: json["allDocStatus"], allDocStatus: json["allDocStatus"],
isValidSubscription: json["isValidSubscription"], isValidSubscription: json["isValidSubscription"],
userId: json["userID"], userId: json["userID"],
isFavorite: json["isFavorite"] ?? false,
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))), serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
); );
Map<String, dynamic> toJson() => {
"id": id,
"companyName": companyName,
"companyDescription": companyDescription,
"allDocStatus": allDocStatus,
"isValidSubscription": isValidSubscription,
"userID": userId,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x.toJson())),
};
} }

@ -86,7 +86,7 @@ class RequestModel {
cityName: json["cityName"], cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"], vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"], countryName: json["countryName"],
customerName: json["customerName"], customerName: json["customerName"] ?? "",
customerID: json["customerUserID"], customerID: json["customerUserID"],
serviceProviders: json["serviceProviders"], serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"], offerCount: json["offerCount"],

@ -49,6 +49,8 @@ abstract class AppointmentRepo {
Future<GenericRespModel> createServiceAppointment({required List<ServiceAppointmentScheduleModel> schedules, required int serviceProviderID}); Future<GenericRespModel> createServiceAppointment({required List<ServiceAppointmentScheduleModel> schedules, required int serviceProviderID});
Future<GenericRespModel> cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction}); Future<GenericRespModel> cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction});
Future<GenericRespModel> addProviderToFavourite({required int providerID});
} }
class AppointmentRepoImp implements AppointmentRepo { class AppointmentRepoImp implements AppointmentRepo {
@ -250,4 +252,17 @@ class AppointmentRepoImp implements AppointmentRepo {
String t = appState.getUser.data!.accessToken ?? ""; String t = appState.getUser.data!.accessToken ?? "";
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createMergeAppointment, map, token: t); return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createMergeAppointment, map, token: t);
} }
@override
Future<GenericRespModel> addProviderToFavourite({required int providerID}) async {
final customerID = appState.getUser.data!.userInfo!.customerId;
final parameters = {"providerID": providerID, "customerID": customerID};
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.createBranchRatings,
parameters,
token: appState.getUser.data!.accessToken,
);
return adsGenericModel;
}
} }

@ -9,6 +9,7 @@ import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/branch.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/branch.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
@ -73,6 +74,12 @@ abstract class BranchRepo {
double? latitude, double? latitude,
double? longitude, double? longitude,
}); });
Future<List<BranchDetailModel>> getMyRecentBranchesWithServices();
Future<List<BranchRatingModel>> getBranchRatings({required int serviceProviderBranchID});
Future<GenericRespModel> submitBranchRatings({required int serviceProviderBranchID, required String title, required String review, required double ratingNo});
} }
class BranchRepoImp implements BranchRepo { class BranchRepoImp implements BranchRepo {
@ -273,6 +280,13 @@ class BranchRepoImp implements BranchRepo {
return nearBranches; return nearBranches;
} }
@override
Future<List<BranchDetailModel>> getMyRecentBranchesWithServices() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.getMyRecentBranches, token: appState.getUser.data!.accessToken);
List<BranchDetailModel> recentBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
return recentBranches;
}
@override @override
Future<List<ItemData>> getServiceItems(int serviceId) async { Future<List<ItemData>> getServiceItems(int serviceId) async {
var queryParameters = { var queryParameters = {
@ -345,4 +359,31 @@ class BranchRepoImp implements BranchRepo {
List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index])); List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
return nearBranches; return nearBranches;
} }
@override
Future<List<BranchRatingModel>> getBranchRatings({required int serviceProviderBranchID}) async {
var postParams = {"ServiceProviderBranchID": serviceProviderBranchID.toString()};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getBranchRatings,
token: appState.getUser.data!.accessToken,
queryParameters: postParams,
);
List<BranchRatingModel> branchRatings = List.generate(adsGenericModel.data.length, (index) => BranchRatingModel.fromJson(adsGenericModel.data[index]));
return branchRatings;
}
@override
Future<GenericRespModel> submitBranchRatings({required int serviceProviderBranchID, required String title, required String review, required double ratingNo}) async {
final customerID = appState.getUser.data!.userInfo!.customerId;
final parameters = {"title": title, "review": review, "ratNo": ratingNo, "serviceProviderBranchID": serviceProviderBranchID, "customerID": "$customerID"};
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.createBranchRatings,
parameters,
token: appState.getUser.data!.accessToken,
);
return adsGenericModel;
}
} }

@ -16,7 +16,9 @@ abstract class RequestRepo {
Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId}); Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId});
Future<List<RequestModel>> getRequests(Map<String, dynamic> postParams); Future<List<RequestModel>> getRequests({required int providerOrCustomerID});
Future<List<RequestModel>> getServiceRequestsForProviders({required int serviceProviderID});
Future<GenericRespModel> updateOfferRequestStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}); Future<GenericRespModel> updateOfferRequestStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments});
} }
@ -37,11 +39,21 @@ class RequestRepoImp implements RequestRepo {
} }
@override @override
Future<List<RequestModel>> getRequests(Map<String, dynamic> postParams) async { Future<List<RequestModel>> getRequests({required int providerOrCustomerID}) async {
final paramsForGetRequests = {
"pageSize": 100,
"pageIndex": 0,
};
if (AppState().currentAppType == AppType.provider) {
paramsForGetRequests.addEntries([MapEntry("providerID", providerOrCustomerID)]);
} else {
paramsForGetRequests.addEntries([MapEntry("customerID", providerOrCustomerID)]);
}
GenericRespModel enumGenericModel = await apiClient.postJsonForObject( GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.getRequest, ApiConsts.getRequest,
postParams, paramsForGetRequests,
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
); );
List<RequestModel> requests = List.generate( List<RequestModel> requests = List.generate(
@ -53,6 +65,26 @@ class RequestRepoImp implements RequestRepo {
return requests; return requests;
} }
@override
Future<List<RequestModel>> getServiceRequestsForProviders({required int serviceProviderID}) async {
final parameters = {
"ServiceProviderId": serviceProviderID.toString(),
};
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getServiceRequestsForProvider,
queryParameters: parameters,
token: appState.getUser.data!.accessToken,
);
List<RequestModel> requests = List.generate(
genericRespModel.data.length,
(index) => RequestModel.fromJson(
genericRespModel.data[index],
),
);
return requests;
}
@override @override
Future<List<OffersModel>> getOffersByRequest({required int requestId, int serviceProviderId = 0}) async { Future<List<OffersModel>> getOffersByRequest({required int requestId, int serviceProviderId = 0}) async {
var queryParameters = { var queryParameters = {

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
class MyColors { class MyColors {
static const Color darkPrimaryColor = Color(0xffF47F20); static const Color darkPrimaryColor = Color(0xffF47F20);
static const Color primaryColor = Color(0xffF69521); static const Color primaryColor = Color(0xffF69521);
static const Color lightPrimaryColor = Color(0xffFFD077);
static const Color accentColor = Colors.blue; static const Color accentColor = Colors.blue;
static const Color lightTextColor = Color(0xff969696); static const Color lightTextColor = Color(0xff969696);
static const Color textColor = Color(0xff777777); static const Color textColor = Color(0xff777777);
@ -38,6 +39,7 @@ class MyColors {
static const Color borderColor = Color(0xffE8E8E8); static const Color borderColor = Color(0xffE8E8E8);
static const Color greyAddBorderColor = Color(0xffEEEEEE); static const Color greyAddBorderColor = Color(0xffEEEEEE);
static const Color lightGreyBgColor = Color(0xffFDFDFD); static const Color lightGreyBgColor = Color(0xffFDFDFD);
static const Color lightGreyDDColor = Color(0xffDDDDDD);
//AdStatusColors: //AdStatusColors:
static const Color adActiveStatusColor = Color(0xff5FC16A); static const Color adActiveStatusColor = Color(0xff5FC16A);

@ -175,8 +175,7 @@ class AdVM extends BaseVM {
if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) { if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) {
return; return;
} }
log("myAdsEnums: ${myAdsEnums.length}");
log("exploreAdsEnums: ${exploreAdsEnums.length}");
if (myAdsEnums.isEmpty) { if (myAdsEnums.isEmpty) {
myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.myAdsFilterEnumId); myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.myAdsFilterEnumId);
} }
@ -196,8 +195,6 @@ class AdVM extends BaseVM {
} }
exploreAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0)); exploreAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0));
logger.i("myAdsEnums: ${myAdsEnums.length}");
logger.i("exploreAdsEnums: ${exploreAdsEnums.length}");
notifyListeners(); notifyListeners();
} }
@ -409,6 +406,7 @@ class AdVM extends BaseVM {
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId); vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId);
isFetchingLists = false; isFetchingLists = false;
notifyListeners(); notifyListeners();
} }
@ -497,7 +495,6 @@ class AdVM extends BaseVM {
return; return;
} }
vehicleBrandId = id; vehicleBrandId = id;
logger.i("message: ${vehicleBrandId.selectedOption}");
await getVehicleDetailsByVehicleBrandId(); await getVehicleDetailsByVehicleBrandId();
notifyListeners(); notifyListeners();
@ -1210,7 +1207,7 @@ class AdVM extends BaseVM {
vehicleAdsSpecialServices.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: ""); // vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
@ -1221,7 +1218,6 @@ class AdVM extends BaseVM {
vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
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: "");
vehicleDemandAmount = ""; vehicleDemandAmount = "";
vehicleVin = ""; vehicleVin = "";
vehicleTitle = ""; vehicleTitle = "";
@ -1679,11 +1675,13 @@ class AdVM extends BaseVM {
///// Edit Work Amir ///// Edit Work Amir
void onEditUpdateAdPressed(BuildContext context, AdDetailsModel previousDetails) { void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) {
isAdEditEnabled = true; isAdEditEnabled = true;
previousAdDetails = previousDetails; previousAdDetails = previousDetails;
autoFillSelectedVehicleType(); autoFillSelectedVehicleType();
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: AppState().currentAppType == AppType.provider ? true : false); autoFillSelectedVehicleAdsDuration();
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd]);
} }
autoFillSelectedVehicleType() async { autoFillSelectedVehicleType() async {
@ -1707,6 +1705,7 @@ class AdVM extends BaseVM {
await getVehicleAdsDuration(); await getVehicleAdsDuration();
} }
if (vehicleAdsDurations.isNotEmpty) { if (vehicleAdsDurations.isNotEmpty) {
// TODO: FOR THE PROVIDER, THIS CHECK WILL NOT WORK. BECAUSE IN CASE OF PROVIDER,THE PRICE WILL ALWAYS BE 0.0. Have to get ads duration ID from API in previousAd Details
int index = vehicleAdsDurations.indexWhere((element) => element.price == previousAdDetails!.adsDurationPrice!); int index = vehicleAdsDurations.indexWhere((element) => element.price == previousAdDetails!.adsDurationPrice!);
if (index != -1) { if (index != -1) {
updateVehicleAdDurationId( updateVehicleAdDurationId(
@ -1743,13 +1742,12 @@ class AdVM extends BaseVM {
updateSelectionVehicleColorId(SelectionModel(selectedId: previousAdDetails!.vehicle!.color!.id!, selectedOption: previousAdDetails!.vehicle!.color!.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 ?? "")); updateSelectionVehicleConditionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.condition!.id!, selectedOption: previousAdDetails!.vehicle!.condition!.label ?? ""));
updateSelectionVehicleCategoryId(SelectionModel(selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: previousAdDetails!.vehicle!.category!.label ?? "")); updateSelectionVehicleCategoryId(SelectionModel(selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: previousAdDetails!.vehicle!.category!.label ?? ""));
updateSelectionVehicleMileageId(SelectionModel( updateSelectionVehicleMileageId(SelectionModel(selectedId: previousAdDetails!.vehicle!.mileage!.id!, selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}"));
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 ?? "")); updateSelectionVehicleTransmissionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.transmission!.id!, selectedOption: previousAdDetails!.vehicle!.transmission!.label ?? ""));
updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: previousAdDetails!.vehicle!.sellertype!.id!, selectedOption: previousAdDetails!.vehicle!.sellertype!.label ?? "")); updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: previousAdDetails!.vehicle!.sellertype!.id!, selectedOption: previousAdDetails!.vehicle!.sellertype!.label ?? ""));
int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID); int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID);
if (indexCountry != -1) { if (indexCountry != -1) {
updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[index].id!, selectedOption: vehicleCountries[index].countryName ?? "")); updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[indexCountry].id!, selectedOption: vehicleCountries[indexCountry].countryName ?? ""));
} }
updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? "")); updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? ""));
@ -1759,6 +1757,7 @@ class AdVM extends BaseVM {
vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString(); vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString();
financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false; financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
pickedPostingImages.clear();
if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) { if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
for (var element in previousAdDetails!.vehicle!.image!) { for (var element in previousAdDetails!.vehicle!.image!) {
if (element.imageUrl != null) { if (element.imageUrl != null) {
@ -1815,7 +1814,6 @@ class AdVM extends BaseVM {
} }
isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null; isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null;
logger.i("previousAdDetails!: $previousAdDetails");
notifyListeners(); notifyListeners();
} }
@ -1846,10 +1844,9 @@ class AdVM extends BaseVM {
adsChatBuyerId: 1, adsChatBuyerId: 1,
adID: adDetailsModel.id, adID: adDetailsModel.id,
userID: myUserID, userID: myUserID,
senderName: adDetailsModel.adOwnerName,
) )
.whenComplete( .whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments),
);
} }
} }

@ -15,6 +15,7 @@ import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/general_models/m_response.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/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
@ -161,7 +162,7 @@ class AppointmentsVM extends BaseVM {
} }
} }
} catch (e) { } catch (e) {
Utils.showToast("${e.toString()}"); Utils.showToast(e.toString());
} }
} }
@ -238,7 +239,9 @@ class AppointmentsVM extends BaseVM {
} }
void removeServiceInCurrentAppointment(int index) { void removeServiceInCurrentAppointment(int index) {
int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1; int serviceId = servicesInCurrentAppointment
.elementAt(index)
.serviceProviderServiceId ?? -1;
allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId); allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId);
servicesInCurrentAppointment.removeAt(index); servicesInCurrentAppointment.removeAt(index);
notifyListeners(); notifyListeners();
@ -382,9 +385,7 @@ class AppointmentsVM extends BaseVM {
} }
} }
Future<void> getMyAppointmentsForProvider( Future<void> getMyAppointmentsForProvider(Map<String, dynamic> map) async {
Map<String, dynamic> map,
) async {
setState(ViewState.busy); setState(ViewState.busy);
myAppointments = await appointmentRepo.getMyAppointmentsForProvider(map); myAppointments = await appointmentRepo.getMyAppointmentsForProvider(map);
myFilteredAppointments = myAppointments; myFilteredAppointments = myAppointments;
@ -434,7 +435,7 @@ class AppointmentsVM extends BaseVM {
updateCheckBoxInMergeRequest(int currentIndex) { updateCheckBoxInMergeRequest(int currentIndex) {
myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected = myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected =
!(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false); !(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false);
int count = countSelected(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList ?? []); int count = countSelected(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList ?? []);
if (count > 1) if (count > 1)
@ -445,7 +446,10 @@ class AppointmentsVM extends BaseVM {
} }
int countSelected(List<AppointmentListModel> appointments) { int countSelected(List<AppointmentListModel> appointments) {
return appointments.where((appointment) => appointment.isSelected == true).toList().length; return appointments
.where((appointment) => appointment.isSelected == true)
.toList()
.length;
} }
updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) { updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) {
@ -531,6 +535,7 @@ class AppointmentsVM extends BaseVM {
} }
Future<List<ItemData>> getServiceItems(int serviceId) async { Future<List<ItemData>> getServiceItems(int serviceId) async {
setState(ViewState.busy);
serviceItemsFromApi.clear(); serviceItemsFromApi.clear();
serviceItemsFromApi = await branchRepo.getServiceItems(serviceId); serviceItemsFromApi = await branchRepo.getServiceItems(serviceId);
for (var item in serviceItemsFromApi) { for (var item in serviceItemsFromApi) {
@ -612,13 +617,14 @@ class AppointmentsVM extends BaseVM {
Column( Column(
children: List.generate( children: List.generate(
selectedService.serviceItems!.length, selectedService.serviceItems!.length,
(index) => Row( (index) =>
mainAxisAlignment: MainAxisAlignment.spaceBetween, Row(
children: [ mainAxisAlignment: MainAxisAlignment.spaceBetween,
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), children: [
"${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true), "${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
], "${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true),
), ],
),
), ),
), ),
Row( Row(
@ -654,8 +660,8 @@ class AppointmentsVM extends BaseVM {
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
(selectedService.isHomeSelected (selectedService.isHomeSelected
? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}" ? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}"
: "${selectedService.currentTotalServicePrice}") : "${selectedService.currentTotalServicePrice}")
.toText(fontSize: 29, isBold: true), .toText(fontSize: 29, isBold: true),
2.width, 2.width,
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
@ -810,19 +816,6 @@ class AppointmentsVM extends BaseVM {
List<ServiceModel> branchServices = []; List<ServiceModel> branchServices = [];
// populateBranchesFilterList() {
// branchesFilterOptions.clear(); // TODO: THIS SHOULD BE DYNAMIC AND FILTERS SHOULD COME FORM API
// branchesFilterOptions = [
// FilterListModel(title: "All Branches", isSelected: true, id: 0),
// FilterListModel(title: "Maintenance", isSelected: false, id: 1),
// FilterListModel(title: "Oil Service", isSelected: false, id: 2),
// FilterListModel(title: "Accessories", isSelected: false, id: 3),
// FilterListModel(title: "Tire Service", isSelected: false, id: 4),
// FilterListModel(title: "Dent and Paint", isSelected: false, id: 5),
// ];
// notifyListeners();
// }
Future<void> populateBranchesFilterList() async { Future<void> populateBranchesFilterList() async {
if (branchesFilterOptions.isNotEmpty) return; if (branchesFilterOptions.isNotEmpty) return;
branchesFilterOptions.clear(); branchesFilterOptions.clear();
@ -853,7 +846,7 @@ class AppointmentsVM extends BaseVM {
Future<void> getMyRecentBranches({bool isNeedToRebuild = false}) async { Future<void> getMyRecentBranches({bool isNeedToRebuild = false}) async {
myRecentBranches.clear(); myRecentBranches.clear();
if (isNeedToRebuild) setState(ViewState.busy); if (isNeedToRebuild) setState(ViewState.busy);
myRecentBranches = await branchRepo.getAllNearBranchAndServices(); myRecentBranches = await branchRepo.getMyRecentBranchesWithServices();
setState(ViewState.idle); setState(ViewState.idle);
} }
@ -1086,10 +1079,10 @@ class AppointmentsVM extends BaseVM {
DropValue( DropValue(
element.id ?? 0, element.id ?? 0,
((element.categoryName!.isEmpty ((element.categoryName!.isEmpty
? "N/A" ? "N/A"
: countryCode == "SA" : countryCode == "SA"
? element.categoryNameN ? element.categoryNameN
: element.categoryName) ?? : element.categoryName) ??
"N/A"), "N/A"),
""), ""),
); );
@ -1433,4 +1426,33 @@ class AppointmentsVM extends BaseVM {
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
setState(ViewState.idle); setState(ViewState.idle);
} }
Future<void> addProviderToFavorite({required String serviceProviderID}) async {
setState(ViewState.busy);
}
List<BranchRatingModel> currentBranchReviews = [];
bool isReadMoreEnabled = false;
void resetCurrentBranchRatings() {
currentBranchReviews.clear();
isReadMoreEnabled = false;
}
updateIsReadMoreEnabled(var value) {
isReadMoreEnabled = value;
notifyListeners();
}
Future<void> getReviewsByBranchId({required int serviceProviderBranchID}) async {
setState(ViewState.busy);
try {
currentBranchReviews = await branchRepo.getBranchRatings(serviceProviderBranchID: serviceProviderBranchID);
} catch (e, s) {
logger.e(s);
setState(ViewState.idle);
Utils.showToast(e.toString());
}
setState(ViewState.idle);
}
} }

@ -446,7 +446,6 @@ class ChatVM extends ChangeNotifier {
return false; return false;
}); });
} }
return true; return true;
} }
@ -454,7 +453,7 @@ class ChatVM extends ChangeNotifier {
List<ChatMessageModel> currentMessagesForAds = []; List<ChatMessageModel> currentMessagesForAds = [];
Future<void> getUsersChatMessagesForAd({required BuildContext context, int? adID, int? adsChatBuyerId, String? userID, required bool isForBuyer}) async { Future<void> getUsersChatMessagesForAd({required BuildContext context, int? adID, int? adsChatBuyerId, String? userID, String? senderName, required bool isForBuyer}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
currentMessagesForAds = await chatRepo.getUsersChatMessagesForAds(userID: userID, adID: adID, isForBuyer: isForBuyer, adsChatBuyerId: adsChatBuyerId); currentMessagesForAds = await chatRepo.getUsersChatMessagesForAds(userID: userID, adID: adID, isForBuyer: isForBuyer, adsChatBuyerId: adsChatBuyerId);
@ -463,6 +462,7 @@ class ChatVM extends ChangeNotifier {
List<int> unreadMessageIds = []; List<int> unreadMessageIds = [];
for (var msg in currentMessagesForAds) { for (var msg in currentMessagesForAds) {
msg.senderName = senderName ?? "";
if (!msg.isRead!) { if (!msg.isRead!) {
unreadMessageIds.add(msg.id!); unreadMessageIds.add(msg.id!);
} }

@ -64,27 +64,26 @@ class RequestsVM extends BaseVM {
Future<void> getRequests({bool isNeedToRebuild = false, required AppType appType}) async { Future<void> getRequests({bool isNeedToRebuild = false, required AppType appType}) async {
if (isNeedToRebuild) setState(ViewState.busy); if (isNeedToRebuild) setState(ViewState.busy);
var paramsForGetRequests = <String, dynamic>{}; int providerOrCustomerID = 0;
paramsForGetRequests = {
"pageSize": 100,
"pageIndex": 0,
// "requestType": 0,
};
if (appType == AppType.provider) { if (appType == AppType.provider) {
paramsForGetRequests.addEntries([MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)]); providerOrCustomerID = AppState().getUser.data!.userInfo!.providerId ?? 0;
} else { } else {
paramsForGetRequests.addEntries([MapEntry("customerID", AppState().getUser.data!.userInfo!.customerId)]); providerOrCustomerID = AppState().getUser.data!.userInfo!.customerId ?? 0;
} }
myRequests = await requestRepo.getRequests(paramsForGetRequests); myRequests = await requestRepo.getRequests(providerOrCustomerID: providerOrCustomerID);
applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest); applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest);
setState(ViewState.idle); setState(ViewState.idle);
notifyListeners(); notifyListeners();
} }
Future<List<RequestModel>> getServiceRequestsForProviders() async {
setState(ViewState.busy);
List<RequestModel> serviceRequestsForProviders = await requestRepo.getServiceRequestsForProviders(serviceProviderID: AppState().getUser.data!.userInfo!.providerId);
setState(ViewState.idle);
return serviceRequestsForProviders;
}
addChatMessagesInRequestsModel({required ChatMessageModel msg, required int index}) { addChatMessagesInRequestsModel({required ChatMessageModel msg, required int index}) {
log("msg: $msg");
log("index: $index");
myFilteredRequests[index].chatMessages.add(msg); myFilteredRequests[index].chatMessages.add(msg);
notifyListeners(); notifyListeners();
} }
@ -102,12 +101,16 @@ class RequestsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
applyFilterOnRequestsVM({required RequestsTypeEnum requestsTypeEnum}) { applyFilterOnRequestsVM({required RequestsTypeEnum requestsTypeEnum}) async {
if (requestsTypeFilterOptions.isEmpty) return; if (requestsTypeFilterOptions.isEmpty) return;
for (var value in requestsTypeFilterOptions) { for (var value in requestsTypeFilterOptions) {
value.isSelected = false; value.isSelected = false;
} }
requestsTypeFilterOptions[requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1].isSelected = true; // -1 to match with the index requestsTypeFilterOptions[requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1].isSelected = true; // -1 to match with the index
if (AppState().currentAppType == AppType.provider && requestsTypeEnum == RequestsTypeEnum.serviceRequest) {
myFilteredRequests = await getServiceRequestsForProviders();
return;
}
myFilteredRequests = myRequests.where((element) => element.requestType == requestsTypeEnum.getIdFromRequestTypeStatusEnum()).toList(); myFilteredRequests = myRequests.where((element) => element.requestType == requestsTypeEnum.getIdFromRequestTypeStatusEnum()).toList();
notifyListeners(); notifyListeners();
} }

@ -5,12 +5,11 @@ 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/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.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';
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/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_special_service_sheet.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/widgets/common_widgets/custom_add_button_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package: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 +19,7 @@ import 'package:easy_localization/easy_localization.dart';
class AdDuration extends StatelessWidget { class AdDuration extends StatelessWidget {
const AdDuration({Key? key}) : super(key: key); const AdDuration({Key? key}) : super(key: key);
void onAddServiceButtonTapped(BuildContext context, AdVM adVM) { void onAddSpecialServiceButtonTapped(BuildContext context, AdVM adVM) {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
@ -228,7 +227,7 @@ class AdDuration extends StatelessWidget {
needsBorder: true, needsBorder: true,
bgColor: MyColors.white, bgColor: MyColors.white,
onTap: () { onTap: () {
onAddServiceButtonTapped(context, adVM); onAddSpecialServiceButtonTapped(context, adVM);
}, },
text: LocaleKeys.addService.tr(), text: LocaleKeys.addService.tr(),
icon: Container( icon: Container(

@ -4,7 +4,7 @@ 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/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/picked_images_container.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.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';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -78,7 +78,7 @@ class VehicleDetailsReview extends StatelessWidget {
16.height, 16.height,
SingleDetailWidget(text: adVM.vehicleVin, type: LocaleKeys.vehicleVIN.tr()), SingleDetailWidget(text: adVM.vehicleVin, type: LocaleKeys.vehicleVIN.tr()),
16.height, 16.height,
SingleDetailWidget(text: ("${adVM.warrantyDuration} "+ LocaleKeys.years.tr()), type: LocaleKeys.warrantyAvailable.tr()), SingleDetailWidget(text: ("${adVM.warrantyDuration} ${LocaleKeys.years.tr()}"), type: LocaleKeys.warrantyAvailable.tr()),
16.height, 16.height,
], ],
), ),
@ -111,7 +111,7 @@ class VehicleDetailsReview extends StatelessWidget {
), ),
SingleDetailWidget(text: adVM.vehicleDescription, type: LocaleKeys.description.tr()), SingleDetailWidget(text: adVM.vehicleDescription, type: LocaleKeys.description.tr()),
8.height, 8.height,
(LocaleKeys.vehiclePictures.tr() + ":").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), ("${LocaleKeys.vehiclePictures.tr()}:").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
if (adVM.pickedPostingImages.isNotEmpty) ...[ if (adVM.pickedPostingImages.isNotEmpty) ...[
// 10.height, // 10.height,
PickedFilesContainer( PickedFilesContainer(
@ -142,7 +142,7 @@ class DamagePartsReview extends StatelessWidget {
], ],
), ),
if (adVM.vehicleDamageCards[index].partImages != null && adVM.vehicleDamageCards[index].partImages!.isNotEmpty) ...[ if (adVM.vehicleDamageCards[index].partImages != null && adVM.vehicleDamageCards[index].partImages!.isNotEmpty) ...[
(LocaleKeys.damagePartPictures.tr() + ":").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), ("${LocaleKeys.damagePartPictures.tr()}:").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
PickedFilesContainer( PickedFilesContainer(
pickedFiles: adVM.vehicleDamageCards[index].partImages!, pickedFiles: adVM.vehicleDamageCards[index].partImages!,
onCrossPressedPrimary: adVM.removeImageFromList, onCrossPressedPrimary: adVM.removeImageFromList,

@ -5,10 +5,9 @@ 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/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/bottom_sheet_content.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_damage_parts_selection_sheet.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/views/advertisement/network_images_container.dart'; import 'package:mc_common_app/widgets/common_widgets/custom_add_button_widget.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';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -32,7 +31,7 @@ class DamageParts extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return const BottomSheetListContent(); return const AdDamagePartsSelectionSheet();
}); });
} }
@ -131,7 +130,6 @@ class DamageParts extends StatelessWidget {
], ],
).paddingOnly(right: 10) ).paddingOnly(right: 10)
], ],
], ],
).toWhiteContainer( ).toWhiteContainer(
width: double.infinity, width: double.infinity,

@ -8,8 +8,8 @@ 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/components/network_images_container_widget.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.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';

@ -1,95 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:provider/provider.dart';
class AdsBuyerChatsListView extends StatelessWidget {
final List<BuyersChatForAdsModel> buyersListViewArguments;
const AdsBuyerChatsListView({super.key, required this.buyersListViewArguments});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.chat.tr()),
body: buyersListViewArguments.isEmpty
? Center(child: LocaleKeys.noOffersShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
: ListView.separated(
itemCount: buyersListViewArguments.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
BuyersChatForAdsModel chatForAdsModel = buyersListViewArguments[index];
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(chatForAdsModel.buyerName ?? "").toText(fontSize: 16, isBold: true),
if (chatForAdsModel.unReadMessagesCount != null && chatForAdsModel.unReadMessagesCount! > 0) ...[
Center(
child: "${chatForAdsModel.unReadMessagesCount ?? "1"}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
),
).toContainer(
backgroundColor: MyColors.redColor,
borderRadius: 100,
paddingAll: 1,
width: 22,
height: 22,
),
]
],
),
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
(chatForAdsModel.lastMessage ?? "").toText(color: MyColors.lightTextColor, fontSize: 12),
],
),
if (chatForAdsModel.lastMessageDateTime != null) ...[
DateTime.parse(chatForAdsModel.lastMessageDateTime!).getTimeAgo().toText(color: MyColors.lightTextColor),
],
// const Icon(
// Icons.arrow_forward,
// color: MyColors.darkIconColor,
// size: 18,
// ),
],
),
],
).onPress(() async {
ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: chatForAdsModel.buyerUserID, adsID: chatForAdsModel.adsID);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd);
final chatVM = context.read<ChatVM>();
await chatVM.getUsersChatMessagesForAd(context: context, isForBuyer: false, adsChatBuyerId: chatForAdsModel.id).whenComplete(
() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments),
);
}).toContainer(isShadowEnabled: true);
},
separatorBuilder: (context, index) => 16.height,
),
);
}
}

@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
class AdsBuyerChatsView extends StatelessWidget {
final List<BuyersChatForAdsModel> buyersListViewArguments;
const AdsBuyerChatsView({super.key, required this.buyersListViewArguments});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.chat.tr()),
body: buyersListViewArguments.isEmpty
? Center(child: LocaleKeys.noOffersShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
: ListView.separated(
itemCount: buyersListViewArguments.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
BuyersChatForAdsModel chatForAdsModel = buyersListViewArguments[index];
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
MyAssets.bnCar,
width: 34,
height: 34,
fit: BoxFit.fill,
).toCircle(borderRadius: 100),
SizedBox(width: 2.w),
Expanded(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(chatForAdsModel.buyerName ?? "").toText(fontSize: 16, isBold: true),
if (chatForAdsModel.unReadMessagesCount != null && chatForAdsModel.unReadMessagesCount! > 0) ...[
Center(
child: "${chatForAdsModel.unReadMessagesCount ?? "1"}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
),
).toContainer(
backgroundColor: MyColors.redColor,
borderRadius: 100,
paddingAll: 1,
width: 22,
height: 22,
),
]
],
),
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: ("${chatForAdsModel.lastMessage}").toText(color: MyColors.lightTextColor, fontSize: 12)),
SizedBox(width: 5.w),
if (chatForAdsModel.lastMessageDateTime != null) ...[
DateTime.parse(chatForAdsModel.lastMessageDateTime!).getTimeAgo().toText(color: MyColors.lightTextColor),
],
],
),
2.height,
const Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(
Icons.arrow_forward,
color: MyColors.darkIconColor,
size: 18,
),
],
)
],
),
),
],
),
],
).onPress(() async {
ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: chatForAdsModel.buyerUserID, adsID: chatForAdsModel.adsID);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd);
final chatVM = context.read<ChatVM>();
await chatVM
.getUsersChatMessagesForAd(context: context, isForBuyer: false, adsChatBuyerId: chatForAdsModel.id, senderName: chatForAdsModel.buyerName)
.whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
}).toContainer(isShadowEnabled: true);
},
separatorBuilder: (context, index) => 16.height,
),
);
}
}

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
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/config/routes.dart';
@ -15,9 +16,10 @@ 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/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/bottom_sheets/ad_duration_selection_sheet.dart';
import 'package:mc_common_app/views/advertisement/ads_images_slider.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart'; import 'package:mc_common_app/views/advertisement/components/ads_images_corousel_widget.dart';
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.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';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
@ -41,12 +43,15 @@ class AdsDetailView extends StatefulWidget {
class _AdsDetailViewState extends State<AdsDetailView> { class _AdsDetailViewState extends State<AdsDetailView> {
late AdVM adVM; late AdVM adVM;
late List<VehicleDamageCard> damagePartsPictures;
@override @override
void initState() { void initState() {
adVM = context.read<AdVM>(); adVM = context.read<AdVM>();
damagePartsPictures = [];
scheduleMicrotask(() { scheduleMicrotask(() {
onAdDetailsLoaded(); onAdDetailsLoaded();
populateDamagePartPictures();
}); });
super.initState(); super.initState();
} }
@ -58,6 +63,24 @@ class _AdsDetailViewState extends State<AdsDetailView> {
} }
} }
void populateDamagePartPictures() {
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) {
for (var element in widget.adDetails.vehicle!.damagereport!) {
int index = -1;
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
partImages: [imageModel],
);
damagePartsPictures.add(vehicleDamageCard);
}
}
}
void deleteAdBottomSheet(BuildContext context) { void deleteAdBottomSheet(BuildContext context) {
return actionConfirmationBottomSheet( return actionConfirmationBottomSheet(
context: context, context: context,
@ -90,6 +113,196 @@ class _AdsDetailViewState extends State<AdsDetailView> {
); );
} }
Widget buildVehicleDetailsWidget() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AdImagesCorouselWidget(vehicleImages: widget.adDetails.vehicle!.image!),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText(
fontSize: 18,
isBold: true,
maxLines: 2,
),
),
(widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.model.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
fontSize: 14,
isBold: true,
),
],
),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor) : const SizedBox(),
],
),
Row(
children: [
("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.transmission!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
8.height,
("${LocaleKeys.description.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.vehicleDescription}".toText(
fontSize: 14,
isBold: true,
),
if (widget.adDetails.isMyAd ?? false) ...[
8.height,
("${LocaleKeys.demand.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
8.height,
const Divider(thickness: 1, height: 1),
8.height,
LocaleKeys.adDurationExpired.tr().toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
],
]
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildBankDetailsIfAvailable() {
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.adsBankDetailsModel != null) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.bankDetails.tr().toText(fontSize: 18, isBold: true),
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row(
children: [
("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.bankName ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
Row(
children: [
("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.iban ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
return const SizedBox.shrink();
});
}
Widget buildAdRejectionDetails() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.rejectionComments.tr().toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor),
Row(
children: [
LocaleKeys.editAd.tr().toText(fontSize: 10, isBold: true),
2.width,
const Icon(Icons.edit, size: 15),
],
).onPress(() async {
Utils.showLoading(context);
await adVM.getVehicleTypes();
await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: widget.adDetails.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
adVM.onEditUpdateAdPressed(context: context, previousDetails: widget.adDetails, isFromExtendAd: false);
}),
],
).paddingOnly(bottom: 5),
Row(
children: [
Flexible(
child: (widget.adDetails.comment ?? "").toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
)
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildDamagePartDetails() {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
MyAssets.carHitIcon.buildSvg(color: MyColors.darkTextColor),
10.width,
LocaleKeys.damagePartPictures.tr().toText(fontSize: 16),
],
),
const Icon(Icons.arrow_forward_ios_rounded, size: 20)
],
).paddingOnly(top: 5, bottom: 5).onPress(() {
showMyBottomSheet(context, child: AdDamagePartPicturesSheet(adDamageReportList: widget.adDetails.vehicle!.damagereport ?? []));
}).toWhiteContainer(width: double.infinity, allPading: 12);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -128,173 +341,16 @@ class _AdsDetailViewState extends State<AdsDetailView> {
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
Column( buildVehicleDetailsWidget(),
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CarouselWithIndicatorDemo(vehicleImages: widget.adDetails.vehicle!.image!),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText(
fontSize: 18,
isBold: true,
maxLines: 2,
),
),
(widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.model.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
fontSize: 14,
isBold: true,
),
],
),
widget.adDetails.createdOn != null
? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor)
: const SizedBox(),
],
),
Row(
children: [
("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.transmission!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
8.height,
("${LocaleKeys.description.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.vehicleDescription}".toText(
fontSize: 14,
isBold: true,
),
if (widget.adDetails.isMyAd ?? false) ...[
8.height,
("${LocaleKeys.demand.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
8.height,
const Divider(thickness: 1, height: 1),
8.height,
LocaleKeys.adDurationExpired.tr().toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
],
]
],
).toWhiteContainer(width: double.infinity, allPading: 12),
12.height, 12.height,
Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) { buildBankDetailsIfAvailable(),
if (adVM.adsBankDetailsModel != null) { if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) ...[
return Column( buildDamagePartDetails(),
mainAxisSize: MainAxisSize.min, ],
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.bankDetails.tr().toText(fontSize: 18, isBold: true),
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row(
children: [
("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.bankName ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
Row(
children: [
("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.iban ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
return const SizedBox.shrink();
}),
12.height, 12.height,
if (widget.adDetails.adPostStatus == AdPostStatus.rejected) if (widget.adDetails.adPostStatus == AdPostStatus.rejected) ...[
Column( buildAdRejectionDetails(),
mainAxisSize: MainAxisSize.min, ],
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.rejectionComments.tr().toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor),
Row(
children: [
LocaleKeys.editAd.tr().toText(fontSize: 10, isBold: true),
2.width,
const Icon(Icons.edit, size: 15),
],
).onPress(() async {
Utils.showLoading(context);
await adVM.getVehicleTypes();
await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: widget.adDetails.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
adVM.onEditUpdateAdPressed(context, widget.adDetails);
}),
],
).paddingOnly(bottom: 5),
Row(
children: [
Flexible(
child: (widget.adDetails.comment ?? "").toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
)
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
], ],
), ),
), ),
@ -533,13 +589,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
), ),
if (adDetailsModel.whatsAppNo == null) ...[ if (adDetailsModel.whatsAppNo == null) ...[
8.width, 8.width,
Container( Container(height: 55, width: 55, alignment: Alignment.center, decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), child: MyAssets.whatsAppIcon.buildSvg(height: 33, width: 35)).onPress(() {
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
child: MyAssets.whatsAppIcon.buildSvg(height: 33, width: 35))
.onPress(() {
Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? ""); Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? "");
}), }),
], ],
@ -1155,12 +1205,12 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
maxHeight: 55, maxHeight: 55,
title: LocaleKeys.yes.tr(), title: LocaleKeys.yes.tr(),
fontSize: 15, fontSize: 15,
onPressed: () { onPressed: () async {
Navigator.pop(context); Utils.showLoading(context);
adVM.updateSelectionVehicleTypeId( await adVM.getVehicleTypes();
SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""), await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: adDetailsModel.vehicle!.vehicleType ?? -1);
); Utils.hideLoading(context);
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: true)); adVM.onEditUpdateAdPressed(context: context, previousDetails: adDetailsModel, isFromExtendAd: true);
}, },
), ),
), ),
@ -1177,7 +1227,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""), SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""),
); );
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: false)); showMyBottomSheet(context, child: const AdDurationSelectionSheet(isFromExtendAd: true, isUpdateAdSelected: false));
}, },
), ),
), ),

@ -0,0 +1,143 @@
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/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_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/view_models/ad_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class AdDamagePartsSelectionSheet extends StatefulWidget {
const AdDamagePartsSelectionSheet({Key? key}) : super(key: key);
@override
State<AdDamagePartsSelectionSheet> createState() => _AdDamagePartsSelectionSheetState();
}
class _AdDamagePartsSelectionSheetState extends State<AdDamagePartsSelectionSheet> {
bool checkBoxValue = false;
@override
Widget build(BuildContext context) {
AdVM adVM = context.watch<AdVM>();
return SizedBox(
height: MediaQuery.of(context).size.height * 0.85,
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: [
LocaleKeys.damagePartList.tr().toText(fontSize: 24, isBold: true),
],
),
8.height,
TxtField(
value: adVM.damagePartSearchValue,
errorValue: "",
hint: LocaleKeys.searchPart.tr(),
onChanged: (value) {
adVM.onSearchChangedForDamagePart(value);
},
),
8.height,
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: adVM.vehiclePartsSearchResults.isEmpty ? adVM.vehicleDamageParts.length : adVM.vehiclePartsSearchResults.length,
itemBuilder: (BuildContext context, int index) {
VehiclePartModel vehiclePart = adVM.vehiclePartsSearchResults.isEmpty ? adVM.vehicleDamageParts[index] : adVM.vehiclePartsSearchResults[index];
return Column(
children: [
// CheckboxListTile(
// value: false,
// visualDensity: VisualDensity.compact,
// contentPadding: EdgeInsets.zero,
// controlAffinity: ListTileControlAffinity.leading,
// title: "Rear Break Light".toText(
// fontSize: 16,
// isBold: true,
// ),
// onChanged: (value) {},
// ),
InkWell(
onTap: () {
if (vehiclePart.isSelected!) {
return;
}
adVM.vehicleDamageParts[index].isChecked = !(adVM.vehicleDamageParts[index].isChecked!);
setState(() {});
},
child: Row(
children: [
SizedBox(
height: 40.0,
width: 30.0,
child: Transform.scale(
scale: 1.3,
child: Checkbox(
value: vehiclePart.isSelected! ? true : vehiclePart.isChecked,
activeColor: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.primaryColor,
onChanged: (value) {
if (vehiclePart.isSelected!) {
return;
}
adVM.vehicleDamageParts[index].isChecked = !(adVM.vehicleDamageParts[index].isChecked!);
setState(() {});
},
),
),
),
const SizedBox(width: 20),
vehiclePart.partName.toString().toText(
fontSize: 16,
color: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.black,
)
],
),
),
const Divider(thickness: 1),
],
);
},
),
),
SizedBox(
width: double.infinity,
child: ShowFillButton(
title: LocaleKeys.addDamagePart.tr(),
onPressed: () {
for (var value in adVM.vehicleDamageParts) {
if (value.isChecked! && !value.isSelected!) {
adVM.addNewDamagePartCard(
damageCard: VehicleDamageCard(
partImageErrorValue: "",
partImages: null,
partSelectedId: SelectionModel(selectedOption: value.partName!, selectedId: value.id!, errorValue: ""),
),
);
value.isChecked = false;
value.isSelected = true;
}
}
Navigator.pop(context);
},
).paddingOnly(bottom: 10),
),
],
),
).horPaddingMain();
}
}

@ -15,14 +15,11 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class AdDurationSelectionSheetContent extends StatelessWidget { class AdDurationSelectionSheet extends StatelessWidget {
final bool isFromExtendAd; final bool isFromExtendAd;
final bool isUpdateAdSelected; final bool isUpdateAdSelected;
const AdDurationSelectionSheetContent( const AdDurationSelectionSheet({super.key, required this.isFromExtendAd, required this.isUpdateAdSelected});
{super.key,
required this.isFromExtendAd,
required this.isUpdateAdSelected});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -33,10 +30,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
children: [ children: [
Row( Row(
children: [ children: [
LocaleKeys.selectDuration LocaleKeys.selectDuration.tr().toText(fontSize: 22, isBold: true).paddingOnly(top: 10, left: 21, right: 21),
.tr()
.toText(fontSize: 22, isBold: true)
.paddingOnly(top: 10, left: 21, right: 21),
], ],
), ),
Expanded( Expanded(
@ -56,32 +50,22 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
("${adDuration.days}${LocaleKeys.daysVar.tr()}") ("${adDuration.days}${LocaleKeys.daysVar.tr()}").toString().toText(fontSize: 16, isBold: true),
.toString()
.toText(fontSize: 16, isBold: true),
4.height, 4.height,
"Your Ad will be active for ${adDuration.days} Days and then you will need to extend it to keep it active. " "Your Ad will be active for ${adDuration.days} Days and then you will need to extend it to keep it active. ".toText(
.toText(
fontSize: 14, fontSize: 14,
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
12.height, 12.height,
LocaleKeys.adCharges.tr().toText( LocaleKeys.adCharges.tr().toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true),
fontSize: 14,
color: MyColors.lightTextColor,
isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
"${adDuration.price}" "${adDuration.price}".toText(fontSize: 22, isBold: true),
.toText(fontSize: 22, isBold: true),
2.width, 2.width,
Padding( Padding(
padding: const EdgeInsets.only(bottom: 4), padding: const EdgeInsets.only(bottom: 4),
child: LocaleKeys.sar.tr().toText( child: LocaleKeys.sar.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
), ),
], ],
), ),
@ -92,16 +76,14 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
).toWhiteContainer( ).toWhiteContainer(
width: double.infinity, width: double.infinity,
allPading: 12, allPading: 12,
isBorderRequired: isBorderRequired: adDuration.id == adVM.vehicleAdDurationId.selectedId,
adDuration.id == adVM.vehicleAdDurationId.selectedId,
), ),
).onPress(() { ).onPress(() {
if (isFromExtendAd) { if (isFromExtendAd) {
adVM.updateVehicleExtendAdDurationId( adVM.updateVehicleExtendAdDurationId(
SelectionModel( SelectionModel(
selectedId: adDuration.id ?? 0, selectedId: adDuration.id ?? 0,
selectedOption: selectedOption: ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
itemPrice: adDuration.price!.toInt().toString(), itemPrice: adDuration.price!.toInt().toString(),
), ),
); );
@ -110,8 +92,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
adVM.updateVehicleAdDurationId( adVM.updateVehicleAdDurationId(
SelectionModel( SelectionModel(
selectedId: adDuration.id ?? 0, selectedId: adDuration.id ?? 0,
selectedOption: selectedOption: ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
itemPrice: adDuration.price!.toInt().toString(), itemPrice: adDuration.price!.toInt().toString(),
), ),
); );
@ -142,8 +123,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
return; return;
} else { } else {
if (isFromExtendAd && !isUpdateAdSelected) { if (isFromExtendAd && !isUpdateAdSelected) {
navigateWithName(context, AppRoutes.paymentMethodsView, navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.extendAds);
arguments: PaymentTypes.extendAds);
return; return;
} }
navigateReplaceWithName(context, AppRoutes.createAdView); navigateReplaceWithName(context, AppRoutes.createAdView);
@ -155,8 +135,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
); );
} }
Widget showItem(String item, String value, Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
{Color valueColor = Colors.black}) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,

@ -15,14 +15,14 @@ import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart'; import 'package:sizer/sizer.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class BottomSheetListContent extends StatefulWidget { class BottomSheetAdDamagePartsContent extends StatefulWidget {
const BottomSheetListContent({Key? key}) : super(key: key); const BottomSheetAdDamagePartsContent({Key? key}) : super(key: key);
@override @override
State<BottomSheetListContent> createState() => _BottomSheetListContentState(); State<BottomSheetAdDamagePartsContent> createState() => _BottomSheetAdDamagePartsContentState();
} }
class _BottomSheetListContentState extends State<BottomSheetListContent> { class _BottomSheetAdDamagePartsContentState extends State<BottomSheetAdDamagePartsContent> {
bool checkBoxValue = false; bool checkBoxValue = false;
@override @override
@ -207,8 +207,7 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
(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: LocaleKeys.selectService.tr(), hint: LocaleKeys.selectService.tr(),
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,
); );
}, },
), ),
@ -266,8 +265,7 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
], ],
if (adVM.vehicleAdsSpecialServicesId.selectedId != 3 && adVM.vehicleAdsSpecialServicesId.selectedId != 1) ...[ if (adVM.vehicleAdsSpecialServicesId.selectedId != 3 && adVM.vehicleAdsSpecialServicesId.selectedId != 1) ...[
descriptionCard( descriptionCard(
description: description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "Some Dummy Service Description!!",
adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "Some Dummy Service Description!!",
), ),
], ],
if (adVM.adSSTimeSlots.isNotEmpty) ...[ if (adVM.adSSTimeSlots.isNotEmpty) ...[

@ -0,0 +1,91 @@
import 'dart:async';
import 'dart:developer';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
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/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class AdDamagePartPicturesSheet extends StatefulWidget {
final List<DamageReport> adDamageReportList;
const AdDamagePartPicturesSheet({super.key, required this.adDamageReportList});
@override
State<AdDamagePartPicturesSheet> createState() => _AdDamagePartPicturesSheetState();
}
class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
List<VehicleDamageCard> vehicleDamageCards = [];
@override
void initState() {
scheduleMicrotask(() => populateDamagePartPictures());
super.initState();
}
void populateDamagePartPictures() {
for (var element in widget.adDamageReportList) {
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
partImages: [imageModel],
);
vehicleDamageCards.add(vehicleDamageCard);
}
setState(() {});
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.2,
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: vehicleDamageCards.length,
itemBuilder: (BuildContext context, int index) {
VehicleDamageCard vehicleDamageCard = vehicleDamageCards[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
vehicleDamageCard.partSelectedId!.selectedOption.toText(fontSize: 18, color: MyColors.darkTextColor),
PickedFilesContainer(
pickedFiles: vehicleDamageCard.partImages ?? [],
isReview: true,
onCrossPressedSecondary: (imageIndex, filePath) {},
index: index,
onAddFilePressed: () {},
),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4),
);
},
).paddingOnly(top: 10),
);
}
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
4.width,
value.toText(fontSize: 12, color: valueColor, isBold: true),
],
);
}
}

@ -3,16 +3,16 @@ import 'package:flutter/material.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';
class CarouselWithIndicatorDemo extends StatefulWidget { class AdImagesCorouselWidget extends StatefulWidget {
final List<AdImage> vehicleImages; final List<AdImage> vehicleImages;
const CarouselWithIndicatorDemo({super.key, required this.vehicleImages}); const AdImagesCorouselWidget({super.key, required this.vehicleImages});
@override @override
State<StatefulWidget> createState() => _CarouselWithIndicatorState(); State<StatefulWidget> createState() => _CarouselWithIndicatorState();
} }
class _CarouselWithIndicatorState extends State<CarouselWithIndicatorDemo> { class _CarouselWithIndicatorState extends State<AdImagesCorouselWidget> {
int _current = 0; int _current = 0;
final CarouselController _controller = CarouselController(); final CarouselController _controller = CarouselController();

@ -14,13 +14,13 @@ import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class BuildAdsList extends StatelessWidget { class AdsListWidget extends StatelessWidget {
final List<AdDetailsModel> adsList; final List<AdDetailsModel> adsList;
final ScrollPhysics? scrollPhysics; final ScrollPhysics? scrollPhysics;
final bool isAdsFragment; final bool isAdsFragment;
final bool shouldShowAdStatus; final bool shouldShowAdStatus;
const BuildAdsList({ const AdsListWidget({
Key? key, Key? key,
required this.adsList, required this.adsList,
this.scrollPhysics, this.scrollPhysics,

@ -68,10 +68,10 @@ class CreateAdProgressSteps extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
buildStep(MyAssets.carIcon, (LocaleKeys.vehicleVar.tr() + " \n" + LocaleKeys.detailsVar.tr()), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 1), buildStep(MyAssets.carIcon, ("${LocaleKeys.vehicleVar.tr()} \n${LocaleKeys.detailsVar.tr()}"), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 1),
buildStep(MyAssets.carHitIcon, (LocaleKeys.damageVar.tr() + " \n" + LocaleKeys.partsVar.tr()), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 2), buildStep(MyAssets.carHitIcon, ("${LocaleKeys.damageVar.tr()} \n${LocaleKeys.partsVar.tr()}"), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 2),
buildStep(MyAssets.clockIcon, (LocaleKeys.additional.tr() + " \n" + LocaleKeys.detailsVar.tr()), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 3), buildStep(MyAssets.clockIcon, ("${LocaleKeys.additional.tr()} \n${LocaleKeys.detailsVar.tr()}"), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 3),
buildStep(MyAssets.reviewIcon, (LocaleKeys.review.tr() + " \n"+ LocaleKeys.adVar.tr()), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 4), buildStep(MyAssets.reviewIcon, ("${LocaleKeys.review.tr()} \n${LocaleKeys.adVar.tr()}"), getProgressStepNumber(currentStep: adVM.currentProgressStep) >= 4),
], ],
), ),
], ],

@ -0,0 +1,110 @@
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
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/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class DamagePicturesList extends StatefulWidget {
final int serviceId;
const DamagePicturesList(this.serviceId, {super.key});
@override
State<DamagePicturesList> createState() => _DamagePicturesListState();
}
class _DamagePicturesListState extends State<DamagePicturesList> {
@override
void initState() {
super.initState();
context.read<AppointmentsVM>().getServiceItems(widget.serviceId);
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.2,
child: Consumer<AppointmentsVM>(
builder: (context, appointmentsVM, _) {
if (appointmentsVM.state == ViewState.busy) {
return Center(child: CircularProgressIndicator());
}
return appointmentsVM.serviceItemsFromApi.isEmpty
? const EmptyWidget()
: ListView.separated(
itemCount: appointmentsVM.serviceItemsFromApi.length,
itemBuilder: (BuildContext context, int index) {
ItemData serviceItemModel = appointmentsVM.serviceItemsFromApi[index];
return SizedBox(
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
serviceItemModel.name.toString().toText(fontSize: 16, isBold: true),
4.height,
showItem(LocaleKeys.availableforAppointment.tr() + ":", (serviceItemModel.isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem(LocaleKeys.allowingWorkshopService.tr() + ":", (serviceItemModel.isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem(LocaleKeys.allowingHomeService.tr() + ":", (serviceItemModel.isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
12.height,
LocaleKeys.serviceAmount.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
serviceItemModel.price!.toText(fontSize: 22, isBold: true),
2.width,
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: LocaleKeys.sar.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
],
),
],
),
),
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset(
// MyAssets.icEdit,
// width: 16,
// height: 16,
// ),
// )
],
),
).toWhiteContainer(width: double.infinity, allPading: 12);
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
padding: const EdgeInsets.all(20),
);
},
),
);
}
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
4.width,
value.toText(fontSize: 12, color: valueColor, isBold: true),
],
);
}
}

@ -64,17 +64,6 @@ class PickedFilesContainer extends StatelessWidget {
}, },
), ),
); );
// return Wrap(
// children: pickedImages
// .map((file) => BuildImageContainer(
// file: file,
// onCrossPressedPrimary: onCrossPressedPrimary,
// onCrossPressedSecondary: onCrossPressedSecondary,
// index: index,
// isReview: isReview,
// ))
// .toList(),
// );
} }
} }
@ -107,8 +96,8 @@ class BuildFilesContainer extends StatelessWidget {
children: [ children: [
isPdf isPdf
? Container( ? Container(
height: 72, height: 75,
width: 70, width: 73,
margin: const EdgeInsets.all(8), margin: const EdgeInsets.all(8),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(
@ -121,8 +110,8 @@ class BuildFilesContainer extends StatelessWidget {
? Image.network( ? Image.network(
image.filePath!, image.filePath!,
fit: BoxFit.fill, fit: BoxFit.fill,
height: 72, height: 75,
width: 70, width: 73,
).paddingAll(8) ).paddingAll(8)
: Image.file( : Image.file(
File(image.filePath!), File(image.filePath!),

@ -9,14 +9,13 @@ import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_duration_
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/damage_parts_container.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/damage_parts_container.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/vehicle_details_container.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/vehicle_details_container.dart';
import 'package:mc_common_app/views/advertisement/create_ad_progress_steps.dart'; import 'package:mc_common_app/views/advertisement/components/create_ad_progress_steps_widget.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';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class CreateAdView extends StatefulWidget { class CreateAdView extends StatefulWidget {
const CreateAdView({Key? key}) : super(key: key); const CreateAdView({Key? key}) : super(key: key);
@ -37,7 +36,7 @@ class _CreateAdViewState extends State<CreateAdView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: adVM.isAdEditEnabled ? LocaleKeys.updateAd.tr(): LocaleKeys.createAd.tr(), title: adVM.isAdEditEnabled ? LocaleKeys.updateAd.tr() : LocaleKeys.createAd.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => adVM.onBackButtonPressed(context), onBackButtonTapped: () => adVM.onBackButtonPressed(context),

@ -1,30 +1,26 @@
import 'dart:developer';
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/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.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/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';
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/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/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';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class SelectAdTypeView extends StatelessWidget { class SelectAdTypeView extends StatelessWidget {
final bool isProvider; final List<bool> arguments; // [0] isProviderOrCustomer [1] isFromExtendAd
const SelectAdTypeView({ const SelectAdTypeView({Key? key, required this.arguments}) : super(key: key);
Key? key,
this.isProvider = true,
}) : super(key: key);
Widget getVehicleAdTypeIcon(VehicleType vehicleTypeEnum) { Widget getVehicleAdTypeIcon(VehicleType vehicleTypeEnum) {
switch (vehicleTypeEnum) { switch (vehicleTypeEnum) {
@ -42,26 +38,10 @@ class SelectAdTypeView extends StatelessWidget {
} }
} }
// bool checkSelection(VehicleTypeModel vtype, AdVM adVM) {
// bool value = false;
// if (adVM.vehicleTypes.isNotEmpty) {
// for (var vehicle in adVM.vehicleTypes) {
// if (vtype.id == adVM.previousADDetails?.vehicle?.vehicleType) {
// value = true;
// break;
// }
// }
// }
// return value;
// }
//
// clearAll(BuildContext context) {
// AdVM adVM = context.read<AdVM>();
// adVM.clearEditValues();
// }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool isProvider = arguments[0];
bool isFromExtendAd = arguments[1];
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: LocaleKeys.selectAdType.tr(), title: LocaleKeys.selectAdType.tr(),
@ -79,14 +59,12 @@ class SelectAdTypeView extends StatelessWidget {
VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index]; VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index];
return InkWell( return InkWell(
onTap: () { onTap: () {
adVM.updateSelectionVehicleTypeId( adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""));
SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""),
);
if (adVM.isAdEditEnabled) { if (adVM.isAdEditEnabled) {
adVM.autoFillSelectedVehicleAdsDuration();
adVM.autoFillSelectedVehicleAdsDetails(); adVM.autoFillSelectedVehicleAdsDetails();
} }
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isUpdateAdSelected: false, isFromExtendAd: false)); log("isUpdateAdSelected: ${adVM.isAdEditEnabled}}");
showMyBottomSheet(context, child: AdDurationSelectionSheet(isUpdateAdSelected: adVM.isAdEditEnabled, isFromExtendAd: isFromExtendAd));
}, },
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
@ -110,7 +88,7 @@ class SelectAdTypeView extends StatelessWidget {
Row( Row(
children: [ children: [
LocaleKeys.duration.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), LocaleKeys.duration.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
LocaleKeys.validUntilSubscriptionExpiration.tr() .toText(fontSize: 13, isBold: true), LocaleKeys.validUntilSubscriptionExpiration.tr().toText(fontSize: 13, isBold: true),
], ],
).paddingOnly(top: 5, bottom: 5), ).paddingOnly(top: 5, bottom: 5),
] else ...[ ] else ...[
@ -140,7 +118,7 @@ class SelectAdTypeView extends StatelessWidget {
), ),
], ],
), ),
).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) {
@ -160,7 +138,7 @@ class SelectAdTypeView extends StatelessWidget {
LocaleKeys.adsRemainingVar.tr().toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), LocaleKeys.adsRemainingVar.tr().toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true),
], ],
), ),
Text.rich( Text.rich(
TextSpan( TextSpan(
children: [ children: [
TextSpan( TextSpan(

@ -24,7 +24,7 @@ class ScreenArgumentsForAppointmentDetailPage {
class BookAppointmentSchedulesView extends StatelessWidget { class BookAppointmentSchedulesView extends StatelessWidget {
final ScreenArgumentsForAppointmentDetailPage screenArgumentsForAppointmentDetailPage; final ScreenArgumentsForAppointmentDetailPage screenArgumentsForAppointmentDetailPage;
BookAppointmentSchedulesView({Key? key, required this.screenArgumentsForAppointmentDetailPage}) : super(key: key); const BookAppointmentSchedulesView({Key? key, required this.screenArgumentsForAppointmentDetailPage}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -47,14 +47,14 @@ class BookAppointmentSchedulesView extends StatelessWidget {
itemBuilder: (BuildContext context, int scheduleIndex) { itemBuilder: (BuildContext context, int scheduleIndex) {
ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex]; ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex];
return ExpansionTile( return ExpansionTile(
tilePadding: EdgeInsets.symmetric(horizontal: 21, vertical: 10), tilePadding: const EdgeInsets.symmetric(horizontal: 21, vertical: 10),
childrenPadding: EdgeInsets.only(left: 16, bottom: 10, right: 16), childrenPadding: const EdgeInsets.only(left: 16, bottom: 10, right: 16),
title: Column( title: Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
child: (LocaleKeys.schedule.tr() + " ${scheduleIndex + 1}").toText(fontSize: 20, isBold: true), child: ("${LocaleKeys.schedule.tr()} ${scheduleIndex + 1}").toText(fontSize: 20, isBold: true),
), ),
], ],
), ),
@ -62,7 +62,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
("${scheduleData.appointmentType == 2 ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()}").toText(fontSize: 12, isBold: true).expand(), (scheduleData.appointmentType == 2 ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(),
], ],
), ),
Column( Column(
@ -70,7 +70,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
children: [ children: [
5.height, 5.height,
ListView.builder( ListView.builder(
physics: NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].servicesListInAppointment!.length, itemCount: appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].servicesListInAppointment!.length,
itemBuilder: (BuildContext context, int serviceIndex) { itemBuilder: (BuildContext context, int serviceIndex) {

@ -1,6 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.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';
@ -8,15 +6,15 @@ import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.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/common_widgets/custom_add_button_widget.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';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class BookAppointmentServicesView extends StatelessWidget { class BookAppointmentServicesView extends StatelessWidget {
BookAppointmentServicesView({Key? key}) : super(key: key); const BookAppointmentServicesView({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -31,8 +29,7 @@ class BookAppointmentServicesView extends StatelessWidget {
}, },
), ),
body: Consumer( body: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
Widget? child) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -40,14 +37,12 @@ class BookAppointmentServicesView extends StatelessWidget {
CustomAddButton( CustomAddButton(
needsBorder: true, needsBorder: true,
bgColor: MyColors.white, bgColor: MyColors.white,
onTap: () => appointmentsVM.openTheAddServiceBottomSheet( onTap: () => appointmentsVM.openTheAddServiceBottomSheet(context, appointmentsVM),
context, appointmentsVM),
text: LocaleKeys.addServices.tr(), text: LocaleKeys.addServices.tr(),
icon: Container( icon: Container(
height: 24, height: 24,
width: 24, width: 24,
decoration: const BoxDecoration( decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
shape: BoxShape.circle, color: MyColors.darkTextColor),
child: const Icon(Icons.add, color: MyColors.white), child: const Icon(Icons.add, color: MyColors.white),
), ),
).horPaddingMain(), ).horPaddingMain(),
@ -56,56 +51,34 @@ class BookAppointmentServicesView extends StatelessWidget {
shrinkWrap: true, shrinkWrap: true,
itemCount: appointmentsVM.servicesInCurrentAppointment.length, itemCount: appointmentsVM.servicesInCurrentAppointment.length,
itemBuilder: (BuildContext context, int serviceIndex) { itemBuilder: (BuildContext context, int serviceIndex) {
ServiceModel serviceData = appointmentsVM ServiceModel serviceData = appointmentsVM.servicesInCurrentAppointment[serviceIndex];
.servicesInCurrentAppointment[serviceIndex];
return Column( return Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
child: (serviceData.serviceDescription ?? "") child: (serviceData.serviceDescription ?? "").toText(fontSize: 15, isBold: true),
.toText(fontSize: 15, isBold: true),
), ),
IconButton( IconButton(onPressed: () => appointmentsVM.removeServiceInCurrentAppointment(serviceIndex), icon: const Icon(Icons.delete_outline, color: MyColors.redColor))
onPressed: () => appointmentsVM
.removeServiceInCurrentAppointment(
serviceIndex),
icon: Icon(Icons.delete_outline,
color: MyColors.redColor),
)
], ],
), ),
if (true) ...[ if (true) ...[
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(LocaleKeys.serviceLocation.tr()).toText( (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
fontSize: 12, (serviceData.isHomeSelected ? serviceData.homeLocation : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(),
color: MyColors.lightTextColor,
isBold: true),
(serviceData.isHomeSelected
? serviceData.homeLocation
: LocaleKeys.workshop.tr())
.toText(fontSize: 12, isBold: true)
.expand(),
], ],
), ),
5.height, 5.height,
Column( Column(
children: List.generate( children: List.generate(serviceData.serviceItems!.length, (itemIndex) {
serviceData.serviceItems!.length, (itemIndex) { ItemData itemData = serviceData.serviceItems![itemIndex];
ItemData itemData =
serviceData.serviceItems![itemIndex];
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"${itemData.name}: ".toText( "${itemData.name}: ".toText(fontSize: 13, color: MyColors.lightTextColor, isBold: true),
fontSize: 13, ("${itemData.price}").toText(fontSize: 13, isBold: true).expand(),
color: MyColors.lightTextColor,
isBold: true),
("${itemData.price}")
.toText(fontSize: 13, isBold: true)
.expand(),
], ],
); );
}), }),
@ -114,33 +87,15 @@ class BookAppointmentServicesView extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
((appointmentsVM ((appointmentsVM.servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice).toString()).toText(fontSize: 32, isBold: true),
.servicesInCurrentAppointment[
serviceIndex]
.currentTotalServicePrice)
.toString())
.toText(fontSize: 32, isBold: true),
2.width, 2.width,
LocaleKeys.sar LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
.tr() const Icon(Icons.arrow_drop_down, size: 30)
.toText(
color: MyColors.lightTextColor,
fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
Icon(Icons.arrow_drop_down, size: 30)
], ],
).onPress(() => appointmentsVM.priceBreakDownClicked( ).onPress(() => appointmentsVM.priceBreakDownClicked(context, appointmentsVM.servicesInCurrentAppointment[serviceIndex])),
context,
appointmentsVM
.servicesInCurrentAppointment[serviceIndex])),
], ],
], ],
).toWhiteContainer( ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10));
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(
horizontal: 21, vertical: 10));
}, },
).expand(), ).expand(),
Row( Row(

@ -14,7 +14,7 @@ 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/view_models/appointments_view_model.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/widgets/common_widgets/custom_add_button_widget.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';
@ -223,8 +223,7 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
(AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "") (AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16),
.toText(color: MyColors.black, isBold: true, fontSize: 16),
Row( Row(
children: [ children: [
MyAssets.miniClock.buildSvg(height: 12), MyAssets.miniClock.buildSvg(height: 12),

@ -11,7 +11,7 @@ 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/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart'; import 'package:mc_common_app/views/advertisement/components/ads_list_widget.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/common_widgets/categories_list.dart'; import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
@ -102,10 +102,10 @@ class AdsFragment extends StatelessWidget {
if (adVM.adsFiltersCounter == 0) ...[ if (adVM.adsFiltersCounter == 0) ...[
16.height, 16.height,
FiltersList( FiltersList(
filterList: adVM.exploreAdsFilterOptions, filterList: adVM.exploreAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()), onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()),
needLeftPadding: false) needLeftPadding: false,
.paddingOnly(left: 21), ).paddingOnly(left: 21),
] ]
] else ...[ ] else ...[
16.height, 16.height,
@ -126,7 +126,7 @@ class AdsFragment extends StatelessWidget {
await adVM.getExploreAds(); await adVM.getExploreAds();
await adVM.getMyAds(); await adVM.getMyAds();
}, },
child: BuildAdsList(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM)), child: AdsListWidget(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM)),
), ),
) )
], ],
@ -134,7 +134,7 @@ class AdsFragment extends StatelessWidget {
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: () async { onPressed: () async {
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: injector.get<AppState>().currentAppType == AppType.provider); navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector.get<AppState>().currentAppType == AppType.provider, false]);
}, },
backgroundColor: MyColors.darkPrimaryColor, backgroundColor: MyColors.darkPrimaryColor,
child: const Icon(Icons.add, color: MyColors.white), child: const Icon(Icons.add, color: MyColors.white),

@ -53,7 +53,7 @@ class MyRequestsFragment extends StatelessWidget {
) )
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppType.provider, requestIndex: index); return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppState().currentAppType, requestIndex: index);
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return 16.height; return 16.height;

@ -7,7 +7,7 @@ import 'package:mc_common_app/extensions/string_extensions.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';
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/picked_images_container.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.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/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';

@ -65,13 +65,9 @@ class RequestItem extends StatelessWidget {
), ),
], ],
2.height, 2.height,
request.cityName.toText( request.cityName.toText(color: MyColors.lightTextColor),
color: MyColors.lightTextColor,
),
if (request.createdOn != null) ...[ if (request.createdOn != null) ...[
DateTime.parse(request.createdOn!).getTimeAgo().toText( DateTime.parse(request.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor),
color: MyColors.lightTextColor,
),
], ],
], ],
) )
@ -92,15 +88,7 @@ class RequestItem extends StatelessWidget {
isBold: true, isBold: true,
), ),
2.width, 2.width,
LocaleKeys.sar LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10).paddingOnly(bottom: 3),
.tr()
.toText(
color: MyColors.lightTextColor,
fontSize: 10,
)
.paddingOnly(
bottom: 3,
),
], ],
), ),
request.requestStatus == RequestStatus.submitted request.requestStatus == RequestStatus.submitted

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@ -20,7 +22,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final String profileImageUrl; final String profileImageUrl;
final bool isDrawerEnabled; final bool isDrawerEnabled;
final VoidCallback? onTap; final VoidCallback? onTap;
final VoidCallback? onBackButtonTapped; final Function? onBackButtonTapped;
final double? leadingWidth; final double? leadingWidth;
const CustomAppBar({ const CustomAppBar({
@ -53,73 +55,70 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
centerTitle: isTitleCenter ?? true, centerTitle: isTitleCenter ?? true,
leading: isDrawerEnabled leading: isDrawerEnabled
? InkWell( ? InkWell(
onTap: onTap, onTap: onTap,
child: Row( child: Row(
children: [ children: [
profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userLocalImage != null profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userLocalImage != null
? Image.file( ? Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!, AppState().getUser.data!.userInfo!.userLocalImage!,
width: 34, width: 34,
height: 34, height: 34,
fit: BoxFit.fill, fit: BoxFit.fill,
).toCircle(borderRadius: 100) ).toCircle(borderRadius: 100)
: profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userImageUrl != null : profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userImageUrl != null
? CachedNetworkImage( ? CachedNetworkImage(
imageUrl: AppState().getUser.data!.userInfo!.userImageUrl, imageUrl: AppState().getUser.data!.userInfo!.userImageUrl,
imageBuilder: (context, imageProvider) => imageBuilder: (context, imageProvider) => Container(
Container( decoration: BoxDecoration(
decoration: BoxDecoration( image: DecorationImage(
image: DecorationImage( image: imageProvider,
image: imageProvider, fit: BoxFit.cover,
fit: BoxFit.cover, ),
), ),
), ),
), placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
placeholder: (context, url) => const Center(child: CircularProgressIndicator()), errorWidget: (context, url, error) => const Icon(Icons.supervised_user_circle_outlined),
errorWidget: (context, url, error) => const Icon(Icons.supervised_user_circle_outlined), fadeInCurve: Curves.easeIn,
fadeInCurve: Curves.easeIn, width: 34,
width: 34, height: 34,
height: 34, fit: BoxFit.fill,
fit: BoxFit.fill, fadeInDuration: const Duration(milliseconds: 1000),
fadeInDuration: Duration(milliseconds: 1000), useOldImageOnUrlChange: false)
useOldImageOnUrlChange: false .toCircle(borderRadius: 100)
).toCircle(borderRadius: 100) : Image.asset(
: Image.asset( MyAssets.carBanner,
MyAssets.carBanner, width: 34,
width: 34, height: 34,
height: 34, fit: BoxFit.fill,
fit: BoxFit.fill, ).toCircle(borderRadius: 100),
).toCircle(borderRadius: 100), 10.width,
10.width, SvgPicture.asset(MyAssets.dashboardDrawerIcon),
SvgPicture.asset(MyAssets.dashboardDrawerIcon), ],
], ).paddingOnly(left: 21),
).paddingOnly(left: 21), )
)
: isRemoveBackButton : isRemoveBackButton
? null ? null
: Row( : Row(
children: [ children: [
21.width, 21.width,
IconButton( const Icon(Icons.arrow_back_ios, color: Colors.black, size: 16)
icon: const Icon( .toContainer(
Icons.arrow_back_ios, padding: const EdgeInsets.only(left: 5),
color: Colors.black, borderRadius: 100,
size: 16, borderColor: MyColors.lightGreyEFColor,
), isEnabledBorder: true,
onPressed: onBackButtonTapped ?? height: 40,
() { width: 40,
Navigator.pop(context); )
}, .onPress(() {
).toContainer( if (onBackButtonTapped != null) {
paddingAll: 0, onBackButtonTapped!();
borderRadius: 100, } else {
borderColor: MyColors.lightGreyEFColor, Navigator.pop(context);
isEnabledBorder: true, }
height: 40, }),
width: 40, ],
), ),
],
),
iconTheme: IconThemeData( iconTheme: IconThemeData(
color: backIconColor ?? Colors.black, //change your color here color: backIconColor ?? Colors.black, //change your color here
), ),

Loading…
Cancel
Save