Merge remote-tracking branch 'origin/mirza_development' into faiz_development
# Conflicts: # lib/config/customer_dependencies.dart # lib/config/customer_routes.dart # lib/main.dart # lib/views/dashboard/dashboard_page.dartaamir_dev
commit
a47cae92f2
@ -0,0 +1,138 @@
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
|
||||
class Request {
|
||||
int requestType;
|
||||
String requestTypeName;
|
||||
String requestStatusName;
|
||||
RequestStatus requestStatus;
|
||||
String cityName;
|
||||
String vehicleTypeName;
|
||||
String countryName;
|
||||
String customerName;
|
||||
dynamic serviceProviders;
|
||||
int offerCount;
|
||||
int id;
|
||||
int customerId;
|
||||
dynamic customer;
|
||||
String brand;
|
||||
String model;
|
||||
int year;
|
||||
bool isNew;
|
||||
String description;
|
||||
List<dynamic> requestImages;
|
||||
int cityId;
|
||||
dynamic city;
|
||||
double price;
|
||||
int paymentStatus;
|
||||
int vehicleTypeId;
|
||||
int countryId;
|
||||
List<dynamic> requestProviderItem;
|
||||
bool isActive;
|
||||
int createdBy;
|
||||
DateTime createdOn;
|
||||
dynamic modifiedBy;
|
||||
dynamic modifiedOn;
|
||||
|
||||
Request({
|
||||
required this.requestType,
|
||||
required this.requestTypeName,
|
||||
required this.requestStatusName,
|
||||
required this.requestStatus,
|
||||
required this.cityName,
|
||||
required this.vehicleTypeName,
|
||||
required this.countryName,
|
||||
required this.customerName,
|
||||
required this.serviceProviders,
|
||||
required this.offerCount,
|
||||
required this.id,
|
||||
required this.customerId,
|
||||
required this.customer,
|
||||
required this.brand,
|
||||
required this.model,
|
||||
required this.year,
|
||||
required this.isNew,
|
||||
required this.description,
|
||||
required this.requestImages,
|
||||
required this.cityId,
|
||||
required this.city,
|
||||
required this.price,
|
||||
required this.paymentStatus,
|
||||
required this.vehicleTypeId,
|
||||
required this.countryId,
|
||||
required this.requestProviderItem,
|
||||
required this.isActive,
|
||||
required this.createdBy,
|
||||
required this.createdOn,
|
||||
required this.modifiedBy,
|
||||
required this.modifiedOn,
|
||||
});
|
||||
|
||||
factory Request.fromJson(Map<String, dynamic> json) => Request(
|
||||
requestType: json["requestType"],
|
||||
requestTypeName: json["requestTypeName"],
|
||||
requestStatusName: json["requestStatusName"],
|
||||
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
|
||||
cityName: json["cityName"],
|
||||
vehicleTypeName: json["vehicleTypeName"],
|
||||
countryName: json["countryName"],
|
||||
customerName: json["customerName"],
|
||||
serviceProviders: json["serviceProviders"],
|
||||
offerCount: json["offerCount"],
|
||||
id: json["id"],
|
||||
customerId: json["customerID"],
|
||||
customer: json["customer"],
|
||||
brand: json["brand"],
|
||||
model: json["model"],
|
||||
year: json["year"],
|
||||
isNew: json["isNew"],
|
||||
description: json["description"],
|
||||
requestImages: List<dynamic>.from(json["requestImages"].map((x) => x)),
|
||||
cityId: json["cityID"],
|
||||
city: json["city"],
|
||||
price: json["price"],
|
||||
paymentStatus: json["paymentStatus"],
|
||||
vehicleTypeId: json["vehicleTypeID"],
|
||||
countryId: json["countryID"],
|
||||
requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)),
|
||||
isActive: json["isActive"],
|
||||
createdBy: json["createdBy"],
|
||||
createdOn: DateTime.parse(json["createdOn"]),
|
||||
modifiedBy: json["modifiedBy"],
|
||||
modifiedOn: json["modifiedOn"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"requestType": requestType,
|
||||
"requestTypeName": requestTypeName,
|
||||
"requestStatusName": requestStatusName,
|
||||
"requestStatus": requestStatus,
|
||||
"cityName": cityName,
|
||||
"vehicleTypeName": vehicleTypeName,
|
||||
"countryName": countryName,
|
||||
"customerName": customerName,
|
||||
"serviceProviders": serviceProviders,
|
||||
"offerCount": offerCount,
|
||||
"id": id,
|
||||
"customerID": customerId,
|
||||
"customer": customer,
|
||||
"brand": brand,
|
||||
"model": model,
|
||||
"year": year,
|
||||
"isNew": isNew,
|
||||
"description": description,
|
||||
"requestImages": List<dynamic>.from(requestImages.map((x) => x)),
|
||||
"cityID": cityId,
|
||||
"city": city,
|
||||
"price": price,
|
||||
"paymentStatus": paymentStatus,
|
||||
"vehicleTypeID": vehicleTypeId,
|
||||
"countryID": countryId,
|
||||
"requestProviderItem": List<dynamic>.from(requestProviderItem.map((x) => x)),
|
||||
"isActive": isActive,
|
||||
"createdBy": createdBy,
|
||||
"createdOn": createdOn.toIso8601String(),
|
||||
"modifiedBy": modifiedBy,
|
||||
"modifiedOn": modifiedOn,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
import 'package:car_customer_app/model/request.dart';
|
||||
import 'package:mc_common_app/api/api_client.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/config/dependencies.dart';
|
||||
import 'package:mc_common_app/models/generic_resp_model.dart';
|
||||
|
||||
abstract class RequestRepo {
|
||||
Future<GenericRespModel> createRequest(Map<String, dynamic> map);
|
||||
|
||||
Future<List<Request>> getRequests(Map<String, dynamic> postParams);
|
||||
}
|
||||
|
||||
class RequestRepoImp implements RequestRepo {
|
||||
ApiClient apiClient = injector.get<ApiClient>();
|
||||
AppState appState = injector.get<AppState>();
|
||||
|
||||
@override
|
||||
Future<GenericRespModel> createRequest(Map<String, dynamic> postParams) async {
|
||||
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
|
||||
(json) => GenericRespModel.fromJson(json),
|
||||
ApiConsts.createRequest,
|
||||
postParams,
|
||||
token: appState.getUser.data!.accessToken,
|
||||
);
|
||||
return enumGenericModel;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Request>> getRequests(Map<String, dynamic> postParams) async {
|
||||
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
|
||||
(json) => GenericRespModel.fromJson(json),
|
||||
ApiConsts.getRequest,
|
||||
postParams,
|
||||
token: appState.getUser.data!.accessToken,
|
||||
);
|
||||
List<Request> requests = List.generate(
|
||||
enumGenericModel.data.length,
|
||||
(index) => Request.fromJson(
|
||||
enumGenericModel.data[index],
|
||||
),
|
||||
);
|
||||
return requests;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,272 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:car_customer_app/repositories/request_repo.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
|
||||
import 'package:mc_common_app/models/enums.dart';
|
||||
import 'package:mc_common_app/models/generic_resp_model.dart';
|
||||
import 'package:mc_common_app/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/services/common_services.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
|
||||
import '../model/request.dart';
|
||||
|
||||
class RequestsVM extends BaseVM {
|
||||
final CommonAppServices commonServices;
|
||||
final CommonRepo commonRepo;
|
||||
final RequestRepo requestRepo;
|
||||
|
||||
RequestsVM({required this.commonServices, required this.commonRepo, required this.requestRepo});
|
||||
|
||||
List<FilterListModel> requestsFilterOptions = [];
|
||||
|
||||
populateRequestsFilterList() {
|
||||
requestsFilterOptions.clear();
|
||||
requestsFilterOptions = [
|
||||
FilterListModel(title: "Cars", isSelected: true, id: 1),
|
||||
FilterListModel(title: "Spare Parts", isSelected: false, id: 2),
|
||||
];
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
applyFilterOnRequestsVM({required int index}) {
|
||||
if (requestsFilterOptions.isEmpty) return;
|
||||
for (var value in requestsFilterOptions) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
requestsFilterOptions[index].isSelected = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<File> pickedVehicleImages = [];
|
||||
String vehicleImageError = "";
|
||||
|
||||
void removeImageFromList(String filePath) {
|
||||
int index = pickedVehicleImages.indexWhere((element) => element.path == filePath);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
pickedVehicleImages.removeAt(index);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void pickMultipleImages() async {
|
||||
List<File> Images = await commonServices.pickMultipleImages();
|
||||
pickedVehicleImages.addAll(Images);
|
||||
if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool isFetchingRequestType = false;
|
||||
bool isFetchingVehicleType = true;
|
||||
bool isFetchingVehicleDetail = false;
|
||||
List<Enums> requestTypes = [];
|
||||
List<VehicleTypeModel> vehicleTypes = [];
|
||||
VehicleDetailsModel? vehicleDetails;
|
||||
List<VehicleBrandsModel> vehicleBrands = [];
|
||||
List<VehicleModel> vehicleModels = [];
|
||||
List<VehicleYearModel> vehicleModelYears = [];
|
||||
List<VehicleCountryModel> vehicleCountries = [];
|
||||
List<VehicleCityModel> vehicleCities = [];
|
||||
|
||||
SelectionModel requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
getRequestTypes() async {
|
||||
requestTypeId.selectedId = -1;
|
||||
isFetchingRequestType = true;
|
||||
requestTypes = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 16 is to get Request types
|
||||
isFetchingRequestType = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateSelectionRequestTypeId(SelectionModel id) async {
|
||||
requestTypeId = id;
|
||||
getVehicleTypes();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
Future<void> getVehicleTypes() async {
|
||||
reset();
|
||||
isFetchingVehicleType = true;
|
||||
vehicleTypes = await commonRepo.getVehicleTypes();
|
||||
isFetchingVehicleType = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
reset() {
|
||||
vehicleTypeId.selectedId = -1;
|
||||
vehicleBrandId.selectedId = -1;
|
||||
vehicleModelId.selectedId = -1;
|
||||
vehicleModelYearId.selectedId = -1;
|
||||
vehicleCountryId.selectedId = -1;
|
||||
vehicleCityId.selectedId = -1;
|
||||
}
|
||||
|
||||
void updateSelectionVehicleTypeId(SelectionModel id) async {
|
||||
vehicleTypeId = id;
|
||||
getVehicleBrandsByVehicleTypeId();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getVehicleBrandsByVehicleTypeId() async {
|
||||
// if (vehicleBrandId.selectedId == -1) {
|
||||
// return;
|
||||
// }
|
||||
isFetchingVehicleDetail = true;
|
||||
notifyListeners();
|
||||
vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId);
|
||||
|
||||
if (vehicleDetails != null) {
|
||||
vehicleBrands = vehicleDetails!.vehicleBrands!;
|
||||
vehicleModels = vehicleDetails!.vehicleModels!;
|
||||
vehicleModelYears = vehicleDetails!.vehicleModelYears!;
|
||||
vehicleCountries = vehicleDetails!.vehicleCountries!;
|
||||
}
|
||||
isFetchingVehicleDetail = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateSelectionVehicleBrandId(SelectionModel id) {
|
||||
vehicleBrandId = id;
|
||||
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateSelectionVehicleModelId(SelectionModel id) {
|
||||
vehicleModelId = id;
|
||||
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateSelectionVehicleModelYearId(SelectionModel id) {
|
||||
vehicleModelYearId = id;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool isShippingDeliveryEnabled = false;
|
||||
|
||||
void updateShippingDeliverEnabled(bool v) {
|
||||
isShippingDeliveryEnabled = v;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool isCountryFetching = false;
|
||||
SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateSelectionVehicleCountryId(SelectionModel id) async {
|
||||
vehicleCountryId = id;
|
||||
isCountryFetching = true;
|
||||
notifyListeners();
|
||||
vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
|
||||
isCountryFetching = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
|
||||
|
||||
void updateSelectionVehicleCityId(SelectionModel id) {
|
||||
vehicleCityId = id;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
//Request Management
|
||||
String price = "", description = "";
|
||||
|
||||
updatePrice(String v) {
|
||||
price = v;
|
||||
}
|
||||
|
||||
updateDescription(String v) {
|
||||
description = v;
|
||||
}
|
||||
|
||||
Future<GenericRespModel?> createRequest() async {
|
||||
if (validate()) {
|
||||
Map<String, dynamic> m = {
|
||||
"customerID": AppState().getUser.data!.userInfo!.customerId ?? 0,
|
||||
"requestType": requestTypeId.selectedId,
|
||||
"vehicleTypeID": vehicleTypeId.selectedId,
|
||||
"brand": vehicleBrandId.selectedOption,
|
||||
"model": vehicleModelId.selectedOption,
|
||||
"year": vehicleModelYearId.selectedOption,
|
||||
"isNew": true,
|
||||
"countryID": vehicleCountryId.selectedId,
|
||||
"cityID": vehicleCityId.selectedId,
|
||||
"price": price,
|
||||
"description": description,
|
||||
"isSpecialServiceNeeded": false,
|
||||
"requestImages": []
|
||||
};
|
||||
GenericRespModel respModel = await requestRepo.createRequest(m);
|
||||
return respModel;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool validate() {
|
||||
bool isValid = true;
|
||||
if (requestTypeId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Request Type");
|
||||
isValid = false;
|
||||
} else if (vehicleTypeId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Vehicle Type");
|
||||
isValid = false;
|
||||
} else if (vehicleBrandId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Brand");
|
||||
isValid = false;
|
||||
} else if (vehicleModelId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Model");
|
||||
isValid = false;
|
||||
} else if (vehicleModelYearId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Year");
|
||||
isValid = false;
|
||||
} else if (vehicleCountryId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid Country");
|
||||
isValid = false;
|
||||
} else if (vehicleCityId.selectedId == -1) {
|
||||
Utils.showToast("Please select valid City");
|
||||
isValid = false;
|
||||
} else if (price.isEmpty) {
|
||||
Utils.showToast("Please add valid Price");
|
||||
isValid = false;
|
||||
} else if (description.isEmpty) {
|
||||
Utils.showToast("Please add valid Description");
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
bool isRequestLoading = true;
|
||||
List<Request> requests = [];
|
||||
|
||||
getRequests() async {
|
||||
isRequestLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
int selectedRequestType;
|
||||
// Find the FilterListModel with isSelected equal to true
|
||||
|
||||
requests = await requestRepo.getRequests(
|
||||
{
|
||||
"customerID": AppState().getUser.data!.userInfo!.customerId,
|
||||
"pageSize": 100,
|
||||
"pageIndex": 0,
|
||||
"requestType": requestsFilterOptions.firstWhere((element) => element.isSelected).id,
|
||||
},
|
||||
);
|
||||
isRequestLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
import 'package:car_customer_app/view_models/requests_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/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../requests/widget/request_item.dart';
|
||||
|
||||
class RequestsFragment extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) {
|
||||
return Column(
|
||||
children: [
|
||||
ShowFillButton(
|
||||
title: "title",
|
||||
onPressed: () {
|
||||
context.read<RequestsVM>().getRequests();
|
||||
}),
|
||||
16.height,
|
||||
FiltersList(
|
||||
filterList: requestsVM.requestsFilterOptions,
|
||||
onFilterTapped: (index, selectedFilterId) => requestsVM.applyFilterOnRequestsVM(index: index),
|
||||
),
|
||||
8.height,
|
||||
Expanded(
|
||||
child: requestsVM.isRequestLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: requestsVM.requests.length == 0
|
||||
? Center(
|
||||
child: "No Request Available".toText(
|
||||
isBold: true,
|
||||
),
|
||||
)
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return RequestItem(requestsVM.requests[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 16.height;
|
||||
},
|
||||
itemCount: requestsVM.requests.length,
|
||||
padding: EdgeInsets.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
top: 8,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,249 @@
|
||||
import 'package:car_customer_app/view_models/requests_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/generic_resp_model.dart';
|
||||
import 'package:mc_common_app/models/widgets_models.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart';
|
||||
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/dotted_rect.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';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CreateRequestPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// context.read<RequestsVM>().getVehicleTypes();
|
||||
context.read<RequestsVM>().getRequestTypes();
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Create Request",
|
||||
),
|
||||
body: Consumer<RequestsVM>(builder: (context, model, widget) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Vehicle Detail".toText(fontSize: 18, isBold: true),
|
||||
8.height,
|
||||
if (model.isFetchingRequestType) ...[
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
] else ...[
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> requestTypeDrop = [];
|
||||
for (var element in model.requestTypes) {
|
||||
requestTypeDrop.add(DropValue(element.enumValue.toInt() ?? 0, element.enumValueStr ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionRequestTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: requestTypeDrop,
|
||||
dropdownValue: model.requestTypeId.selectedId != -1 ? DropValue(model.requestTypeId.selectedId, model.requestTypeId.selectedOption, "") : null,
|
||||
hint: "Request Type",
|
||||
errorValue: model.requestTypeId.errorValue,
|
||||
);
|
||||
}),
|
||||
],
|
||||
8.height,
|
||||
if (model.requestTypeId.selectedId != -1)
|
||||
if (model.isFetchingVehicleType) ...[
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
] else ...[
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleTypeDrop = [];
|
||||
for (var element in model.vehicleTypes) {
|
||||
vehicleTypeDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleTypeName ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: vehicleTypeDrop,
|
||||
dropdownValue: model.vehicleTypeId.selectedId != -1 ? DropValue(model.vehicleTypeId.selectedId, model.vehicleTypeId.selectedOption, "") : null,
|
||||
hint: "Vehicle Type",
|
||||
errorValue: model.vehicleTypeId.errorValue,
|
||||
);
|
||||
}),
|
||||
],
|
||||
8.height,
|
||||
if (model.vehicleTypeId.selectedId != -1)
|
||||
if (model.isFetchingVehicleDetail) ...[
|
||||
Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
] else ...[
|
||||
Column(
|
||||
children: [
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleBrandsDrop = [];
|
||||
for (var element in model.vehicleBrands) {
|
||||
vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleBrandDescription ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: vehicleBrandsDrop,
|
||||
dropdownValue: model.vehicleBrandId.selectedId != -1 ? DropValue(model.vehicleBrandId.selectedId, model.vehicleBrandId.selectedOption, "") : null,
|
||||
hint: "Brand",
|
||||
errorValue: model.vehicleBrandId.errorValue,
|
||||
);
|
||||
}),
|
||||
8.height,
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleModelsDrop = [];
|
||||
for (var element in model.vehicleModels) {
|
||||
if (model.vehicleBrandId.selectedId == element.vehicleBrandID) vehicleModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.model ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleModelId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: vehicleModelsDrop,
|
||||
dropdownValue: model.vehicleModelId.selectedId != -1 ? DropValue(model.vehicleModelId.selectedId, model.vehicleModelId.selectedOption, "") : null,
|
||||
hint: "Model",
|
||||
errorValue: model.vehicleModelId.errorValue,
|
||||
);
|
||||
}),
|
||||
8.height,
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleYearModelsDrop = [];
|
||||
for (var element in model.vehicleModelYears) {
|
||||
vehicleYearModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.modelYear ?? "", ""));
|
||||
}
|
||||
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleModelYearId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: vehicleYearModelsDrop,
|
||||
dropdownValue: model.vehicleModelYearId.selectedId != -1 ? DropValue(model.vehicleModelYearId.selectedId, model.vehicleModelYearId.selectedOption, "") : null,
|
||||
hint: "Year",
|
||||
errorValue: model.vehicleModelYearId.errorValue,
|
||||
);
|
||||
}),
|
||||
8.height,
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleCountriesDrop = [];
|
||||
for (var element in model.vehicleCountries) {
|
||||
vehicleCountriesDrop.add(DropValue(element.id?.toInt() ?? 0, element.countryName ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleCountryId(SelectionModel(selectedOption: value.value, selectedId: value.id)),
|
||||
list: vehicleCountriesDrop,
|
||||
dropdownValue: model.vehicleCountryId.selectedId != -1 ? DropValue(model.vehicleCountryId.selectedId, model.vehicleCountryId.selectedOption, "") : null,
|
||||
hint: "Country",
|
||||
errorValue: model.vehicleCountryId.errorValue,
|
||||
);
|
||||
}),
|
||||
if (model.vehicleCountryId.selectedId != -1) ...[
|
||||
if (model.isCountryFetching) ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [const CircularProgressIndicator().paddingAll(10)],
|
||||
),
|
||||
] else ...[
|
||||
8.height,
|
||||
Builder(builder: (context) {
|
||||
List<DropValue> vehicleCitiesDrop = [];
|
||||
for (var element in model.vehicleCities) {
|
||||
vehicleCitiesDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
|
||||
}
|
||||
return DropdownField(
|
||||
(DropValue value) => model.updateSelectionVehicleCityId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
|
||||
list: vehicleCitiesDrop,
|
||||
dropdownValue: model.vehicleCityId.selectedId != -1 ? DropValue(model.vehicleCityId.selectedId, model.vehicleCityId.selectedOption, "") : null,
|
||||
hint: "City",
|
||||
errorValue: model.vehicleCityId.errorValue,
|
||||
);
|
||||
}),
|
||||
],
|
||||
],
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "Price",
|
||||
value: model.price,
|
||||
onChanged: (e) => model.updatePrice(e),
|
||||
),
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "Description",
|
||||
maxLines: 5,
|
||||
value: model.description,
|
||||
onChanged: (e) => model.updateDescription(e),
|
||||
),
|
||||
8.height,
|
||||
DottedRectContainer(
|
||||
onTap: () => context.read<RequestsVM>().pickMultipleImages(),
|
||||
text: "Attach Image",
|
||||
icon: MyAssets.attachmentIcon.buildSvg(),
|
||||
),
|
||||
if (model.vehicleImageError != "") ...[
|
||||
10.height,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
model.vehicleImageError.toText(fontSize: 14, color: Colors.red),
|
||||
],
|
||||
).paddingOnly(right: 10)
|
||||
],
|
||||
if (model.pickedVehicleImages.isNotEmpty) ...[
|
||||
16.height,
|
||||
PickedImagesContainer(
|
||||
pickedImages: model.pickedVehicleImages,
|
||||
onCrossPressedPrimary: model.removeImageFromList,
|
||||
onAddImagePressed: () {
|
||||
context.read<RequestsVM>().pickMultipleImages();
|
||||
},
|
||||
),
|
||||
],
|
||||
16.height,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Checkbox(
|
||||
value: model.isShippingDeliveryEnabled,
|
||||
onChanged: null,
|
||||
),
|
||||
"Shipping/Delivery".toText(color: MyColors.darkPrimaryColor, isBold: true, fontSize: 18)
|
||||
],
|
||||
).onPress(() {
|
||||
model.updateShippingDeliverEnabled(!model.isShippingDeliveryEnabled);
|
||||
}),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
).toContainer(isShadowEnabled: true, marginAll: 16, paddingAll: 12),
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: "Create Request",
|
||||
maxWidth: double.infinity,
|
||||
margin: EdgeInsets.all(16),
|
||||
onPressed: () async {
|
||||
Utils.showLoading(context);
|
||||
GenericRespModel? response = await model.createRequest();
|
||||
Utils.hideLoading(context);
|
||||
if (response != null) {
|
||||
if (response.messageStatus == 1) {
|
||||
Utils.showToast("Request Successfully Created");
|
||||
} else {
|
||||
Utils.showToast(response.message.toString());
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
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/common_widgets/app_bar.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class OfferListPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: "Offers",
|
||||
),
|
||||
body: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return showOfferItem();
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 16.height;
|
||||
},
|
||||
itemCount: 2,
|
||||
padding: EdgeInsets.all(16),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showOfferItem() {
|
||||
return Stack(
|
||||
alignment: Alignment.bottomRight,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Toyota Corolla".toText(fontSize: 16, isBold: true),
|
||||
Center(
|
||||
child: "2".toText(
|
||||
color: Colors.white,
|
||||
isBold: true,
|
||||
fontSize: 10,
|
||||
),
|
||||
).toContainer(
|
||||
backgroundColor: MyColors.redColor,
|
||||
borderRadius: 100,
|
||||
paddingAll: 1,
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
8.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
"Dear, how you doing. I have great offer for You for this car. Dear, how you doing. I have great offer for You for this car. Dear, how you doing. I have great offer for You for this car. Dear, how you doing. I have great offer for You for this car. Dear, how you doing. I have great offer for You for this car."
|
||||
.toText(
|
||||
color: MyColors.lightTextColor,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
12.width,
|
||||
"9 Hours Ago".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward,
|
||||
color: MyColors.darkIconColor,
|
||||
size: 18,
|
||||
),
|
||||
],
|
||||
).toContainer(
|
||||
isShadowEnabled: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
import 'package:car_customer_app/model/request.dart';
|
||||
import 'package:car_customer_app/views/requests/widget/request_status_chip.dart';
|
||||
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/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class RequestItem extends StatelessWidget {
|
||||
Request request;
|
||||
|
||||
RequestItem(this.request);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RequestStatusChip(request),
|
||||
6.height,
|
||||
"${request.brand} ${request.model}".toText(fontSize: 16, isBold: true),
|
||||
showItem("Model:", "${request.year}"),
|
||||
showItem("Customer Name:", "${request.customerName}"),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Center(
|
||||
child: "${request.offerCount}".toText(
|
||||
color: Colors.white,
|
||||
isBold: true,
|
||||
fontSize: 10,
|
||||
),
|
||||
).toContainer(
|
||||
backgroundColor: MyColors.redColor,
|
||||
borderRadius: 100,
|
||||
paddingAll: 1,
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
2.height,
|
||||
request.cityName.toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
"9 Hours Ago".toText(
|
||||
color: MyColors.lightTextColor,
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
showItem("Description: ", request.description),
|
||||
showItem("Price Range: ", ""),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
request.price.toString().toText(
|
||||
fontSize: 20,
|
||||
color: Colors.black,
|
||||
isBold: true,
|
||||
),
|
||||
2.width,
|
||||
"SAR"
|
||||
.toText(
|
||||
color: MyColors.lightTextColor,
|
||||
fontSize: 10,
|
||||
)
|
||||
.paddingOnly(
|
||||
bottom: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward,
|
||||
color: MyColors.darkIconColor,
|
||||
size: 18,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
.toContainer(
|
||||
isShadowEnabled: true,
|
||||
)
|
||||
.onPress(() {
|
||||
navigateWithName(context, AppRoutes.offersListPage);
|
||||
});
|
||||
}
|
||||
|
||||
Widget showItem(String title, String value) {
|
||||
return Row(
|
||||
children: [
|
||||
title.toText(
|
||||
color: MyColors.lightTextColor,
|
||||
),
|
||||
2.width,
|
||||
value.toText(
|
||||
isBold: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
import 'package:car_customer_app/model/request.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
class RequestStatusChip extends StatelessWidget {
|
||||
Request request;
|
||||
|
||||
RequestStatusChip(this.request);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return request.requestStatusName
|
||||
.toText(
|
||||
fontSize: 8,
|
||||
color: Colors.white,
|
||||
)
|
||||
.toContainer(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
backgroundColor: request.requestStatus == RequestStatus.pending
|
||||
? MyColors.adPendingStatusColor
|
||||
: request.requestStatus == RequestStatus.cancelled
|
||||
? MyColors.redColor
|
||||
: MyColors.greenColor,
|
||||
borderRadius: 100,
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue