Added Damage Pictures in ad_detail_view and extend edit ad

master_new_changes
Faiz Hashmi 1 year ago
parent 424942bf58
commit dfa57dbe55

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

@ -581,5 +581,7 @@
"whendoyouWanttoRenew": "When do you want to renew",
"renewVar": "Renew",
"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 serviceProviderDDLGet = "${baseUrlServices}api/ServiceProviders/ServiceProviderDDL_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
static String serviceProvidersAppointmentGet = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointment_Get";
@ -153,6 +156,7 @@ class ApiConsts {
static String getRequestOffers = "${baseUrlServices}api/RequestManagement/ReqOffer_Get";
static String updateRequestOffer = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateStatus";
static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get";
static String getServiceRequestsForProvider = "${baseUrlServices}api/RequestManagement/Request_ServiceProvider";
//Chat
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/user_models/register_user.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_filter_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
@ -83,9 +83,9 @@ class AppRoutes {
static const String paymentMethodsView = "/paymentMethodsView";
//Customer APP: Provider & Services
static const String branchDetailPage = "/branchDetailPage";
static const String branchDetailView = "/branchDetailPage";
static const String branchSearchFilterPage = "/branchSearchFilterPage";
static const String providerProfilePage = "/providerProfilePage";
static const String providerProfileView = "/providerProfilePage";
// Subscriptions
static const String mySubscriptionsPage = "/mySubscriptionsPage";
@ -145,10 +145,10 @@ class AppRoutes {
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(),
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.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.settingOptionsFaqs: (context) => const SettingOptionsFAQs(),
AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(),

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

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

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

@ -1,95 +1,34 @@
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: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(
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
Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false));
class MyApp extends StatelessWidget {
const MyApp({super.key});
// class MyHttpOverrides extends HttpOverrides {
// @override
// HttpClient createHttpClient(SecurityContext? context) {
// return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
// }
// }
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return Sizer(
builder: (
BuildContext context,
Orientation orientation,
DeviceType deviceType,
) {
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(
isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar",
),
debugShowCheckedModeBanner: false,
localizationsDelegates: delegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
);
},
);
});
}
}
// Future<void> main() async {
// WidgetsFlutterBinding.ensureInitialized();
//
// await EasyLocalization.ensureInitialized();
// // AppState().setPostParamsInitConfig();
// HttpOverrides.global = MyHttpOverrides();
//
// runApp(
// EasyLocalization(
// supportedLocales: const <Locale>[
// Locale('en', 'US'),
// Locale('ar', 'SA'),
// ],
// path: 'resources',
// // assetLoader: const CodegenLoader(),
// child: const MyApp(),
// ),
// );
// }
// class MyApp extends StatelessWidget {
// const MyApp({super.key});
@ -104,13 +43,9 @@ class MyApp extends StatelessWidget {
// DeviceType deviceType,
// ) {
// 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(
// isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar",
// ),
@ -124,45 +59,9 @@ class MyApp extends StatelessWidget {
// });
// }
// }
//
// // class MyApp extends StatelessWidget {
// // MyApp({super.key}) {
// // AppDependencies.addDependencies();
// // AppState = Injector.appInstance.get<AppState>();
// // // AppState.setPostParamsInitConfig();
// // }
// //
// // @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,
// // );
// // },
// // );
// // });
// // }
// // }
// 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

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

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

@ -19,12 +19,14 @@ class BranchDetailModel {
final String? closeTime;
final BranchStatusEnum? branchStatus;
final int? statusId;
final dynamic statusText;
final String? statusText;
final double? branchRateAvg;
final List<ServiceModel>? branchServices;
List<CategoryData>? categories;
int? countryID;
String? countryName;
bool isExpanded;
bool? isFavorite;
BranchDetailModel({
this.id,
@ -41,17 +43,18 @@ class BranchDetailModel {
this.openTime,
this.closeTime,
this.branchStatus,
this.branchRateAvg,
this.statusId,
this.statusText,
this.branchServices,
this.categories,
this.countryID,
this.countryName,
this.isFavorite,
required this.isExpanded,
});
factory BranchDetailModel.fromJson(Map<String, dynamic> json) =>
BranchDetailModel(
factory BranchDetailModel.fromJson(Map<String, dynamic> json) => BranchDetailModel(
id: json["id"],
serviceProviderId: json["serviceProviderID"],
serviceProviderName: json["serviceProviderName"],
@ -65,33 +68,13 @@ class BranchDetailModel {
distanceKm: json["distanceKM"]?.toDouble(),
openTime: json["openTime"],
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"],
statusText: json["statusText"],
branchServices: json["serviceProviderServices"] == null ? [] : List<
ServiceModel>.from(json["serviceProviderServices"]!.map((x) =>
ServiceModel.fromJson(x))),
branchRateAvg: json["branchRateAvg"],
branchServices: json["serviceProviderServices"] == null ? [] : List<ServiceModel>.from(json["serviceProviderServices"]!.map((x) => ServiceModel.fromJson(x))),
categories: [],
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;
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))),
messageStatus: json["messageStatus"] == null ? null : json["messageStatus"],
message: json["message"] == null ? null : json["message"],
messageStatus: json["messageStatus"],
message: json["message"],
);
Map<String, dynamic> toJson() => {
"totalItemsCount": totalItemsCount == null ? null : totalItemsCount,
"totalItemsCount": totalItemsCount,
"data": data == null ? null : List<dynamic>.from(data!.map((x) => x.toJson())),
"messageStatus": messageStatus == null ? null : messageStatus,
"message": message == null ? null : message,
"messageStatus": messageStatus,
"message": message,
};
}
@ -60,26 +60,26 @@ class BranchData {
int? status;
factory BranchData.fromJson(Map<String, dynamic> json) => BranchData(
id: json["id"] == null ? null : json["id"],
serviceProviderId: json["serviceProviderID"] == null ? null : json["serviceProviderID"],
branchName: json["branchName"] == null ? null : json["branchName"],
branchDescription: json["branchDescription"] == null ? null : json["branchDescription"],
cityId: json["cityID"] == null ? null : json["cityID"],
address: json["address"] == null ? null : json["address"],
latitude: json["latitude"] == null ? null : json["latitude"],
longitude: json["longitude"] == null ? null : json["longitude"],
status: json["status"] == null ? null : json["status"],
id: json["id"],
serviceProviderId: json["serviceProviderID"],
branchName: json["branchName"],
branchDescription: json["branchDescription"],
cityId: json["cityID"],
address: json["address"],
latitude: json["latitude"],
longitude: json["longitude"],
status: json["status"],
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"serviceProviderID": serviceProviderId == null ? null : serviceProviderId,
"branchName": branchName == null ? null : branchName,
"branchDescription": branchDescription == null ? null : branchDescription,
"cityID": cityId == null ? null : cityId,
"address": address == null ? null : address,
"latitude": latitude == null ? null : latitude,
"longitude": longitude == null ? null : longitude,
"status": status == null ? null : status,
"id": id,
"serviceProviderID": serviceProviderId,
"branchName": branchName,
"branchDescription": branchDescription,
"cityID": cityId,
"address": address,
"latitude": latitude,
"longitude": longitude,
"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));
String branch2ToJson(ProviderModel data) => json.encode(data.toJson());
class ProviderModel {
ProviderModel({
this.messageStatus,
@ -29,13 +27,6 @@ class ProviderModel {
data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? null : data!.toJson(),
"message": message,
};
}
class ProviderModelData {
@ -72,16 +63,6 @@ class ProviderModelData {
userId: json["userID"],
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"companyName": companyName,
"companyDescription": companyDescription,
"allDocStatus": allDocStatus,
"isValidSubscription": isValidSubscription,
"userID": userId,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x.toJson())),
};
}
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';
class ProviderProfileModel {
ProviderProfileModel({
this.id,
@ -16,6 +11,7 @@ class ProviderProfileModel {
this.userId,
this.serviceProviderBranch,
this.countryID,
this.isFavorite,
});
final int? id;
@ -25,10 +21,12 @@ class ProviderProfileModel {
final String? companyDescription;
final int? allDocStatus;
final bool? isValidSubscription;
final bool? isFavorite;
final String? userId;
final List<BranchDetailModel>? serviceProviderBranch;
factory ProviderProfileModel.fromJson(Map<String, dynamic> json) => ProviderProfileModel(
factory ProviderProfileModel.fromJson(Map<String, dynamic> json) =>
ProviderProfileModel(
id: json["id"],
companyName: json["companyName"],
countryName: json["countryName"],
@ -37,17 +35,7 @@ class ProviderProfileModel {
allDocStatus: json["allDocStatus"],
isValidSubscription: json["isValidSubscription"],
userId: json["userID"],
isFavorite: json["isFavorite"] ?? false,
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"],
vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"],
customerName: json["customerName"],
customerName: json["customerName"] ?? "",
customerID: json["customerUserID"],
serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"],

@ -49,6 +49,8 @@ abstract class AppointmentRepo {
Future<GenericRespModel> createServiceAppointment({required List<ServiceAppointmentScheduleModel> schedules, required int serviceProviderID});
Future<GenericRespModel> cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction});
Future<GenericRespModel> addProviderToFavourite({required int providerID});
}
class AppointmentRepoImp implements AppointmentRepo {
@ -250,4 +252,17 @@ class AppointmentRepoImp implements AppointmentRepo {
String t = appState.getUser.data!.accessToken ?? "";
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: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/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
@ -73,6 +74,12 @@ abstract class BranchRepo {
double? latitude,
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 {
@ -273,6 +280,13 @@ class BranchRepoImp implements BranchRepo {
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
Future<List<ItemData>> getServiceItems(int serviceId) async {
var queryParameters = {
@ -345,4 +359,31 @@ class BranchRepoImp implements BranchRepo {
List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
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<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});
}
@ -37,11 +39,21 @@ class RequestRepoImp implements RequestRepo {
}
@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(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getRequest,
postParams,
paramsForGetRequests,
token: appState.getUser.data!.accessToken,
);
List<RequestModel> requests = List.generate(
@ -53,6 +65,26 @@ class RequestRepoImp implements RequestRepo {
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
Future<List<OffersModel>> getOffersByRequest({required int requestId, int serviceProviderId = 0}) async {
var queryParameters = {

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

@ -175,8 +175,7 @@ class AdVM extends BaseVM {
if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) {
return;
}
log("myAdsEnums: ${myAdsEnums.length}");
log("exploreAdsEnums: ${exploreAdsEnums.length}");
if (myAdsEnums.isEmpty) {
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));
logger.i("myAdsEnums: ${myAdsEnums.length}");
logger.i("exploreAdsEnums: ${exploreAdsEnums.length}");
notifyListeners();
}
@ -409,6 +406,7 @@ class AdVM extends BaseVM {
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId);
isFetchingLists = false;
notifyListeners();
}
@ -497,7 +495,6 @@ class AdVM extends BaseVM {
return;
}
vehicleBrandId = id;
logger.i("message: ${vehicleBrandId.selectedOption}");
await getVehicleDetailsByVehicleBrandId();
notifyListeners();
@ -1210,7 +1207,7 @@ class AdVM extends BaseVM {
vehicleAdsSpecialServices.clear();
currentProgressStep = AdCreationSteps.vehicleDetails;
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
// vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = 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: "");
vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleDemandAmount = "";
vehicleVin = "";
vehicleTitle = "";
@ -1679,11 +1675,13 @@ class AdVM extends BaseVM {
///// Edit Work Amir
void onEditUpdateAdPressed(BuildContext context, AdDetailsModel previousDetails) {
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) {
isAdEditEnabled = true;
previousAdDetails = previousDetails;
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 {
@ -1707,6 +1705,7 @@ class AdVM extends BaseVM {
await getVehicleAdsDuration();
}
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!);
if (index != -1) {
updateVehicleAdDurationId(
@ -1743,13 +1742,12 @@ class AdVM extends BaseVM {
updateSelectionVehicleColorId(SelectionModel(selectedId: previousAdDetails!.vehicle!.color!.id!, selectedOption: previousAdDetails!.vehicle!.color!.label ?? ""));
updateSelectionVehicleConditionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.condition!.id!, selectedOption: previousAdDetails!.vehicle!.condition!.label ?? ""));
updateSelectionVehicleCategoryId(SelectionModel(selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: previousAdDetails!.vehicle!.category!.label ?? ""));
updateSelectionVehicleMileageId(SelectionModel(
selectedId: previousAdDetails!.vehicle!.mileage!.id!, selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}"));
updateSelectionVehicleMileageId(SelectionModel(selectedId: previousAdDetails!.vehicle!.mileage!.id!, selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}"));
updateSelectionVehicleTransmissionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.transmission!.id!, selectedOption: previousAdDetails!.vehicle!.transmission!.label ?? ""));
updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: previousAdDetails!.vehicle!.sellertype!.id!, selectedOption: previousAdDetails!.vehicle!.sellertype!.label ?? ""));
int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID);
if (indexCountry != -1) {
updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[index].id!, selectedOption: vehicleCountries[index].countryName ?? ""));
updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[indexCountry].id!, selectedOption: vehicleCountries[indexCountry].countryName ?? ""));
}
updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? ""));
@ -1759,6 +1757,7 @@ class AdVM extends BaseVM {
vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString();
financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
pickedPostingImages.clear();
if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
for (var element in previousAdDetails!.vehicle!.image!) {
if (element.imageUrl != null) {
@ -1815,7 +1814,6 @@ class AdVM extends BaseVM {
}
isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null;
logger.i("previousAdDetails!: $previousAdDetails");
notifyListeners();
}
@ -1846,10 +1844,9 @@ class AdVM extends BaseVM {
adsChatBuyerId: 1,
adID: adDetailsModel.id,
userID: myUserID,
senderName: adDetailsModel.adOwnerName,
)
.whenComplete(
() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments),
);
.whenComplete(() => 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/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_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/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
@ -161,7 +162,7 @@ class AppointmentsVM extends BaseVM {
}
}
} catch (e) {
Utils.showToast("${e.toString()}");
Utils.showToast(e.toString());
}
}
@ -238,7 +239,9 @@ class AppointmentsVM extends BaseVM {
}
void removeServiceInCurrentAppointment(int index) {
int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1;
int serviceId = servicesInCurrentAppointment
.elementAt(index)
.serviceProviderServiceId ?? -1;
allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId);
servicesInCurrentAppointment.removeAt(index);
notifyListeners();
@ -382,9 +385,7 @@ class AppointmentsVM extends BaseVM {
}
}
Future<void> getMyAppointmentsForProvider(
Map<String, dynamic> map,
) async {
Future<void> getMyAppointmentsForProvider(Map<String, dynamic> map) async {
setState(ViewState.busy);
myAppointments = await appointmentRepo.getMyAppointmentsForProvider(map);
myFilteredAppointments = myAppointments;
@ -434,7 +435,7 @@ class AppointmentsVM extends BaseVM {
updateCheckBoxInMergeRequest(int currentIndex) {
myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected =
!(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false);
!(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false);
int count = countSelected(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList ?? []);
if (count > 1)
@ -445,7 +446,10 @@ class AppointmentsVM extends BaseVM {
}
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}) {
@ -531,6 +535,7 @@ class AppointmentsVM extends BaseVM {
}
Future<List<ItemData>> getServiceItems(int serviceId) async {
setState(ViewState.busy);
serviceItemsFromApi.clear();
serviceItemsFromApi = await branchRepo.getServiceItems(serviceId);
for (var item in serviceItemsFromApi) {
@ -612,13 +617,14 @@ class AppointmentsVM extends BaseVM {
Column(
children: List.generate(
selectedService.serviceItems!.length,
(index) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true),
],
),
(index) =>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true),
],
),
),
),
Row(
@ -654,8 +660,8 @@ class AppointmentsVM extends BaseVM {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
(selectedService.isHomeSelected
? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}"
: "${selectedService.currentTotalServicePrice}")
? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}"
: "${selectedService.currentTotalServicePrice}")
.toText(fontSize: 29, isBold: true),
2.width,
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 = [];
// 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 {
if (branchesFilterOptions.isNotEmpty) return;
branchesFilterOptions.clear();
@ -853,7 +846,7 @@ class AppointmentsVM extends BaseVM {
Future<void> getMyRecentBranches({bool isNeedToRebuild = false}) async {
myRecentBranches.clear();
if (isNeedToRebuild) setState(ViewState.busy);
myRecentBranches = await branchRepo.getAllNearBranchAndServices();
myRecentBranches = await branchRepo.getMyRecentBranchesWithServices();
setState(ViewState.idle);
}
@ -1086,10 +1079,10 @@ class AppointmentsVM extends BaseVM {
DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
""),
);
@ -1433,4 +1426,33 @@ class AppointmentsVM extends BaseVM {
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
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 true;
}
@ -454,7 +453,7 @@ class ChatVM extends ChangeNotifier {
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 {
Utils.showLoading(context);
currentMessagesForAds = await chatRepo.getUsersChatMessagesForAds(userID: userID, adID: adID, isForBuyer: isForBuyer, adsChatBuyerId: adsChatBuyerId);
@ -463,6 +462,7 @@ class ChatVM extends ChangeNotifier {
List<int> unreadMessageIds = [];
for (var msg in currentMessagesForAds) {
msg.senderName = senderName ?? "";
if (!msg.isRead!) {
unreadMessageIds.add(msg.id!);
}

@ -64,27 +64,26 @@ class RequestsVM extends BaseVM {
Future<void> getRequests({bool isNeedToRebuild = false, required AppType appType}) async {
if (isNeedToRebuild) setState(ViewState.busy);
var paramsForGetRequests = <String, dynamic>{};
paramsForGetRequests = {
"pageSize": 100,
"pageIndex": 0,
// "requestType": 0,
};
int providerOrCustomerID = 0;
if (appType == AppType.provider) {
paramsForGetRequests.addEntries([MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)]);
providerOrCustomerID = AppState().getUser.data!.userInfo!.providerId ?? 0;
} 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);
setState(ViewState.idle);
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}) {
log("msg: $msg");
log("index: $index");
myFilteredRequests[index].chatMessages.add(msg);
notifyListeners();
}
@ -102,12 +101,16 @@ class RequestsVM extends BaseVM {
notifyListeners();
}
applyFilterOnRequestsVM({required RequestsTypeEnum requestsTypeEnum}) {
applyFilterOnRequestsVM({required RequestsTypeEnum requestsTypeEnum}) async {
if (requestsTypeFilterOptions.isEmpty) return;
for (var value in requestsTypeFilterOptions) {
value.isSelected = false;
}
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();
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/string_extensions.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/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_special_service_sheet.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/extensions/extensions_widget.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 {
const AdDuration({Key? key}) : super(key: key);
void onAddServiceButtonTapped(BuildContext context, AdVM adVM) {
void onAddSpecialServiceButtonTapped(BuildContext context, AdVM adVM) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
@ -228,7 +227,7 @@ class AdDuration extends StatelessWidget {
needsBorder: true,
bgColor: MyColors.white,
onTap: () {
onAddServiceButtonTapped(context, adVM);
onAddSpecialServiceButtonTapped(context, adVM);
},
text: LocaleKeys.addService.tr(),
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/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
@ -78,7 +78,7 @@ class VehicleDetailsReview extends StatelessWidget {
16.height,
SingleDetailWidget(text: adVM.vehicleVin, type: LocaleKeys.vehicleVIN.tr()),
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,
],
),
@ -111,7 +111,7 @@ class VehicleDetailsReview extends StatelessWidget {
),
SingleDetailWidget(text: adVM.vehicleDescription, type: LocaleKeys.description.tr()),
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) ...[
// 10.height,
PickedFilesContainer(
@ -142,7 +142,7 @@ class DamagePartsReview extends StatelessWidget {
],
),
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(
pickedFiles: adVM.vehicleDamageCards[index].partImages!,
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/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/views/advertisement/network_images_container.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_damage_parts_selection_sheet.dart';
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.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:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
@ -32,7 +31,7 @@ class DamageParts extends StatelessWidget {
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return const BottomSheetListContent();
return const AdDamagePartsSelectionSheet();
});
}
@ -131,7 +130,6 @@ class DamageParts extends StatelessWidget {
],
).paddingOnly(right: 10)
],
],
).toWhiteContainer(
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/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/network_images_container.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/views/advertisement/components/network_images_container_widget.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/extensions/extensions_widget.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:developer';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.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/view_models/ad_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/ads_images_slider.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.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/widgets/bottom_sheet.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> {
late AdVM adVM;
late List<VehicleDamageCard> damagePartsPictures;
@override
void initState() {
adVM = context.read<AdVM>();
damagePartsPictures = [];
scheduleMicrotask(() {
onAdDetailsLoaded();
populateDamagePartPictures();
});
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) {
return actionConfirmationBottomSheet(
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
Widget build(BuildContext context) {
return Scaffold(
@ -128,173 +341,16 @@ class _AdsDetailViewState extends State<AdsDetailView> {
child: ListView(
shrinkWrap: true,
children: [
Column(
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),
buildVehicleDetailsWidget(),
12.height,
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();
}),
buildBankDetailsIfAvailable(),
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) ...[
buildDamagePartDetails(),
],
12.height,
if (widget.adDetails.adPostStatus == AdPostStatus.rejected)
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, 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),
if (widget.adDetails.adPostStatus == AdPostStatus.rejected) ...[
buildAdRejectionDetails(),
],
],
),
),
@ -533,13 +589,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
),
if (adDetailsModel.whatsAppNo == null) ...[
8.width,
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(() {
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(() {
Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? "");
}),
],
@ -1155,12 +1205,12 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: () {
Navigator.pop(context);
adVM.updateSelectionVehicleTypeId(
SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""),
);
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: true));
onPressed: () async {
Utils.showLoading(context);
await adVM.getVehicleTypes();
await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: adDetailsModel.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
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: ""),
);
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:easy_localization/easy_localization.dart';
class AdDurationSelectionSheetContent extends StatelessWidget {
class AdDurationSelectionSheet extends StatelessWidget {
final bool isFromExtendAd;
final bool isUpdateAdSelected;
const AdDurationSelectionSheetContent(
{super.key,
required this.isFromExtendAd,
required this.isUpdateAdSelected});
const AdDurationSelectionSheet({super.key, required this.isFromExtendAd, required this.isUpdateAdSelected});
@override
Widget build(BuildContext context) {
@ -33,10 +30,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
children: [
Row(
children: [
LocaleKeys.selectDuration
.tr()
.toText(fontSize: 22, isBold: true)
.paddingOnly(top: 10, left: 21, right: 21),
LocaleKeys.selectDuration.tr().toText(fontSize: 22, isBold: true).paddingOnly(top: 10, left: 21, right: 21),
],
),
Expanded(
@ -56,32 +50,22 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
("${adDuration.days}${LocaleKeys.daysVar.tr()}")
.toString()
.toText(fontSize: 16, isBold: true),
("${adDuration.days}${LocaleKeys.daysVar.tr()}").toString().toText(fontSize: 16, isBold: true),
4.height,
"Your Ad will be active for ${adDuration.days} Days and then you will need to extend it to keep it active. "
.toText(
"Your Ad will be active for ${adDuration.days} Days and then you will need to extend it to keep it active. ".toText(
fontSize: 14,
color: MyColors.lightTextColor,
),
12.height,
LocaleKeys.adCharges.tr().toText(
fontSize: 14,
color: MyColors.lightTextColor,
isBold: true),
LocaleKeys.adCharges.tr().toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${adDuration.price}"
.toText(fontSize: 22, isBold: true),
"${adDuration.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),
child: LocaleKeys.sar.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
],
),
@ -92,16 +76,14 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
).toWhiteContainer(
width: double.infinity,
allPading: 12,
isBorderRequired:
adDuration.id == adVM.vehicleAdDurationId.selectedId,
isBorderRequired: adDuration.id == adVM.vehicleAdDurationId.selectedId,
),
).onPress(() {
if (isFromExtendAd) {
adVM.updateVehicleExtendAdDurationId(
SelectionModel(
selectedId: adDuration.id ?? 0,
selectedOption:
("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
selectedOption: ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
itemPrice: adDuration.price!.toInt().toString(),
),
);
@ -110,8 +92,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
adVM.updateVehicleAdDurationId(
SelectionModel(
selectedId: adDuration.id ?? 0,
selectedOption:
("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
selectedOption: ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"),
itemPrice: adDuration.price!.toInt().toString(),
),
);
@ -142,8 +123,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
return;
} else {
if (isFromExtendAd && !isUpdateAdSelected) {
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.extendAds);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.extendAds);
return;
}
navigateReplaceWithName(context, AppRoutes.createAdView);
@ -155,8 +135,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget {
);
}
Widget showItem(String item, String value,
{Color valueColor = Colors.black}) {
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,

@ -15,14 +15,14 @@ import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
import 'package:easy_localization/easy_localization.dart';
class BottomSheetListContent extends StatefulWidget {
const BottomSheetListContent({Key? key}) : super(key: key);
class BottomSheetAdDamagePartsContent extends StatefulWidget {
const BottomSheetAdDamagePartsContent({Key? key}) : super(key: key);
@override
State<BottomSheetListContent> createState() => _BottomSheetListContentState();
State<BottomSheetAdDamagePartsContent> createState() => _BottomSheetAdDamagePartsContentState();
}
class _BottomSheetListContentState extends State<BottomSheetListContent> {
class _BottomSheetAdDamagePartsContentState extends State<BottomSheetAdDamagePartsContent> {
bool checkBoxValue = false;
@override
@ -207,8 +207,7 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
(DropValue value) => adVM.updateVehicleAdsSpecialServicesId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: vehicleAdsSpecialServices,
hint: LocaleKeys.selectService.tr(),
dropdownValue:
adVM.vehicleAdsSpecialServicesId.selectedId != -1 ? DropValue(adVM.vehicleAdsSpecialServicesId.selectedId, adVM.vehicleAdsSpecialServicesId.selectedOption, "") : null,
dropdownValue: 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) ...[
descriptionCard(
description:
adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "Some Dummy Service Description!!",
description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "Some Dummy Service Description!!",
),
],
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/theme/colors.dart';
class CarouselWithIndicatorDemo extends StatefulWidget {
class AdImagesCorouselWidget extends StatefulWidget {
final List<AdImage> vehicleImages;
const CarouselWithIndicatorDemo({super.key, required this.vehicleImages});
const AdImagesCorouselWidget({super.key, required this.vehicleImages});
@override
State<StatefulWidget> createState() => _CarouselWithIndicatorState();
}
class _CarouselWithIndicatorState extends State<CarouselWithIndicatorDemo> {
class _CarouselWithIndicatorState extends State<AdImagesCorouselWidget> {
int _current = 0;
final CarouselController _controller = CarouselController();

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

@ -68,10 +68,10 @@ class CreateAdProgressSteps extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
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.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.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.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),
],
),
],

@ -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: [
isPdf
? Container(
height: 72,
width: 70,
height: 75,
width: 73,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
@ -121,8 +110,8 @@ class BuildFilesContainer extends StatelessWidget {
? Image.network(
image.filePath!,
fit: BoxFit.fill,
height: 72,
width: 70,
height: 75,
width: 73,
).paddingAll(8)
: Image.file(
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/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/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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class CreateAdView extends StatefulWidget {
const CreateAdView({Key? key}) : super(key: key);
@ -37,7 +36,7 @@ class _CreateAdViewState extends State<CreateAdView> {
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: adVM.isAdEditEnabled ? LocaleKeys.updateAd.tr(): LocaleKeys.createAd.tr(),
title: adVM.isAdEditEnabled ? LocaleKeys.updateAd.tr() : LocaleKeys.createAd.tr(),
isRemoveBackButton: false,
isDrawerEnabled: false,
onBackButtonTapped: () => adVM.onBackButtonPressed(context),

@ -1,30 +1,26 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/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/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_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/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class SelectAdTypeView extends StatelessWidget {
final bool isProvider;
final List<bool> arguments; // [0] isProviderOrCustomer [1] isFromExtendAd
const SelectAdTypeView({
Key? key,
this.isProvider = true,
}) : super(key: key);
const SelectAdTypeView({Key? key, required this.arguments}) : super(key: key);
Widget getVehicleAdTypeIcon(VehicleType 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
Widget build(BuildContext context) {
bool isProvider = arguments[0];
bool isFromExtendAd = arguments[1];
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.selectAdType.tr(),
@ -79,14 +59,12 @@ class SelectAdTypeView extends StatelessWidget {
VehicleTypeModel vehicleTypeModel = adVM.vehicleTypes[index];
return InkWell(
onTap: () {
adVM.updateSelectionVehicleTypeId(
SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""),
);
adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""));
if (adVM.isAdEditEnabled) {
adVM.autoFillSelectedVehicleAdsDuration();
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(
width: double.infinity,
@ -110,7 +88,7 @@ class SelectAdTypeView extends StatelessWidget {
Row(
children: [
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),
] 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) {
@ -160,7 +138,7 @@ class SelectAdTypeView extends StatelessWidget {
LocaleKeys.adsRemainingVar.tr().toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true),
],
),
Text.rich(
Text.rich(
TextSpan(
children: [
TextSpan(

@ -24,7 +24,7 @@ class ScreenArgumentsForAppointmentDetailPage {
class BookAppointmentSchedulesView extends StatelessWidget {
final ScreenArgumentsForAppointmentDetailPage screenArgumentsForAppointmentDetailPage;
BookAppointmentSchedulesView({Key? key, required this.screenArgumentsForAppointmentDetailPage}) : super(key: key);
const BookAppointmentSchedulesView({Key? key, required this.screenArgumentsForAppointmentDetailPage}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -47,14 +47,14 @@ class BookAppointmentSchedulesView extends StatelessWidget {
itemBuilder: (BuildContext context, int scheduleIndex) {
ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex];
return ExpansionTile(
tilePadding: EdgeInsets.symmetric(horizontal: 21, vertical: 10),
childrenPadding: EdgeInsets.only(left: 16, bottom: 10, right: 16),
tilePadding: const EdgeInsets.symmetric(horizontal: 21, vertical: 10),
childrenPadding: const EdgeInsets.only(left: 16, bottom: 10, right: 16),
title: Column(
children: [
Row(
children: [
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,
children: [
(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(
@ -70,7 +70,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
children: [
5.height,
ListView.builder(
physics: NeverScrollableScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].servicesListInAppointment!.length,
itemBuilder: (BuildContext context, int serviceIndex) {

@ -1,6 +1,4 @@
import 'package:flutter/foundation.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/string_extensions.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/theme/colors.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/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:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class BookAppointmentServicesView extends StatelessWidget {
BookAppointmentServicesView({Key? key}) : super(key: key);
const BookAppointmentServicesView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -31,8 +29,7 @@ class BookAppointmentServicesView extends StatelessWidget {
},
),
body: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -40,14 +37,12 @@ class BookAppointmentServicesView extends StatelessWidget {
CustomAddButton(
needsBorder: true,
bgColor: MyColors.white,
onTap: () => appointmentsVM.openTheAddServiceBottomSheet(
context, appointmentsVM),
onTap: () => appointmentsVM.openTheAddServiceBottomSheet(context, appointmentsVM),
text: LocaleKeys.addServices.tr(),
icon: Container(
height: 24,
width: 24,
decoration: const BoxDecoration(
shape: BoxShape.circle, color: MyColors.darkTextColor),
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: const Icon(Icons.add, color: MyColors.white),
),
).horPaddingMain(),
@ -56,56 +51,34 @@ class BookAppointmentServicesView extends StatelessWidget {
shrinkWrap: true,
itemCount: appointmentsVM.servicesInCurrentAppointment.length,
itemBuilder: (BuildContext context, int serviceIndex) {
ServiceModel serviceData = appointmentsVM
.servicesInCurrentAppointment[serviceIndex];
ServiceModel serviceData = appointmentsVM.servicesInCurrentAppointment[serviceIndex];
return Column(
children: [
Row(
children: [
Expanded(
child: (serviceData.serviceDescription ?? "")
.toText(fontSize: 15, isBold: true),
child: (serviceData.serviceDescription ?? "").toText(fontSize: 15, isBold: true),
),
IconButton(
onPressed: () => appointmentsVM
.removeServiceInCurrentAppointment(
serviceIndex),
icon: Icon(Icons.delete_outline,
color: MyColors.redColor),
)
IconButton(onPressed: () => appointmentsVM.removeServiceInCurrentAppointment(serviceIndex), icon: const Icon(Icons.delete_outline, color: MyColors.redColor))
],
),
if (true) ...[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(LocaleKeys.serviceLocation.tr()).toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
(serviceData.isHomeSelected
? serviceData.homeLocation
: LocaleKeys.workshop.tr())
.toText(fontSize: 12, isBold: true)
.expand(),
(LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
(serviceData.isHomeSelected ? serviceData.homeLocation : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(),
],
),
5.height,
Column(
children: List.generate(
serviceData.serviceItems!.length, (itemIndex) {
ItemData itemData =
serviceData.serviceItems![itemIndex];
children: List.generate(serviceData.serviceItems!.length, (itemIndex) {
ItemData itemData = serviceData.serviceItems![itemIndex];
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${itemData.name}: ".toText(
fontSize: 13,
color: MyColors.lightTextColor,
isBold: true),
("${itemData.price}")
.toText(fontSize: 13, isBold: true)
.expand(),
"${itemData.name}: ".toText(fontSize: 13, color: MyColors.lightTextColor, isBold: true),
("${itemData.price}").toText(fontSize: 13, isBold: true).expand(),
],
);
}),
@ -114,33 +87,15 @@ class BookAppointmentServicesView extends StatelessWidget {
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
((appointmentsVM
.servicesInCurrentAppointment[
serviceIndex]
.currentTotalServicePrice)
.toString())
.toText(fontSize: 32, isBold: true),
((appointmentsVM.servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice).toString()).toText(fontSize: 32, isBold: true),
2.width,
LocaleKeys.sar
.tr()
.toText(
color: MyColors.lightTextColor,
fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
Icon(Icons.arrow_drop_down, size: 30)
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
const Icon(Icons.arrow_drop_down, size: 30)
],
).onPress(() => appointmentsVM.priceBreakDownClicked(
context,
appointmentsVM
.servicesInCurrentAppointment[serviceIndex])),
).onPress(() => appointmentsVM.priceBreakDownClicked(context, appointmentsVM.servicesInCurrentAppointment[serviceIndex])),
],
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(
horizontal: 21, vertical: 10));
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10));
},
).expand(),
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/view_models/appointments_view_model.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:provider/provider.dart';
@ -223,8 +223,7 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "")
.toText(color: MyColors.black, isBold: true, fontSize: 16),
(AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16),
Row(
children: [
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/navigator.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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
@ -102,10 +102,10 @@ class AdsFragment extends StatelessWidget {
if (adVM.adsFiltersCounter == 0) ...[
16.height,
FiltersList(
filterList: adVM.exploreAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()),
needLeftPadding: false)
.paddingOnly(left: 21),
filterList: adVM.exploreAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()),
needLeftPadding: false,
).paddingOnly(left: 21),
]
] else ...[
16.height,
@ -126,7 +126,7 @@ class AdsFragment extends StatelessWidget {
await adVM.getExploreAds();
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(
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,
child: const Icon(Icons.add, color: MyColors.white),

@ -53,7 +53,7 @@ class MyRequestsFragment extends StatelessWidget {
)
: ListView.separated(
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) {
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/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/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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';

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

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

Loading…
Cancel
Save