add services and items

mirza_dev
mirza.shafique 3 years ago
parent 4e78e6fdc1
commit d6f3c5653a

@ -24,6 +24,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

@ -0,0 +1,100 @@
// To parse this JSON data, do
//
// final itemModel = itemModelFromJson(jsonString);
import 'dart:convert';
ItemModel itemModelFromJson(String str) => ItemModel.fromJson(json.decode(str));
String itemModelToJson(ItemModel data) => json.encode(data.toJson());
class ItemModel {
final int? messageStatus;
final int? totalItemsCount;
final List<ItemData>? data;
final String? message;
ItemModel({
this.messageStatus,
this.totalItemsCount,
this.data,
this.message,
});
factory ItemModel.fromJson(Map<String, dynamic> json) => ItemModel(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<ItemData>.from(json["data"]!.map((x) => ItemData.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
}
class ItemData {
final int? id;
final String? name;
final String? price;
final String? manufactureDate;
final String? description;
final dynamic pictureUrl;
final int? companyId;
final int? serviceProviderServiceId;
final bool? isActive;
final bool? isAllowAppointment;
final bool? isAppointmentCompanyLoc;
final bool? isAppointmentCustomerLoc;
bool? isUpdate;
ItemData({
this.id,
this.name,
this.price,
this.manufactureDate,
this.description,
this.pictureUrl,
this.companyId,
this.serviceProviderServiceId,
this.isActive,
this.isAllowAppointment,
this.isAppointmentCompanyLoc,
this.isAppointmentCustomerLoc,
this.isUpdate,
});
factory ItemData.fromJson(Map<String, dynamic> json) => ItemData(
id: json["id"],
name: json["name"],
price: json["price"].toString(),
manufactureDate: json["manufactureDate"],
description: json["description"],
pictureUrl: json["pictureUrl"],
companyId: json["companyID"],
serviceProviderServiceId: json["serviceProviderServiceID"],
isActive: json["isActive"],
isAllowAppointment: json["isAllowAppointment"],
isAppointmentCompanyLoc: json["isAppointmentCompanyLoc"],
isAppointmentCustomerLoc: json["isAppointmentCustomerLoc"],
isUpdate: false,
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"price": price,
"manufactureDate": manufactureDate,
"description": description,
"pictureUrl": pictureUrl,
"companyID": companyId,
"serviceProviderServiceID": serviceProviderServiceId,
"isActive": isActive,
"isAllowAppointment": isAllowAppointment,
"isAppointmentCompanyLoc": isAppointmentCompanyLoc,
"isAppointmentCustomerLoc": isAppointmentCustomerLoc,
};
}

@ -0,0 +1,81 @@
// To parse this JSON data, do
//
// final schedule = scheduleFromJson(jsonString);
import 'dart:convert';
Schedule scheduleFromJson(String str) => Schedule.fromJson(json.decode(str));
String scheduleToJson(Schedule data) => json.encode(data.toJson());
class Schedule {
final int? messageStatus;
final int? totalItemsCount;
final List<ScheduleData>? data;
final String? message;
Schedule({
this.messageStatus,
this.totalItemsCount,
this.data,
this.message,
});
factory Schedule.fromJson(Map<String, dynamic> json) => Schedule(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<ScheduleData>.from(json["data"]!.map((x) => ScheduleData.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
}
class ScheduleData {
final int? id;
final int? branchId;
final DateTime? fromDate;
final DateTime? toDate;
final String? startTime;
final String? endTime;
final int? slotDurationMinute;
final int? perSlotAppointment;
ScheduleData({
this.id,
this.branchId,
this.fromDate,
this.toDate,
this.startTime,
this.endTime,
this.slotDurationMinute,
this.perSlotAppointment,
});
factory ScheduleData.fromJson(Map<String, dynamic> json) => ScheduleData(
id: json["id"],
branchId: json["branchID"],
fromDate: json["fromDate"] == null ? null : DateTime.parse(json["fromDate"]),
toDate: json["toDate"] == null ? null : DateTime.parse(json["toDate"]),
startTime: json["startTime"],
endTime: json["endTime"],
slotDurationMinute: json["slotDurationMinute"],
perSlotAppointment: json["perSlotAppointment"],
);
Map<String, dynamic> toJson() => {
"id": id,
"branchID": branchId,
"fromDate": fromDate?.toIso8601String(),
"toDate": toDate?.toIso8601String(),
"startTime": startTime,
"endTime": endTime,
"slotDurationMinute": slotDurationMinute,
"perSlotAppointment": perSlotAppointment,
};
}

@ -0,0 +1,125 @@
// To parse this JSON data, do
//
// final subscription = subscriptionFromJson(jsonString);
import 'dart:convert';
Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str));
String subscriptionToJson(Subscription data) => json.encode(data.toJson());
class SubscriptionModel {
SubscriptionModel({
this.messageStatus,
this.totalItemsCount,
this.data,
this.message,
});
int? messageStatus;
int? totalItemsCount;
List<Subscription>? data;
String? message;
factory SubscriptionModel.fromJson(Map<String, dynamic> json) => SubscriptionModel(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? [] : List<Subscription>.from(json["data"]!.map((x) => Subscription.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
"message": message,
};
}
class Subscription {
Subscription({
this.id,
this.name,
this.description,
this.durationName,
this.durationDays,
this.price,
this.currency,
this.numberOfBranches,
this.numberOfSubUsers,
this.numberOfAds,
this.countryId,
this.countryName,
this.isSubscribed,
this.subscriptionAppliedId,
this.serviceProviderId,
this.dateStart,
this.dateEnd,
this.isExpired,
this.isActive,
});
int? id;
String? name;
String? description;
String? durationName;
int? durationDays;
double? price;
String? currency;
int? numberOfBranches;
int? numberOfSubUsers;
int? numberOfAds;
int? countryId;
String? countryName;
bool? isSubscribed;
int? subscriptionAppliedId;
int? serviceProviderId;
DateTime? dateStart;
DateTime? dateEnd;
bool? isExpired;
bool? isActive;
factory Subscription.fromJson(Map<String, dynamic> json) => Subscription(
id: json["id"],
name: json["name"],
description: json["description"],
durationName: json["durationName"],
durationDays: json["durationDays"],
price: json["price"]?.toDouble(),
currency: json["currency"],
numberOfBranches: json["numberOfBranches"],
numberOfSubUsers: json["numberOfSubUsers"],
numberOfAds: json["numberOfAds"],
countryId: json["countryID"],
countryName: json["countryName"]!,
isSubscribed: json["isSubscribed"],
subscriptionAppliedId: json["subscriptionAppliedID"],
serviceProviderId: json["serviceProviderID"],
dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]),
dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]),
isExpired: json["isExpired"],
isActive: json["isActive"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"description": description,
"durationName": durationName,
"durationDays": durationDays,
"price": price,
"currency": currency,
"numberOfBranches": numberOfBranches,
"numberOfSubUsers": numberOfSubUsers,
"numberOfAds": numberOfAds,
"countryID": countryId,
"countryName": countryName,
"isSubscribed": isSubscribed,
"subscriptionAppliedID": subscriptionAppliedId,
"serviceProviderID": serviceProviderId,
"dateStart": dateStart?.toIso8601String(),
"dateEnd": dateEnd?.toIso8601String(),
"isExpired": isExpired,
"isActive": isActive,
};
}

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
class CheckBoxWithTitleDescription extends StatelessWidget {
bool isSelected;
String title, description;
Function(bool) onSelection;
CheckBoxWithTitleDescription({required this.isSelected, required this.title, required this.description, required this.onSelection, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Checkbox(
value: isSelected,
onChanged: (bool? v) {
onSelection(v ?? false);
},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title.toText(fontSize: 14, isBold: true),
description.toText(fontSize: 12, color: MyColors.lightTextColor),
],
),
),
],
),
);
}
}

@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
class EmptyWidget extends StatelessWidget {
const EmptyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(child: "No Data Found".toText());
}
}

@ -1,4 +1,7 @@
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/repositories/subscription_repo.dart';
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/config/dependencies.dart';
@ -9,6 +12,9 @@ class ProviderAppDependencies {
static void addDependencies() {
AppDependencies.addDependencies();
injector.registerSingleton<BranchRepo>(() => BranchRepoImp());
injector.registerSingleton<CommonRepo>(() => CommonRepoImp());
injector.registerSingleton<ItemsRepo>(() => ItemsRepoImp());
// injector.registerSingleton<CommonRepo>(() => CommonRepoImp());
injector.registerSingleton<SubscriptionRepo>(() => SubscriptionRepoImp());
injector.registerSingleton<ScheduleRepo>(() => ScheduleRepoImp());
}
}

@ -6,8 +6,15 @@ import 'package:car_provider_app/views/settings/branch/branch_detail_page.dart';
import 'package:car_provider_app/views/settings/branch/branch_list_page.dart';
import 'package:car_provider_app/views/settings/branch/define_branch_page.dart';
import 'package:car_provider_app/views/settings/create_services_page.dart';
import 'package:car_provider_app/views/settings/schedule/add_schedules_page.dart';
import 'package:car_provider_app/views/settings/schedule/schedules_list_page.dart';
import 'package:car_provider_app/views/settings/services/create_item_page.dart';
import 'package:car_provider_app/views/settings/services/create_services_page2.dart';
import 'package:car_provider_app/views/settings/dealership_page.dart';
import 'package:car_provider_app/views/settings/define_license_page.dart';
import 'package:car_provider_app/views/settings/services/create_services_page3.dart';
import 'package:car_provider_app/views/settings/services/items_list_page.dart';
import 'package:car_provider_app/views/settings/services/services_list_page.dart';
import 'package:car_provider_app/views/subscriptions/my_subscritions_page.dart';
import 'package:car_provider_app/views/subscriptions/subscriptions_page.dart';
import 'package:mc_common_app/config/routes.dart';
@ -19,22 +26,31 @@ import '../views/dashboard/dashboard_page.dart';
class ProviderAppRoutes {
//settings
static const String defineLicense = "/defineLicese";
static final String dealershipSetting = "/dealershipSetting";
static final String branchList = "/branchList";
static final String branchDetail = "/branchDetail";
static final String defineBranch = "/defineBranch";
static final String createServices = "/createServices";
static const defineLicense = "/defineLicese";
static const String dealershipSetting = "/dealershipSetting";
static const String branchList = "/branchList";
static const String branchDetail = "/branchDetail";
static const String defineBranch = "/defineBranch";
//Appointments
static final String appointmentDetailList = "/appointmentDetailList";
static final String updateAppointmentPage = "/updateAppointmentPage";
static const String appointmentDetailList = "/appointmentDetailList";
static const String updateAppointmentPage = "/updateAppointmentPage";
//Requests
static final String requestsDetailPage = "/requestsDetailPage";
static final String sendOfferPage = "/sendOfferPage";
static const String requestsDetailPage = "/requestsDetailPage";
static const String sendOfferPage = "/sendOfferPage";
//Services
static const String servicesList = "/servicesList";
static const String itemsList = "/itemsList";
static const String createItem = "/createItem";
static const String createServices = "/createServices";
static const String createServices2 = "/createServices2";
static const String createServices3 = "/createServices3";
//Schedules
static const String schedulesList = "/schedulesList";
static const String addSchedule = "/addSchedule";
static final Map<String, WidgetBuilder> routes = {
//Home page
@ -46,7 +62,6 @@ class ProviderAppRoutes {
branchList: (context) => BranchListPage(),
defineBranch: (context) => DefineBranchPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
branchDetail: (context) => BranchDetailPage(ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch),
createServices: (context) => CreateServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
//Appointments
appointmentDetailList: (context) => const AppointmentDetailListPage(),
@ -56,8 +71,20 @@ class ProviderAppRoutes {
requestsDetailPage: (context) => const RequestDetailPage(),
sendOfferPage: (context) => const SendOfferPage(),
//Subcriptions
//Subscriptions
AppRoutes.mySubscriptionsPage: (context) => const MySubscriptionsPage(),
AppRoutes.subscriptionsPage: (context) => const SubscriptionsPage(),
//Services
servicesList: (context) => const ServicesListPage(),
itemsList: (context) => ItemsListPage(),
createItem: (context) => const CreateItemPage(),
//createServices: (context) => CreateServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
//createServices2: (context) => CreateServicesPage2((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
createServices3: (context) => CreateServicesPage3((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as CreateBranchModel)),
//Schedules
schedulesList: (context) => const SchedulesListPage(),
addSchedule: (context) => AddSchedulesPage(),
};
}

@ -1,7 +1,14 @@
import 'package:car_provider_app/config/provider_dependencies.dart';
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/repositories/subscription_repo.dart';
import 'package:car_provider_app/view_models/branch_view_model.dart';
import 'package:car_provider_app/view_models/dashboard_view_model.dart';
import 'package:car_provider_app/view_models/items_view_model.dart';
import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
@ -42,13 +49,33 @@ Future<void> main() async {
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()),
),
ChangeNotifierProvider<BranchVM>(
create: (_) => BranchVM(
// ChangeNotifierProvider<BranchVM>(
// create: (_) => BranchVM(
// branchRepo: injector.get<BranchRepo>(),
// commonServices: injector.get<CommonServices>(),
// commonRepo: injector.get<CommonRepo>(),
// ),
// ),
ChangeNotifierProvider<ServiceVM>(
create: (_) => ServiceVM(
branchRepo: injector.get<BranchRepo>(),
commonServices: injector.get<CommonServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<SubscriptionsVM>(
create: (_) => SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
),
ChangeNotifierProvider<ItemsVM>(
create: (_) => ItemsVM(
itemsRepo: injector.get<ItemsRepo>(),
commonServices: injector.get<CommonServices>(),
),
),
ChangeNotifierProvider<ScheduleVM>(
create: (_) => ScheduleVM(scheduleRepo: injector.get<ScheduleRepo>(),
),
),
],
child: const MyApp(),
).setupLocale());

@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
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/m_response.dart';
@ -119,6 +121,7 @@ class BranchRepoImp implements BranchRepo {
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderDocument_Update, map, token: t);
}
@override
Future<Branch2> getBranchAndServices() async {
var postParams = {"serviceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
@ -146,7 +149,6 @@ class BranchRepoImp implements BranchRepo {
"isActive": isNeedToDelete
};
String t = AppState().getUser.data!.accessToken ?? "";
print("tokeen " + t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateProviderBranch, postParams, token: t);
}

@ -0,0 +1,44 @@
import 'package:car_provider_app/common/item_model.dart';
import 'package:flutter/material.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/m_response.dart';
abstract class ItemsRepo {
Future<MResponse> createServiceItems(Map map);
Future<ItemModel> getServiceItems(int serviceId);
Future<MResponse> updateServiceItem(Map map);
}
class ItemsRepoImp implements ItemsRepo {
@override
Future<MResponse> createServiceItems(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint(t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createItems, map, token: t);
}
@override
Future<ItemModel> getServiceItems(int serviceId) async {
var queryParameters = {
"ServiceProviderServiceID": serviceId.toString(),
};
String? token = AppState().getUser.data?.accessToken;
debugPrint(token);
return await injector
.get<ApiClient>()
.getJsonForObject((json) => ItemModel.fromJson(json), ApiConsts.getServiceItems, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? "");
}
@override
Future<MResponse> updateServiceItem(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint(t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateServiceItem, map, token: t);
}
}

@ -0,0 +1,43 @@
import 'package:car_provider_app/common/schedule_model.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/m_response.dart';
import 'package:mc_common_app/models/profile/services.dart';
abstract class ScheduleRepo {
Future<Services> getAllServices();
Future<MResponse> createSchedule(Map map);
Future<MResponse> addServicesInSchedule(Map map);
Future<Schedule> getSchedules();
}
class ScheduleRepoImp implements ScheduleRepo {
@override
Future<Services> getAllServices() async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, token: t);
}
@override
Future<MResponse> createSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t);
}
@override
Future<MResponse> addServicesInSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t);
}
@override
Future<Schedule> getSchedules() async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Schedule.fromJson(json), ApiConsts.getSchedule, token: t);
}
}

@ -0,0 +1,25 @@
import 'package:car_provider_app/common/subscription_model.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/m_response.dart';
abstract class SubscriptionRepo {
Future<SubscriptionModel> getAllSubscriptions(String? serviceProviderID);
}
class SubscriptionRepoImp extends SubscriptionRepo {
@override
Future<SubscriptionModel> getAllSubscriptions(String? serviceProviderID) async {
String t = AppState().getUser.data!.accessToken ?? "";
Map<String, String> queryParameters = {};
if (serviceProviderID != null) {
queryParameters = {
"ID": serviceProviderID,
};
}
return await injector.get<ApiClient>().getJsonForObject((json) => SubscriptionModel.fromJson(json), ApiConsts.getAllSubscriptions, token: t, queryParameters: queryParameters);
}
}

@ -1,208 +1,218 @@
import 'dart:io';
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:file_picker/file_picker.dart';
import 'package:mc_common_app/models/m_response.dart';
import 'package:mc_common_app/models/model/branch2.dart';
import 'package:mc_common_app/models/profile/branch.dart';
import 'package:mc_common_app/models/profile/categroy.dart';
import 'package:mc_common_app/models/profile/document.dart';
import 'package:mc_common_app/models/profile/services.dart';
import 'package:mc_common_app/models/user/cities.dart';
import 'package:mc_common_app/models/user/country.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:permission_handler/permission_handler.dart';
class BranchVM extends BaseVM {
final BranchRepo branchRepo;
final CommonServices commonServices;
final CommonRepo commonRepo;
BranchVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
Document? document;
Branch2? branchs;
//Create Branch
String countryCode = "", address = "", branchName = "", branchDescription = "";
double latitude = 0, longitude = 0;
int role = -1, countryId = -1, cityId = -1;
List<DropValue> countryDropList = [];
List<DropValue> citiesDropList = [];
DropValue? countryValue;
DropValue? cityValue;
Country? country;
Cities? cities;
//Create Service
String? branchNameForService;
int categoryId = -1, branchId = -1;
DropValue? branchValue;
List<DropValue> countryDropListForService = [];
List<DropValue> categoryDropList = [];
Branch? branch;
Category? category;
Services? services;
getServiceProviderDocument(int providerId) async {
setState(ViewState.busy);
document = await branchRepo.getServiceProviderDocument(providerId);
setState(ViewState.idle);
}
selectFile(int index) async {
File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000) {
Utils.showToast("File is larger then 1KB");
} else {
document!.data![index].document = Utils.convertFileToBase64(file);
document!.data![index].fileExt = Utils.checkFileExt(file.path);
document!.data![index].documentUrl = file.path;
setState(ViewState.idle);
}
} else {
// User canceled the picker
}
}
Future<MResponse> updateDocument(List<DocumentData>? data) async {
return await branchRepo.serviceProviderDocumentsUpdate(data);
}
//Create new branch
getBranchAndServices() async {
setState(ViewState.busy);
branchs = await branchRepo.getBranchAndServices();
setState(ViewState.idle);
}
getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
setState(ViewState.busy);
resetValues();
country = await commonRepo.getAllCountries();
country!.data?.forEach((element) {
if (branchData != null) if (branchData.id != null) {
if (element.id == branchData.countryID) {
countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
}
}
countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
});
if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
setState(ViewState.idle);
}
getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
setState(ViewState.busy);
citiesDropList.clear();
cities = null;
cityId = -1;
cities = await commonRepo.getAllCites(countryId.toString());
cities!.data?.forEach((element) {
if (branchData != null && branchData.id != null) {
if (element.id == branchData.cityId) {
address = branchData.address!;
branchName = branchData.branchName!;
branchDescription = branchData.branchDescription!;
latitude = double.parse(branchData.latitude ?? "");
longitude = double.parse(branchData.longitude ?? "");
countryId = branchData.countryID!;
cityId = branchData.cityId!;
cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
}
}
citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
});
setState(ViewState.idle);
}
resetValues() {
countryCode = "";
address = "";
branchName = "";
branchDescription = "";
latitude = 0;
longitude = 0;
role = -1;
countryId = -1;
cityId = -1;
countryDropList.clear();
countryId = -1;
cityId = -1;
cities = null;
branchNameForService = null;
categoryId = -1;
branchId = -1;
branchValue = null;
countryDropListForService = [];
categoryDropList = [];
branch = null;
category = null;
services = null;
}
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
}
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
}
//Create Service
fetchBranches() async {
resetValues();
setState(ViewState.busy);
branch = await branchRepo.fetchAllBranches();
branch!.data?.forEach((element) {
countryDropListForService.add(DropValue(element.id ?? 0, ((element.branchName!.isEmpty ? "N/A" : element.branchName) ?? "N/A"), ""));
});
setState(ViewState.idle);
}
fetchBranchCategory(String countryCode) async {
setState(ViewState.busy);
category = await branchRepo.fetchBranchCategory();
category!.data?.forEach((element) {
categoryDropList.add(DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
""));
});
setState(ViewState.idle);
}
fetchServicesByCategoryId() async {
setState(ViewState.busy);
services = await branchRepo.fetchServicesByCategoryId(categoryId.toString());
setState(ViewState.idle);
}
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
return await branchRepo.createService(map);
}
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map);
}
}
// import 'dart:io';
//
// import 'package:car_provider_app/repositories/branch_repo.dart';
// import 'package:file_picker/file_picker.dart';
// import 'package:mc_common_app/models/m_response.dart';
// import 'package:mc_common_app/models/model/branch2.dart';
// import 'package:mc_common_app/models/profile/branch.dart';
// import 'package:mc_common_app/models/profile/categroy.dart';
// import 'package:mc_common_app/models/profile/document.dart';
// import 'package:mc_common_app/models/profile/services.dart';
// import 'package:mc_common_app/models/user/cities.dart';
// import 'package:mc_common_app/models/user/country.dart';
// import 'package:mc_common_app/repositories/common_repo.dart';
// import 'package:mc_common_app/services/services.dart';
// import 'package:mc_common_app/utils/enums.dart';
// import 'package:mc_common_app/utils/utils.dart';
// import 'package:mc_common_app/view_models/base_view_model.dart';
// import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
// import 'package:permission_handler/permission_handler.dart';
//
// class BranchVM extends BaseVM {
// final BranchRepo branchRepo;
// final CommonServices commonServices;
// final CommonRepo commonRepo;
//
// BranchVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
//
// Document? document;
// Branch2? branchs;
//
// //Create Branch
// String countryCode = "", address = "", branchName = "", branchDescription = "";
// double latitude = 0, longitude = 0;
// int role = -1, countryId = -1, cityId = -1;
// List<DropValue> countryDropList = [];
// List<DropValue> citiesDropList = [];
// DropValue? countryValue;
// DropValue? cityValue;
//
// Country? country;
// Cities? cities;
//
// //Create Service
// String? branchNameForService;
// int categoryId = -1, branchId = -1, serviceId = -1;
// DropValue? branchValue;
//
// List<DropValue> countryDropListForService = [];
// List<DropValue> categoryDropList = [];
// List<DropValue> servicesDropList = [];
//
// Branch? branch;
// Category? category;
// Services? services;
//
// getServiceProviderDocument(int providerId) async {
// setState(ViewState.busy);
// document = await branchRepo.getServiceProviderDocument(providerId);
// setState(ViewState.idle);
// }
//
// selectFile(int index) async {
// File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
//
// if (file != null) {
// int sizeInBytes = file.lengthSync();
// // double sizeInMb = sizeInBytes / (1024 * 1024);
// if (sizeInBytes > 1000) {
// Utils.showToast("File is larger then 1KB");
// } else {
// document!.data![index].document = Utils.convertFileToBase64(file);
// document!.data![index].fileExt = Utils.checkFileExt(file.path);
// document!.data![index].documentUrl = file.path;
// setState(ViewState.idle);
// }
// } else {
// // User canceled the picker
// }
// }
//
// Future<MResponse> updateDocument(List<DocumentData>? data) async {
// return await branchRepo.serviceProviderDocumentsUpdate(data);
// }
//
// //Create new branch
// getBranchAndServices() async {
// setState(ViewState.busy);
// branchs = await branchRepo.getBranchAndServices();
// setState(ViewState.idle);
// }
//
// getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
// setState(ViewState.busy);
// resetValues();
// country = await commonRepo.getAllCountries();
// country!.data?.forEach((element) {
// if (branchData != null) if (branchData.id != null) {
// if (element.id == branchData.countryID) {
// countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
// }
// }
// countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
// });
// if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
// setState(ViewState.idle);
// }
//
// getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
// setState(ViewState.busy);
// citiesDropList.clear();
// cities = null;
// cityId = -1;
// cities = await commonRepo.getAllCites(countryId.toString());
// cities!.data?.forEach((element) {
// if (branchData != null && branchData.id != null) {
// if (element.id == branchData.cityId) {
// address = branchData.address!;
// branchName = branchData.branchName!;
// branchDescription = branchData.branchDescription!;
// latitude = double.parse(branchData.latitude ?? "");
// longitude = double.parse(branchData.longitude ?? "");
// countryId = branchData.countryID!;
// cityId = branchData.cityId!;
// cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
// }
// }
// citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
// });
// setState(ViewState.idle);
// }
//
// resetValues() {
// countryCode = "";
// address = "";
// branchName = "";
// branchDescription = "";
// latitude = 0;
// longitude = 0;
// role = -1;
// countryId = -1;
// cityId = -1;
// countryDropList.clear();
// countryId = -1;
// cityId = -1;
// cities = null;
// branchNameForService = null;
// categoryId = -1;
// branchId = -1;
// branchValue = null;
// serviceId = -1;
//
// countryDropListForService = [];
// categoryDropList = [];
// servicesDropList = [];
//
// branch = null;
// category = null;
// services = null;
// }
//
// Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
// return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
// return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// //Create Service
// fetchBranches() async {
// resetValues();
// setState(ViewState.busy);
// branch = await branchRepo.fetchAllBranches();
// branch!.data?.forEach((element) {
// countryDropListForService.add(DropValue(element.id ?? 0, ((element.branchName!.isEmpty ? "N/A" : element.branchName) ?? "N/A"), ""));
// });
// setState(ViewState.idle);
// }
//
// fetchBranchCategory(String countryCode) async {
// category = null;
// services = null;
// categoryId = -1;
// categoryDropList.clear();
// setState(ViewState.busy);
// category = await branchRepo.fetchBranchCategory();
// category!.data?.forEach((element) {
// categoryDropList.add(DropValue(
// element.id ?? 0,
// ((element.categoryName!.isEmpty
// ? "N/A"
// : countryCode == "SA"
// ? element.categoryNameN
// : element.categoryName) ??
// "N/A"),
// ""));
// });
// setState(ViewState.idle);
// }
//
// fetchServicesByCategoryId() async {
// setState(ViewState.busy);
// services = await branchRepo.fetchServicesByCategoryId(categoryId.toString());
// servicesDropList = [];
// for (var element in services!.data!) {
// servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
// }
// setState(ViewState.idle);
// }
//
// Future<MResponse> createService(List<Map<String, dynamic>> map) async {
// return await branchRepo.createService(map);
// }
//
// Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
// return await branchRepo.updateService(map);
// }
// }

@ -0,0 +1,54 @@
import 'dart:io';
import 'package:car_provider_app/common/item_model.dart';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:mc_common_app/models/m_response.dart';
import 'package:mc_common_app/services/services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:file_picker/file_picker.dart';
class ItemsVM extends BaseVM {
final ItemsRepo itemsRepo;
final CommonServices commonServices;
ItemsVM({required this.itemsRepo, required this.commonServices});
//Items
ItemModel? serviceItems;
Future<String?> selectFile() async {
File? file = await commonServices.pickFile(fileType: FileType.image);
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000) {
Utils.showToast("File is larger then 1KB");
} else {
return Utils.convertFileToBase64(file);
}
} else {
// User canceled the picker
}
return null;
}
Future<MResponse> createServiceItem(Map map) async {
MResponse response = await itemsRepo.createServiceItems(map);
return response;
}
Future<ItemModel?> getServiceItems(int serviceId) async {
setState(ViewState.busy);
serviceItems = await itemsRepo.getServiceItems(serviceId);
setState(ViewState.idle);
return serviceItems;
}
Future<MResponse> updateServiceItem(Map map) async {
MResponse response = await itemsRepo.updateServiceItem(map);
return response;
}
}

@ -0,0 +1,94 @@
import 'package:car_provider_app/common/schedule_model.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
import 'package:mc_common_app/models/m_response.dart';
import 'package:mc_common_app/models/profile/services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
class ScheduleVM extends BaseVM {
ScheduleRepo scheduleRepo;
ScheduleVM({required this.scheduleRepo});
List<PickerItem> selectedServicesItems = [];
List<ServicesData>? servicesList;
List<PickerItem> selectedDaysItems = [];
Schedule? schedule;
refresh() {
setState(ViewState.idle);
}
getAllServices() async {
if (servicesList == null) {
Services services = await scheduleRepo.getAllServices();
if (services.messageStatus == 1) {
servicesList = services.data;
}
setState(ViewState.idle);
}
}
filterSelectedServices() {
if (servicesList != null) {
selectedServicesItems = [];
for (var element in servicesList!) {
if (element.isSelected ?? false) {
selectedServicesItems.add(PickerItem(id: element.id ?? 0, title: element.description ?? ""));
}
}
setState(ViewState.idle);
}
}
//Days
List<PickerItem> intiDays() {
List<PickerItem> initDays = [
PickerItem(id: 1, title: "Monday", isSelected: false),
PickerItem(id: 2, title: "Tuesday", isSelected: false),
PickerItem(id: 3, title: "Wednesday", isSelected: false),
PickerItem(id: 4, title: "Thursday", isSelected: false),
PickerItem(id: 5, title: "Friday", isSelected: false),
PickerItem(id: 6, title: "Saturday", isSelected: false),
PickerItem(id: 7, title: "Sunday", isSelected: false),
];
if (selectedDaysItems.isNotEmpty) {
for (var element in selectedDaysItems) {
if (element.isSelected ?? false) {
for (var innerElement in initDays) {
if (element.id == innerElement.id) {
innerElement.isSelected = true;
}
}
}
}
}
return initDays;
}
filterDays(List<PickerItem> picked) {
selectedDaysItems = [];
for (var element in picked) {
if (element.isSelected ?? false) {
selectedDaysItems.add(element);
}
}
setState(ViewState.idle);
}
Future<MResponse> createSchedule(Map map) async {
MResponse response = await scheduleRepo.createSchedule(map);
return response;
}
Future<MResponse> addServicesInSchedule(Map map) async {
MResponse response = await scheduleRepo.addServicesInSchedule(map);
return response;
}
getSchedules() async {
schedule = await scheduleRepo.getSchedules();
setState(ViewState.idle);
}
}

@ -0,0 +1,185 @@
import 'dart:io';
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:mc_common_app/models/m_response.dart';
import 'package:mc_common_app/models/model/branch2.dart';
import 'package:mc_common_app/models/profile/categroy.dart';
import 'package:mc_common_app/models/profile/document.dart';
import 'package:mc_common_app/models/profile/services.dart';
import 'package:mc_common_app/models/user/cities.dart';
import 'package:mc_common_app/models/user/country.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:file_picker/file_picker.dart';
class ServiceVM extends BaseVM {
final BranchRepo branchRepo;
final CommonServices commonServices;
final CommonRepo commonRepo;
ServiceVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
//Documents & Branches
Document? document;
Branch2? branchs;
Country? country;
Cities? cities;
DropValue? countryValue;
DropValue? cityValue;
List<DropValue> countryDropList = [];
List<DropValue> citiesDropList = [];
double latitude = 0, longitude = 0;
int role = -1, countryId = -1, cityId = -1;
String countryCode = "", address = "", branchName = "", branchDescription = "";
getServiceProviderDocument(int providerId) async {
setState(ViewState.busy);
document = await branchRepo.getServiceProviderDocument(providerId);
setState(ViewState.idle);
}
selectFile(int index) async {
File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000) {
Utils.showToast("File is larger then 1KB");
} else {
document!.data![index].document = Utils.convertFileToBase64(file);
document!.data![index].fileExt = Utils.checkFileExt(file.path);
document!.data![index].documentUrl = file.path;
setState(ViewState.idle);
}
} else {
// User canceled the picker
}
}
Future<MResponse> updateDocument(List<DocumentData>? data) async {
return await branchRepo.serviceProviderDocumentsUpdate(data);
}
//Create new branch
getBranchAndServices() async {
setState(ViewState.busy);
branchs = await branchRepo.getBranchAndServices();
setState(ViewState.idle);
}
getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
setState(ViewState.busy);
resetValues();
country = await commonRepo.getAllCountries();
country!.data?.forEach((element) {
if (branchData != null) if (branchData.id != null) {
if (element.id == branchData.countryID) {
countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
}
}
countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
});
if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
setState(ViewState.idle);
}
getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
setState(ViewState.busy);
citiesDropList.clear();
cities = null;
cityId = -1;
cities = await commonRepo.getAllCites(countryId.toString());
cities!.data?.forEach((element) {
if (branchData != null && branchData.id != null) {
if (element.id == branchData.cityId) {
address = branchData.address!;
branchName = branchData.branchName!;
branchDescription = branchData.branchDescription!;
latitude = double.parse(branchData.latitude ?? "");
longitude = double.parse(branchData.longitude ?? "");
countryId = branchData.countryID!;
cityId = branchData.cityId!;
cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
}
}
citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
});
setState(ViewState.idle);
}
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
}
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
}
resetValues() {
countryCode = "";
address = "";
branchName = "";
branchDescription = "";
latitude = 0;
longitude = 0;
role = -1;
countryId = -1;
cityId = -1;
countryDropList.clear();
countryId = -1;
cityId = -1;
cities = null;
categoryDropList = [];
servicesDropList = [];
services = null;
}
//Create Services
Services? services;
List<DropValue> categoryDropList = [];
List<DropValue> servicesDropList = [];
fetchBranchCategory(String countryCode) async {
categoryDropList.clear();
servicesDropList = [];
services = null;
setState(ViewState.busy);
Category? category = await branchRepo.fetchBranchCategory();
category.data?.forEach((element) {
categoryDropList.add(DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
""));
});
setState(ViewState.idle);
}
fetchServicesByCategoryId(String categoryId) async {
servicesDropList = [];
setState(ViewState.busy);
services = await branchRepo.fetchServicesByCategoryId(categoryId);
for (var element in services!.data!) {
servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
}
setState(ViewState.idle);
}
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
return await branchRepo.createService(map);
}
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map);
}
}

@ -0,0 +1,73 @@
import 'package:car_provider_app/common/subscription_model.dart';
import 'package:car_provider_app/repositories/subscription_repo.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
class SubscriptionsVM extends BaseVM {
final SubscriptionRepo subscriptionRepo;
SubscriptionsVM({required this.subscriptionRepo});
//All Subscriptions
int selectedIndex = 0;
late DropValue selectedMothlyTab;
List<DropValue> monthlyTabs = [];
late SubscriptionModel allSubscriptions;
List<Subscription> tempSubscriptions = [];
//My Subscriptions
//All Subscriptions
getAllAvailableSubscriptions(String? serviceProviderID) async {
selectedIndex = 0;
setState(ViewState.busy);
allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
if (allSubscriptions.messageStatus == 1) {
monthlyTabs.clear();
var idSet = <int>{};
for (var d in allSubscriptions.data ?? []) {
if (idSet.add(d.durationDays ?? 0)) {
monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
}
}
monthlyTabs.sort((a, b) => a.value.compareTo(b.value));
selectedMothlyTab = monthlyTabs.first;
filterSubscriptions();
setState(ViewState.idle);
} else {
setState(ViewState.error);
}
}
String _convertDaysToMonths(int days) {
final int months = days ~/ 30;
final int remainingDays = days % 30;
String _result = months > 0 ? '$months Month${months > 1 ? 's' : ''}${remainingDays > 0 ? ' & ' : ''}' : '';
_result += remainingDays > 0 ? '$remainingDays Day${remainingDays > 1 ? 's' : ''}' : '';
return _result;
}
filterSubscriptions() {
tempSubscriptions.clear();
for (var element in allSubscriptions.data!) {
if (selectedMothlyTab.id == element.durationDays) {
tempSubscriptions.add(element);
}
}
}
//My Subscriptions
getMySubscriptions(String? serviceProviderID) async {
selectedIndex = 0;
setState(ViewState.busy);
allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
if (allSubscriptions.messageStatus == 1) {
// allSubscriptions.data!.sort((a, b) => a.value.compareTo(b.value));
setState(ViewState.idle);
} else {
setState(ViewState.error);
}
}
}

@ -3,7 +3,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/common_widgets/ad_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/my_service_provider.dart';
import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart';
@ -13,7 +13,8 @@ import '../widget/appointment_slider_widget.dart';
class HomeFragment extends StatelessWidget {
VoidCallback onTap;
HomeFragment({required this.onTap,Key? key}) : super(key: key);
HomeFragment({required this.onTap, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -52,25 +53,28 @@ class HomeFragment extends StatelessWidget {
padding: const EdgeInsets.only(top: 8, left: 21, right: 21, bottom: 21),
child: Column(
children: [
const ViewAllWidget(
ViewAllWidget(
title: 'Upcoming Appointment',
subTitle: 'View All',
onSubtitleTapped: () {},
),
const AppointmentSliderWidget(),
21.height,
const ViewAllWidget(
ViewAllWidget(
title: 'My Branches',
subTitle: 'View All',
onSubtitleTapped: () {},
),
const ServiceProviderWidget(),
21.height,
const ViewAllWidget(
ViewAllWidget(
title: 'Recommended Ads',
subTitle: 'View All',
onSubtitleTapped: () {},
),
const AdWidget(
count: 4,
),
// const AdWidget(
// count: 4,
// ),
],
),
),

@ -1,4 +1,6 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/settings/services/services_list_page.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
@ -14,14 +16,12 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.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 '../../../generated/locale_keys.g.dart';
class BranchDetailPage extends StatelessWidget {
ServiceProviderBranch branchData;
@ -52,9 +52,9 @@ class BranchDetailPage extends StatelessWidget {
branchData.categories = categories;
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.branchName.tr(),
title: branchData.branchName.toString(),
),
body: Consumer<BranchVM>(builder: (context, model, _) {
body: Consumer<ServiceVM>(builder: (context, model, _) {
return SizedBox(
width: double.infinity,
height: double.infinity,
@ -62,71 +62,160 @@ class BranchDetailPage extends StatelessWidget {
children: [
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.all(20),
child: Column(
children: [
Row(
children: [
Expanded(
child: titleWidget(MyAssets.icBranches, LocaleKeys.branchInfo),
),
IconButton(
onPressed: () {
navigateWithName(context, ProviderAppRoutes.defineBranch, arguments: branchData);
},
icon: const Icon(
Icons.edit,
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: titleWidget(MyAssets.icBranches, LocaleKeys.branchInfo.tr()),
),
IconButton(
onPressed: () {
navigateWithName(context, ProviderAppRoutes.defineBranch, arguments: branchData);
},
icon: SvgPicture.asset(MyAssets.icEdit),
)
],
),
)
],
),
8.height,
Column(
children: [
showData("${LocaleKeys.country.tr()}:", branchData.countryName.toString()),
showData("${LocaleKeys.city.tr()}:", branchData.cityName.toString()),
showData("${LocaleKeys.branchName.tr()}:", branchData.branchName.toString()),
showData("${LocaleKeys.branchDescription.tr()}:", branchData.branchDescription.toString()),
showData("${LocaleKeys.address.tr()}:", branchData.address.toString()),
],
Column(
children: [
showData("${LocaleKeys.country.tr()}:", branchData.countryName.toString()),
showData("${LocaleKeys.city.tr()}:", branchData.cityName.toString()),
showData("${LocaleKeys.branchName.tr()}:", branchData.branchName.toString()),
showData("${LocaleKeys.branchDescription.tr()}:", branchData.branchDescription.toString()),
showData("${LocaleKeys.address.tr()}:", branchData.address.toString()),
],
),
],
),
),
Container(
width: double.infinity,
height: 1,
color: Colors.grey,
margin: EdgeInsets.symmetric(vertical: 12),
),
color: MyColors.darkIconColor,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
child: Row(
children: [
const Icon(
Icons.calendar_month,
color: Colors.white,
),
8.width,
Expanded(
child: "Set or Edit Branch Schedule".toText(
isUnderLine: true,
fontSize: 14,
isBold: true,
color: Colors.white,
),
),
const Icon(
Icons.arrow_forward,
size: 20,
color: Colors.white,
),
],
),
).onPress(() {
navigateWithName(context, ProviderAppRoutes.schedulesList, arguments: branchData.id.toString());
}),
categories.isEmpty
? LocaleKeys.no_branch.tr().toText(fontSize: 12)
: ListView.builder(
: ListView.separated(
itemBuilder: (context, pIndex) {
return Container(
width: double.infinity,
child: Column(
return InkWell(
onTap: () {
categories[pIndex].branchId = branchData.id.toString();
categories[pIndex].branchName = branchData.branchName.toString();
navigateWithName(context, ProviderAppRoutes.servicesList, arguments: categories[pIndex]);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
categories[pIndex].categoryName.toString().toText(fontSize: 16, isBold: true),
ListView.builder(
itemBuilder: (context, index) {
return Container(
child:
("- ${EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? categories[pIndex].services![index].serviceNameN.toString() : categories[pIndex].services![index].serviceName.toString()}")
.toText(fontSize: 14),
);
},
itemCount: categories[pIndex].services?.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
)
Padding(
padding: const EdgeInsets.only(top: 5),
child: SvgPicture.asset(
MyAssets.maintenanceIcon,
width: 16,
height: 16,
),
),
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
categories[pIndex].categoryName.toString().toText(fontSize: 16, isBold: true),
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset(
// MyAssets.icEdit,
// width: 16,
// height: 16,
// ),
// ),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
Row(
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return Container(
child: (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA"
? categories[pIndex].services![index].serviceNameN.toString()
: categories[pIndex].services![index].serviceName.toString())
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
);
},
itemCount: categories[pIndex].services?.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
),
),
const Padding(
padding: EdgeInsets.all(4.0),
child: Icon(
Icons.arrow_forward,
size: 20,
),
),
],
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
)
],
)),
],
).toContainer(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
isShadowEnabled: true,
),
);
},
itemCount: categories.length,
physics: NeverScrollableScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20),
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
),
12.height,
],
),
),
@ -139,13 +228,16 @@ class BranchDetailPage extends StatelessWidget {
Padding(
padding: const EdgeInsets.all(12.0),
child: ShowFillButton(
title: LocaleKeys.editServices,
title: "Add Services",
maxWidth: double.infinity,
onPressed: () {
navigateWithName(
context,
ProviderAppRoutes.createServices,
arguments: branchData,
ProviderAppRoutes.createServices3,
arguments: CreateBranchModel(
branchId: branchData.id.toString(),
branchName: branchData.branchName.toString(),
),
);
},
),
@ -174,12 +266,15 @@ class BranchDetailPage extends StatelessWidget {
Widget showData(String title, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
title.toText(fontSize: 10, color: Colors.black, isBold: true),
8.width,
value.toText(
fontSize: 12,
color: MyColors.textColor,
Flexible(
child: value.toText(
fontSize: 12,
color: MyColors.textColor,
),
)
],
);

@ -1,4 +1,5 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
@ -29,7 +30,7 @@ class BranchListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
BranchVM branchVM = context.read<BranchVM>();
ServiceVM branchVM = context.read<ServiceVM>();
branchVM.getBranchAndServices();
return Scaffold(
appBar: !isNeedAppBar
@ -49,7 +50,7 @@ class BranchListPage extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer<BranchVM>(
child: Consumer<ServiceVM>(
builder: (context, model, _) {
if (model.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());

@ -1,4 +1,5 @@
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -19,8 +20,6 @@ import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class DefineBranchPage extends StatelessWidget {
ServiceProviderBranch? branchData;
@ -28,11 +27,13 @@ class DefineBranchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
BranchVM branchVM = context.read<BranchVM>();
ServiceVM branchVM = context.read<ServiceVM>();
branchVM.getAllCountriesList(branchData, EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
return Scaffold(
appBar: const CustomAppBar(),
body: Consumer<BranchVM>(builder: (context, model, _) {
appBar: CustomAppBar(
title: LocaleKeys.defineBranches.tr(),
),
body: Consumer<ServiceVM>(builder: (context, model, _) {
return SizedBox(
width: double.infinity,
height: double.infinity,
@ -44,12 +45,8 @@ class DefineBranchPage extends StatelessWidget {
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
LocaleKeys.defineBranches.tr().toText(fontSize: 20, isBold: true),
12.height,
LocaleKeys.branchLocation.tr().toText(fontSize: 14, color: MyColors.lightTextColor),
20.height,
LocaleKeys.chooseCountry.tr().toText(fontSize: 14, color: MyColors.lightTextColor),
8.height,
// LocaleKeys.chooseCountry.tr().toText(fontSize: 14, color: MyColors.lightTextColor),
// 8.height,
model.country != null
? DropdownField(
(DropValue value) {
@ -129,7 +126,7 @@ class DefineBranchPage extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: MyColors.darkPrimaryColor, width: 2),
borderRadius: BorderRadius.all(Radius.circular(8)),
borderRadius: const BorderRadius.all(Radius.circular(8)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
@ -170,10 +167,10 @@ class DefineBranchPage extends StatelessWidget {
child: ShowFillButton(
title: branchData != null ? (branchData!.id == null ? LocaleKeys.createBranch.tr() : LocaleKeys.updateBranch.tr()) : LocaleKeys.createBranch.tr(),
onPressed: () async {
if (branchData == null) {
Utils.showLoading(context);
MResponse res = await model.createBranch(model.branchName, model.branchDescription,model. cityId.toString(), model.address, model.latitude.toString(), model.longitude.toString());
MResponse res =
await model.createBranch(model.branchName, model.branchDescription, model.cityId.toString(), model.address, model.latitude.toString(), model.longitude.toString());
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast(LocaleKeys.branch_created.tr());
@ -184,8 +181,8 @@ class DefineBranchPage extends StatelessWidget {
}
} else {
Utils.showLoading(context);
MResponse res =
await model.updateBranch(branchData!.id ?? 0, model.branchName, model.branchDescription, model.cityId.toString(), model.address, model.latitude.toString(), model.longitude.toString());
MResponse res = await model.updateBranch(
branchData!.id ?? 0, model.branchName, model.branchDescription, model.cityId.toString(), model.address, model.latitude.toString(), model.longitude.toString());
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast(LocaleKeys.branch_updated.tr());

@ -1,209 +1,211 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:car_provider_app/view_models/branch_view_model.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/m_response.dart';
import 'package:mc_common_app/models/model/branch2.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/utils/utils.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';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class CreateServicesPage extends StatelessWidget {
ServiceProviderBranch? serviceProviderBranch;
CreateServicesPage(this.serviceProviderBranch);
@override
Widget build(BuildContext context) {
BranchVM branchVM = context.read<BranchVM>();
branchVM.getBranchAndServices();
branchVM.fetchBranches();
if (serviceProviderBranch != null) {
branchVM.branchId = serviceProviderBranch!.id ?? -1;
branchVM.branchValue = DropValue(branchVM.branchId, serviceProviderBranch!.branchName ?? "", "");
print("llll1 ${branchVM.branchId} ${serviceProviderBranch!.branchName} ${branchVM.branchValue!.value}");
if (branchVM.branchId != 1) branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
}
return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer<BranchVM>(builder: (context, model, _) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: [
model.branch != null
? (model.branchValue != null && model.branchId != -1)
? Text(
model.branchValue!.value ?? "",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
).toContainer(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
backgroundColor: MyColors.textFieldColor,
borderRadius: 0,
width: double.infinity,
)
: DropdownField(
(DropValue value) {
// countryCode = value.subValue;
// countryId = value.id;
// fetchCites();
model.branchId = value.id;
model.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
model.setState(ViewState.idle);
},
list: model.countryDropListForService,
hint: LocaleKeys.selectBranch.tr(),
dropdownValue: model.branchValue,
)
: const CircularProgressIndicator(),
12.height,
(model.category != null)
? DropdownField((DropValue value) {
// countryCode = value.subValue;
// countryId = value.id;
// fetchCites();
model.categoryId = value.id;
model.fetchServicesByCategoryId();
model.setState(ViewState.idle);
}, list: model.categoryDropList, hint: LocaleKeys.selectServiceCategory.tr())
: model.branchId == -1
? Container()
: const CircularProgressIndicator(),
12.height,
if ((model.categoryId != -1))
model.services == null
? const CircularProgressIndicator()
: ListView.separated(
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Checkbox(
value: model.services!.data![index].isSelected,
onChanged: (v) {
model.services!.data![index].isSelected = v;
model.setState(ViewState.idle);
},
),
12.width,
((EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? model.services!.data![index].descriptionN : model.services!.data![index].description) ??
"")
.toText(fontSize: 12)
],
),
);
},
separatorBuilder: (context, index) {
return 1.height;
},
itemCount: model.services!.data!.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
)
],
),
),
),
),
if (checkServicesSelection(model))
Padding(
padding: const EdgeInsets.all(12.0),
child: ShowFillButton(
title: LocaleKeys.save.tr(),
maxWidth: double.infinity,
onPressed: () {
createService(context, model);
},
),
),
],
);
}),
),
);
}
bool checkServicesSelection(BranchVM model) {
bool isServiceSelected = false;
try {
for (var element in model.services!.data!) {
if (element.isSelected ?? false) isServiceSelected = true;
}
} catch (e) {
isServiceSelected = false;
}
return isServiceSelected;
}
createService(BuildContext context, BranchVM model) async {
List<Map<String, dynamic>> map = [];
if (serviceProviderBranch != null && model.branchId != -1) {
for (int i = 0; i < model.services!.data!.length; i++) {
if (model.services!.data![i].isSelected ?? false) {
var postParams = {
// "id": services!.data![i].id,
"providerBranchID": model.branchId,
"serviceID": model.services!.data![i].id,
"isAllowAppointment": true,
"isActive": true
};
map.add(postParams);
}
}
Utils.showLoading(context);
MResponse mResponse = await model.createService(map);
Utils.hideLoading(context);
if (serviceProviderBranch != null) {
Utils.showToast(mResponse.message ?? "");
if (mResponse.messageStatus != 2) {
pop(context);
pop(context);
model.getBranchAndServices();
}
}
} else {
for (int i = 0; i < model.services!.data!.length; i++) {
if (model.services!.data![i].isSelected ?? false) {
var postParams = {
// "id": services!.data![i].id,
"providerBranchID": model.branchId,
"serviceID": model.services!.data![i].id,
"isAllowAppointment": true,
"isActive": true
};
map.add(postParams);
}
}
Utils.showLoading(context);
MResponse mResponse = await model.createService(map);
model.getBranchAndServices();
Utils.hideLoading(context);
Utils.showToast(mResponse.message ?? "");
}
}
}
// import 'package:car_provider_app/view_models/service_view_model.dart';
// import 'package:easy_localization/easy_localization.dart';
//
// import 'package:flutter/material.dart';
//
// import 'package:car_provider_app/generated/locale_keys.g.dart';
//
// import 'package:car_provider_app/view_models/branch_view_model.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/m_response.dart';
// import 'package:mc_common_app/models/model/branch2.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/utils/utils.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';
// import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
//
// import 'package:provider/provider.dart';
//
// class CreateServicesPage extends StatelessWidget {
// ServiceProviderBranch? serviceProviderBranch;
//
// CreateServicesPage(this.serviceProviderBranch, {Key? key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// ServiceVM branchVM = context.read<ServiceVM>();
// branchVM.getBranchAndServices();
// branchVM.fetchBranches();
// if (serviceProviderBranch != null) {
// // branchVM.branchId = serviceProviderBranch!.id ?? -1;
// // branchVM.branchValue = DropValue(branchVM.branchId, serviceProviderBranch!.branchName ?? "", "");
// // print("llll1 ${branchVM.branchId} ${serviceProviderBranch!.branchName} ${branchVM.branchValue!.value}");
// if (branchVM.branchId != 1) branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
// }
//
// return Scaffold(
// appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
// body: SizedBox(
// width: double.infinity,
// height: double.infinity,
// child: Consumer<ServiceVM>(builder: (context, model, _) {
// return Column(
// children: [
// Expanded(
// child: SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(12.0),
// child: Column(
// children: [
// model.branch != null
// ? (model.branchValue != null && model.branchId != -1)
// ? Text(
// model.branchValue!.value ?? "",
// style: const TextStyle(
// fontSize: 12,
// fontWeight: FontWeight.bold,
// ),
// ).toContainer(
// padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
// backgroundColor: MyColors.textFieldColor,
// borderRadius: 0,
// width: double.infinity,
// )
// : DropdownField(
// (DropValue value) {
// // countryCode = value.subValue;
// // countryId = value.id;
// // fetchCites();
// model.branchId = value.id;
// model.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
// model.setState(ViewState.idle);
// },
// list: model.countryDropListForService,
// hint: LocaleKeys.selectBranch.tr(),
// dropdownValue: model.branchValue,
// )
// : const CircularProgressIndicator(),
// 12.height,
// (model.category != null)
// ? DropdownField((DropValue value) {
// // countryCode = value.subValue;
// // countryId = value.id;
// // fetchCites();
// model.categoryId = value.id;
// model.fetchServicesByCategoryId();
// model.setState(ViewState.idle);
// }, list: model.categoryDropList, hint: LocaleKeys.selectServiceCategory.tr())
// : model.branchId == -1
// ? Container()
// : const CircularProgressIndicator(),
// 12.height,
// if ((model.categoryId != -1))
// model.services == null
// ? const CircularProgressIndicator()
// : ListView.separated(
// itemBuilder: (context, index) {
// return Padding(
// padding: const EdgeInsets.all(8.0),
// child: Row(
// children: [
// Checkbox(
// value: model.services!.data![index].isSelected,
// onChanged: (v) {
// model.services!.data![index].isSelected = v;
// model.setState(ViewState.idle);
// },
// ),
// 12.width,
// ((EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? model.services!.data![index].descriptionN : model.services!.data![index].description) ??
// "")
// .toText(fontSize: 12)
// ],
// ),
// );
// },
// separatorBuilder: (context, index) {
// return 1.height;
// },
// itemCount: model.services!.data!.length,
// physics: NeverScrollableScrollPhysics(),
// shrinkWrap: true,
// )
// ],
// ),
// ),
// ),
// ),
// if (checkServicesSelection(model))
// Padding(
// padding: const EdgeInsets.all(12.0),
// child: ShowFillButton(
// title: LocaleKeys.save.tr(),
// maxWidth: double.infinity,
// onPressed: () {
// createService(context, model);
// },
// ),
// ),
// ],
// );
// }),
// ),
// );
// }
//
// bool checkServicesSelection(BranchVM model) {
// bool isServiceSelected = false;
// try {
// for (var element in model.services!.data!) {
// if (element.isSelected ?? false) isServiceSelected = true;
// }
// } catch (e) {
// isServiceSelected = false;
// }
//
// return isServiceSelected;
// }
//
// createService(BuildContext context, BranchVM model) async {
// List<Map<String, dynamic>> map = [];
// if (serviceProviderBranch != null && model.branchId != -1) {
// for (int i = 0; i < model.services!.data!.length; i++) {
// if (model.services!.data![i].isSelected ?? false) {
// var postParams = {
// // "id": services!.data![i].id,
// "providerBranchID": model.branchId,
// "serviceID": model.services!.data![i].id,
// "isAllowAppointment": true,
// "isActive": true
// };
// map.add(postParams);
// }
// }
// Utils.showLoading(context);
// MResponse mResponse = await model.createService(map);
// Utils.hideLoading(context);
//
// if (serviceProviderBranch != null) {
// Utils.showToast(mResponse.message ?? "");
// if (mResponse.messageStatus != 2) {
// pop(context);
// pop(context);
// model.getBranchAndServices();
// }
// }
// } else {
// for (int i = 0; i < model.services!.data!.length; i++) {
// if (model.services!.data![i].isSelected ?? false) {
// var postParams = {
// // "id": services!.data![i].id,
// "providerBranchID": model.branchId,
// "serviceID": model.services!.data![i].id,
// "isAllowAppointment": true,
// "isActive": true
// };
// map.add(postParams);
// }
// }
// Utils.showLoading(context);
// MResponse mResponse = await model.createService(map);
// model.getBranchAndServices();
// Utils.hideLoading(context);
// Utils.showToast(mResponse.message ?? "");
// }
// }
// }

@ -44,7 +44,7 @@ class DealershipPage extends StatelessWidget {
),
title: LocaleKeys.defineServices.tr().toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.createServices);
navigateWithName(context, ProviderAppRoutes.createServices2);
},
),
ListTile(

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
@ -29,13 +30,13 @@ class DefineLicensePage extends StatefulWidget {
}
class _DefineLicensePageState extends State<DefineLicensePage> {
late BranchVM branchVM;
late ServiceVM branchVM;
@override
void initState() {
// TODO: implement initState
super.initState();
branchVM = Provider.of<BranchVM>(context, listen: false);
branchVM = Provider.of<ServiceVM>(context, listen: false);
branchVM.getServiceProviderDocument(AppState().getUser.data!.userInfo!.providerId ?? 0);
}
@ -46,7 +47,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
title: LocaleKeys.defineLicences.tr(),
isRemoveBackButton: false,
),
body: Consumer<BranchVM>(builder: (_, model, __) {
body: Consumer<ServiceVM>(builder: (_, model, __) {
return Column(
children: [
Expanded(
@ -89,7 +90,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
);
}
validation(BranchVM model) {
validation(ServiceVM model) {
bool valid = true;
model.document!.data!.forEach((element) {
if (element.documentUrl == null) {
@ -99,7 +100,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
return valid;
}
updateDocument(BranchVM model) async {
updateDocument(ServiceVM model) async {
Utils.showLoading(context);
MResponse res = await model.updateDocument(model.document!.data);
Utils.hideLoading(context);
@ -110,7 +111,7 @@ class _DefineLicensePageState extends State<DefineLicensePage> {
}
}
Widget showWidget(BranchVM model) {
Widget showWidget(ServiceVM model) {
if (model.state == ViewState.idle) {
return model.document!.data!.isEmpty
? Text("LocaleKeys.somethingWrong.tr()")

@ -0,0 +1,286 @@
import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/select_days_sheet.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/select_services_sheet.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.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/m_response.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/utils.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/txt_field.dart';
import 'package:provider/provider.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
class AddSchedulesPage extends StatelessWidget {
ScheduleVM? mModel;
String branchId = "", name = "", startDate = "", endDate = "", startTime = "", endTime = "", slotsTime = "", appointmentPerSlot = "";
AddSchedulesPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
branchId = ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
appBar: const CustomAppBar(
title: "Create Schedules",
),
body: SizedBox(
width: double.infinity,
child: Consumer<ScheduleVM>(
builder: (_, ScheduleVM model, child) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
TxtField(
hint: "Name of Schedule",
value: name,
onChanged: (v) {
name = v;
},
),
8.height,
ChipsPickerItem(
hint: 'Select Services',
itemsList: [...model.selectedServicesItems],
onClick: () {
showMyBottomSheet(
context,
child: SelectServicesSheet(
onSelectServices: () {
model.filterSelectedServices();
FocusManager.instance.primaryFocus?.unfocus();
},
),
);
},
),
8.height,
TxtField(
hint: "Starting Date",
value: startDate,
postfixWidget: const Icon(
Icons.calendar_month,
size: 16,
),
isNeedClickAll: true,
onTap: () async {
startDate = await Utils.pickDateFromDatePicker(
context,
firstDate: DateTime.now(),
);
FocusManager.instance.primaryFocus?.unfocus();
model.refresh();
},
),
8.height,
TxtField(
hint: "End Date",
postfixWidget: const Icon(
Icons.calendar_month,
size: 16,
),
value: endDate,
isNeedClickAll: true,
onTap: () async {
endDate = await Utils.pickDateFromDatePicker(
context,
firstDate: DateTime.now(),
);
FocusManager.instance.primaryFocus?.unfocus();
model.refresh();
},
),
8.height,
ChipsPickerItem(
hint: 'Days',
itemsList: [...model.selectedDaysItems],
onClick: () {
showMyBottomSheet(
context,
child: SelectDaysSheet(
onSelected: (List<PickerItem> picked) {
model.filterDays(picked);
FocusManager.instance.primaryFocus?.unfocus();
},
),
);
},
),
8.height,
Row(
children: [
Expanded(
child: TxtField(
hint: "Shift Start Time",
postfixWidget: const Icon(
Icons.access_time_filled_outlined,
size: 16,
),
value: startTime,
isNeedClickAll: true,
onTap: () async {
startTime = await Utils.pickTime(context);
FocusManager.instance.primaryFocus?.unfocus();
model.refresh();
},
),
),
8.width,
Expanded(
child: TxtField(
hint: "Shift End Time",
postfixWidget: const Icon(
Icons.access_time_filled_outlined,
size: 16,
),
value: endTime,
isNeedClickAll: true,
onTap: () async {
TimeOfDay _startTime = TimeOfDay.now();
if (startTime.isNotEmpty) _startTime = TimeOfDay(hour: int.parse(startTime.split(":")[0]), minute: int.parse(startTime.split(":")[1]));
endTime = await Utils.pickTime(
context,
initialTime: _startTime,
);
FocusManager.instance.primaryFocus?.unfocus();
model.refresh();
},
),
),
],
),
8.height,
TxtField(
hint: "Slots Time",
postfixWidget: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
"Min".toText(color: MyColors.lightTextColor),
],
),
keyboardType: TextInputType.number,
value: slotsTime,
onChanged: (v) {
slotsTime = v;
},
),
8.height,
TxtField(
hint: "Appointment Per Slot",
value: appointmentPerSlot,
keyboardType: TextInputType.number,
onChanged: (v) {
appointmentPerSlot = v;
},
),
],
),
),
),
ShowFillButton(
title: "Create",
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
if (validation(model)) {
createSchedule(context, model);
}
},
),
],
);
},
),
),
);
}
bool validation(ScheduleVM model) {
bool valid = true;
if (name.length < 3) {
Utils.showToast("Please enter valid schedule Name");
valid = false;
} else if (model.selectedServicesItems.isEmpty) {
Utils.showToast("");
valid = false;
} else if (startDate.isEmpty) {
Utils.showToast("");
valid = false;
} else if (endDate.isEmpty) {
Utils.showToast("");
valid = false;
} else if (model.selectedDaysItems.isEmpty) {
Utils.showToast("");
valid = false;
} else if (startTime.isEmpty) {
Utils.showToast("");
valid = false;
} else if (endTime.isEmpty) {
Utils.showToast("");
valid = false;
} else if (slotsTime.isEmpty) {
Utils.showToast("");
valid = false;
} else if (appointmentPerSlot.isEmpty) {
Utils.showToast("");
valid = false;
}
return valid;
}
createSchedule(BuildContext context, ScheduleVM model) async {
List<int> days = [];
for (var element in model.selectedDaysItems) {
days.add(element.id);
}
var map = {
"branchID": branchId,
"fromDate": startDate,
"toDate": endDate,
"startTime": startTime,
"endTime": endDate,
"slotDurationMinute": slotsTime,
"perSlotAppointment": appointmentPerSlot,
"deliveryServiceType": 1,
"weeklyOffDays": days
};
Utils.showLoading(context);
MResponse scheduleResponse = await model.createSchedule(map);
if (scheduleResponse.messageStatus == 1) {
List<int> services = [];
for (var element in model.selectedServicesItems) {
services.add(element.id);
}
var map1 = {
// "id": 0,
"branchAppointmentScheduleID": scheduleResponse.data["id"],
"serviceProviderServiceID": services,
"serviceGroupDescription": "string"
};
MResponse servicesResponse = await model.addServicesInSchedule(map1);
Utils.hideLoading(context);
if (servicesResponse.messageStatus == 1) {
Utils.showToast("Successfully schedule created");
} else {
Utils.showToast("Something went wrong while adding services in schedule");
}
} else {
Utils.hideLoading(context);
Utils.showToast("Something went wrong");
}
}
}

@ -0,0 +1,35 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
class SchedulesListPage extends StatelessWidget {
const SchedulesListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
String branchId = ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
appBar: const CustomAppBar(
title: "Schedules",
),
body: SizedBox(
width: double.infinity,
child: Column(
children: [
Expanded(child: Container()),
ShowFillButton(
title: "Create Schedule",
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
navigateWithName(context, ProviderAppRoutes.addSchedule, arguments: branchId);
},
)
],
),
),
);
}
}

@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:sizer/sizer.dart';
class PickerItem {
int id;
String title;
bool? isSelected;
PickerItem({required this.id, required this.title, this.isSelected});
}
class ChipsPickerItem extends StatelessWidget {
String hint;
List<PickerItem> itemsList;
Function onClick;
ChipsPickerItem({Key? key, required this.hint, required this.itemsList, required this.onClick}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
children: [
if (itemsList.isEmpty) Expanded(child: hint.toText(fontSize: 9.sp, color: borderColor)),
if (itemsList.isNotEmpty)
Expanded(
child: ListView(
scrollDirection: Axis.horizontal,
children: [
showItem(itemsList[0].title),
6.width,
if (itemsList.length > 1) showItem(itemsList[1].title),
6.width,
if (itemsList.length > 2) showItem("${itemsList.length - 2}+ more", isNeedToShowIcon: false),
6.width,
],
),
),
const Icon(
Icons.arrow_forward_ios_rounded,
size: 16,
color: MyColors.lightIconColor,
),
],
)
.toContainer(
width: double.infinity,
height: 45,
isEnabledBorder: true,
borderWidget: 2,
borderRadius: 0,
borderColor: MyColors.darkPrimaryColor,
)
.onPress(() {
onClick();
});
}
Widget showItem(String title, {bool isNeedToShowIcon = true}) {
return Container(
child: Row(
children: [
title.toText(fontSize: 12),
if (isNeedToShowIcon) 4.width,
if (isNeedToShowIcon)
const Icon(
Icons.close,
size: 8,
color: Colors.white,
).toContainer(
borderRadius: 100,
width: 12,
height: 12,
paddingAll: 0,
backgroundColor: MyColors.grey70Color,
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 6),
height: double.infinity,
color: MyColors.chipColor,
);
}
}

@ -0,0 +1,97 @@
import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.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/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class SelectDaysSheet extends StatefulWidget {
Function(List<PickerItem>) onSelected;
SelectDaysSheet({Key? key, required this.onSelected}) : super(key: key);
@override
State<SelectDaysSheet> createState() => _SelectDaysSheetState();
}
class _SelectDaysSheetState extends State<SelectDaysSheet> {
List<PickerItem> list = [];
@override
void initState() {
super.initState();
list = context.read<ScheduleVM>().intiDays();
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: MediaQuery.of(context).size.height / 1.4,
padding: const EdgeInsets.only(left: 20, right: 20, top: 6, bottom: 20),
child: Column(
children: [
Row(
children: [
Expanded(
child: "Select Days".toText(fontSize: 24, isBold: true),
),
Center(
child: list.where((element) => element.isSelected == true).toList().length.toString().toText(
fontSize: 10,
isBold: true,
color: Colors.white,
),
).toContainer(
borderRadius: 100,
width: 24,
height: 24,
paddingAll: 0,
backgroundColor: MyColors.darkPrimaryColor,
),
],
),
12.height,
Expanded(
child: ListView.separated(
itemBuilder: (BuildContext context, int index) {
return Row(
children: [
Checkbox(
value: list[index].isSelected,
onChanged: (bool? v) {
list[index].isSelected = v;
setState(() {});
},
),
12.width,
Expanded(
child: list[index].title.toText(),
),
],
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider(
height: 1,
);
},
itemCount: list.length,
),
),
ShowFillButton(
title: 'Add Selected Days',
maxWidth: double.infinity,
onPressed: () {
widget.onSelected(list);
Navigator.pop(context);
},
)
],
),
);
}
}

@ -0,0 +1,106 @@
import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/view_models/service_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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class SelectServicesSheet extends StatelessWidget {
Function onSelectServices;
SelectServicesSheet({Key? key, required this.onSelectServices}) : super(key: key);
@override
Widget build(BuildContext context) {
context.read<ScheduleVM>().getAllServices();
return SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height / 1.4,
child: Column(
children: [
Expanded(
child: Consumer<ScheduleVM>(
builder: (_, model, child) {
return Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 6),
child: Column(
children: [
Row(
children: [
Expanded(
child: "Select Services".toText(fontSize: 24, isBold: true),
),
Center(
child: model.servicesList!.where((element) => element.isSelected == true).toList().length.toString().toText(
fontSize: 10,
isBold: true,
color: Colors.white,
),
).toContainer(
borderRadius: 100,
width: 24,
height: 24,
paddingAll: 0,
backgroundColor: MyColors.darkPrimaryColor,
),
],
),
12.height,
TxtField(
hint: "Search Service",
onChanged: (v) {},
),
12.height,
Expanded(
child: model.servicesList == null
? const Center(child: CircularProgressIndicator())
: ListView.separated(
itemBuilder: (BuildContext context, int index) {
return Row(
children: [
Checkbox(
value: model.servicesList![index].isSelected,
onChanged: (bool? v) {
model.servicesList![index].isSelected = v;
model.notifyListeners();
},
),
12.width,
Expanded(
child: model.servicesList![index].description!.toText(),
),
],
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider(
height: 1,
);
},
itemCount: model.servicesList!.length,
),
),
],
),
);
},
),
),
ShowFillButton(
title: 'Add Selected Services',
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
onSelectServices();
Navigator.pop(context);
},
)
],
),
);
}
}

@ -0,0 +1,289 @@
import 'dart:convert';
import 'package:car_provider_app/common/item_model.dart';
import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
import 'package:car_provider_app/view_models/items_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/models/m_response.dart';
import 'package:mc_common_app/models/model/branch2.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/AppPermissionHandler.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.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:mc_common_app/widgets/txt_field.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class CreateItemPage extends StatefulWidget {
const CreateItemPage({Key? key}) : super(key: key);
@override
State<CreateItemPage> createState() => _CreateItemPageState();
}
class _CreateItemPageState extends State<CreateItemPage> {
String? name, description, price, year, itemImage;
bool isAppointmentAvailable = false;
bool isWorkshopAppointmentAvailable = false;
bool isHomeAppointmentAvailable = false;
bool isDefaultValudDone = false;
ItemsVM? model;
ItemData? itemData;
setDefaultData() {
name = itemData!.name;
description = itemData!.description;
price = itemData!.price;
print(itemData!.manufactureDate);
//TODO: need to discuss with zahoor year and picture
if (itemData!.manufactureDate != null) year = DateHelper.formatAsYearMonthDay(DateHelper.parseStringToDate(itemData!.manufactureDate ?? DateTime.now().toString()));
// itemImage=itemData.
isAppointmentAvailable = itemData!.isAllowAppointment ?? false;
isWorkshopAppointmentAvailable = itemData!.isAppointmentCompanyLoc ?? false;
isHomeAppointmentAvailable = itemData!.isAppointmentCustomerLoc ?? false;
isDefaultValudDone = true;
}
@override
Widget build(BuildContext context) {
model ??= context.read<ItemsVM>();
itemData ??= ModalRoute.of(context)!.settings.arguments as ItemData;
if (!isDefaultValudDone) setDefaultData();
return Scaffold(
appBar: const CustomAppBar(
title: "Add Items",
),
body: Container(
width: double.infinity,
height: double.infinity,
padding: const EdgeInsets.all(20),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
TxtField(
hint: "Item Name",
value: name,
onChanged: (v) {
name = v;
},
),
12.height,
TxtField(
hint: "Item Description",
value: description,
onChanged: (v) {
description = v;
},
),
12.height,
TxtField(
hint: "Item Price",
value: price,
keyboardType: TextInputType.number,
onChanged: (v) {
price = v;
},
),
12.height,
TxtField(
hint: "Manufacture Year",
value: year,
keyboardType: TextInputType.number,
isNeedClickAll: true,
postfixWidget: const IconButton(
onPressed: null,
icon: Icon(Icons.date_range),
),
onTap: () async {
year = await Utils.pickDateFromDatePicker(context, firstDate: DateTime(1990), lastDate: DateTime.now());
setState(() {});
},
onChanged: (v) {
year = v;
},
),
12.height,
if (itemImage != null && itemImage!.isNotEmpty)
Column(
children: [
Image.memory(
base64Decode(itemImage ?? ""),
).toContainer(
isEnabledBorder: true,
paddingAll: 12,
),
12.height,
],
),
InkWell(
onTap: () async {
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
if (isPermissionsAvailable && model != null) {
itemImage = await model!.selectFile() ?? "";
setState(() {});
}
},
child: Container(
width: double.infinity,
height: 45,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: MyColors.greyACColor, width: 2),
borderRadius: const BorderRadius.all(Radius.circular(0)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.attach_file,
size: 18,
color: MyColors.darkPrimaryColor,
),
8.width,
const Text(
"Attach Item Image",
style: TextStyle(
color: MyColors.darkPrimaryColor,
),
),
const Icon(
Icons.attach_file,
size: 18,
color: Colors.transparent,
),
],
),
),
),
20.height,
CheckBoxWithTitleDescription(
isSelected: isAppointmentAvailable,
title: 'Available for appointment',
description: 'This option will allow customer to book appointment for these services',
onSelection: (bool v) {
setState(() {
isAppointmentAvailable = v;
// isWorkshopAppointmentAvailable = v;
});
},
),
12.height,
if (isAppointmentAvailable)
CheckBoxWithTitleDescription(
isSelected: isWorkshopAppointmentAvailable,
title: 'Allow Workshop service',
description: 'This option will show to customer that you can avail this service on workshop or not.',
onSelection: (bool v) {
setState(() {
isWorkshopAppointmentAvailable = v;
});
},
),
12.height,
if (isAppointmentAvailable)
CheckBoxWithTitleDescription(
isSelected: isHomeAppointmentAvailable,
title: 'Allow home services',
description: 'This option will allow customer to book appointment at their desired location',
onSelection: (bool v) {
setState(() {
isHomeAppointmentAvailable = v;
});
},
),
12.height,
],
),
),
),
ShowFillButton(
title: (itemData!.isUpdate ?? false) ? "Update Item" : "Create Item",
maxWidth: double.infinity,
onPressed: () async {
if (validation()) {
if (!(itemData?.isUpdate ?? false)) {
Map map = {
"name": name,
"price": price,
"description": description,
"itemImage": itemImage ?? "",
"companyID": 1,
"manufactureDate": year,
"serviceProviderServiceID": itemData!.serviceProviderServiceId,
"isActive": true,
"isAllowAppointment": isAppointmentAvailable,
"isAppointmentCompanyLoc": isWorkshopAppointmentAvailable,
"isAppointmentCustomerLoc": isHomeAppointmentAvailable
};
Utils.showLoading(context);
MResponse mResponse = await model!.createServiceItem(map);
Utils.hideLoading(context);
if (mResponse.messageStatus == 1) {
model!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
}
Utils.showToast(mResponse.message ?? "");
pop(context);
} else {
Map map = {
"id": itemData!.id,
"name": name,
"price": price,
"description": description,
"itemImage": itemImage ?? "",
"companyID": 1,
"manufactureDate": year,
"serviceProviderServiceID": itemData!.serviceProviderServiceId,
"isActive": true,
"isAllowAppointment": isAppointmentAvailable,
"isAppointmentCompanyLoc": isWorkshopAppointmentAvailable,
"isAppointmentCustomerLoc": isHomeAppointmentAvailable
};
Utils.showLoading(context);
MResponse mResponse = await model!.updateServiceItem(map);
Utils.hideLoading(context);
if (mResponse.messageStatus == 1) {
model!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
}
Utils.showToast(mResponse.message ?? "");
pop(context);
}
}
},
),
],
),
),
);
}
bool validation() {
bool valid = true;
if (name == null || name!.length < 3) {
Utils.showToast("Please add valid item name");
valid = false;
} else if (description == null || description!.length < 3) {
Utils.showToast("Please add valid item description");
valid = false;
} else if (price == null) {
Utils.showToast("Please add valid item price");
valid = false;
} else if (year == null) {
Utils.showToast("Please add valid year");
valid = false;
}
return valid;
}
}

@ -0,0 +1,234 @@
// import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
// import 'package:car_provider_app/view_models/service_view_model.dart';
// import 'package:easy_localization/easy_localization.dart';
//
// import 'package:flutter/material.dart';
//
// import 'package:car_provider_app/generated/locale_keys.g.dart';
//
// import 'package:car_provider_app/view_models/branch_view_model.dart';
// import 'package:mc_common_app/classes/app_state.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/m_response.dart';
// import 'package:mc_common_app/models/model/branch2.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/utils/utils.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';
// import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
// import 'package:mc_common_app/widgets/txt_field.dart';
//
// import 'package:provider/provider.dart';
//
// class CreateServicesPage2 extends StatelessWidget {
// ServiceProviderBranch? serviceProviderBranch;
//
// CreateServicesPage2(this.serviceProviderBranch, {Key? key}) : super(key: key);
// bool isAppointmentAvailable = false;
// bool isHomeAppointmentAvailable = false;
// int serviceRage = 0;
// int chargersPerKm = 0;
//
// @override
// Widget build(BuildContext context) {
// ServiceVM branchVM = context.read<ServiceVM>();
//
// // if (serviceProviderBranch != null) {
// // branchVM.categoryDropList.clear();
// // branchVM.serviceId = -1;
// // branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
// // }
// // print(AppState().getUser.data!.accessToken);
//
// return Scaffold(
// appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
// body: SizedBox(
// width: double.infinity,
// height: double.infinity,
// child: Consumer<ServiceVM>(
// builder: (context, model, _) {
// return Column(
// children: [
// Expanded(
// child: SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(20.0),
// child: Column(
// children: [
// Text(
// serviceProviderBranch!.branchName ?? "N/A",
// style: const TextStyle(
// fontSize: 12,
// fontWeight: FontWeight.bold,
// ),
// ).toContainer(
// padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
// backgroundColor: MyColors.textFieldColor,
// borderRadius: 0,
// width: double.infinity,
// ),
// 12.height,
// (model.category != null)
// ? DropdownField(
// (DropValue value) {
// model.categoryId = value.id;
// model.services = null;
// model.serviceId = -1;
// isAppointmentAvailable = false;
// isHomeAppointmentAvailable = false;
// model.fetchServicesByCategoryId();
//
// // model.setState(ViewState.idle);
// },
// list: model.categoryDropList,
// hint: LocaleKeys.selectServiceCategory.tr(),
// )
// : const CircularProgressIndicator(),
// 12.height,
// (model.services != null)
// ? DropdownField(
// (DropValue value) {
// model.serviceId = value.id;
// isAppointmentAvailable = false;
// isHomeAppointmentAvailable = false;
// model.setState(ViewState.idle);
// },
// list: model.servicesDropList,
// hint: LocaleKeys.defineServices.tr(),
// )
// : model.categoryId == -1
// ? Container()
// : const CircularProgressIndicator(),
// 20.height,
// if (model.serviceId != -1)
// Column(
// children: [
// CheckBoxWithTitleDescription(
// isSelected: isAppointmentAvailable,
// title: 'Available for appointment',
// description: 'This option will allow customer to book appointment for these services',
// onSelection: (bool v) {
// isAppointmentAvailable = v;
// model.setState(ViewState.idle);
// },
// ),
// 20.height,
// CheckBoxWithTitleDescription(
// isSelected: isHomeAppointmentAvailable,
// title: 'Allow home services',
// description: 'This option will allow customer to book appointment at their desired location',
// onSelection: (bool v) {
// isHomeAppointmentAvailable = v;
// model.setState(ViewState.idle);
// },
// ),
// 20.height,
// if (isHomeAppointmentAvailable)
// Column(
// children: [
// TxtField(
// hint: "Home Services Range",
// keyboardType: TextInputType.number,
// postfixWidget: Row(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// "KM".toText(color: MyColors.lightTextColor),
// ],
// ),
// onChanged: (v) {
// if (v.isNotEmpty) {
// serviceRage = int.parse(v);
// } else {
// serviceRage = 0;
// }
// },
// ),
// 12.height,
// TxtField(
// hint: "Charges per Kilometer",
// keyboardType: TextInputType.number,
// onChanged: (v) {
// if (v.isNotEmpty) {
// chargersPerKm = int.parse(v);
// } else {
// chargersPerKm = 0;
// }
// },
// ),
// ],
// ),
// ],
// ),
// ],
// ),
// ),
// ),
// ),
// if (model.serviceId != -1)
// ShowFillButton(
// title: LocaleKeys.save.tr(),
// maxWidth: double.infinity,
// margin: const EdgeInsets.all(20),
// onPressed: () {
// createService(context, model);
// },
// ),
// ],
// );
// },
// ),
// ),
// );
// }
//
// bool checkServicesSelection(BranchVM model) {
// bool isServiceSelected = false;
// try {
// for (var element in model.services!.data!) {
// if (element.isSelected ?? false) isServiceSelected = true;
// }
// } catch (e) {
// isServiceSelected = false;
// }
//
// return isServiceSelected;
// }
//
// createService(BuildContext context, BranchVM model) async {
// List<Map<String, dynamic>> map = [];
// model.services!.data?.forEach((element) {
// if (model.serviceId == element.id) {
// element.isSelected = true;
// } else {
// element.isSelected = false;
// }
// });
//
// for (int i = 0; i < model.services!.data!.length; i++) {
// if (model.services!.data![i].isSelected ?? false) {
// var postParams = {
// // "id": services!.data![i].id,
// "providerBranchID": model.branchId,
// "serviceID": model.services!.data![i].id,
// "isAllowAppointment": isAppointmentAvailable,
// "isActive": true,
// "customerLocationRange": serviceRage,
// "rangePricePerKm": chargersPerKm
// };
// map.add(postParams);
// }
// }
// // print(map);
// Utils.showLoading(context);
// MResponse mResponse = await model.createService(map);
// model.getBranchAndServices();
// Utils.hideLoading(context);
// Utils.showToast(mResponse.message ?? "");
// }
// }

@ -0,0 +1,272 @@
import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/settings/services/services_list_page.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/models/m_response.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.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:easy_localization/easy_localization.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:provider/provider.dart';
class CreateServicesPage3 extends StatelessWidget {
CreateBranchModel? branchModel;
CreateServicesPage3(this.branchModel, {Key? key}) : super(key: key);
bool isAppointmentAvailable = false;
bool isHomeAppointmentAvailable = false;
int serviceRage = 0;
String chargersPerKm = "0";
int? categoryId;
int? serviceId = -1;
@override
Widget build(BuildContext context) {
ServiceVM serviceVM = context.read<ServiceVM>();
if (branchModel!.categoryId == null) {
serviceVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
} else {
isAppointmentAvailable = branchModel?.serviceProviderService?.isAllowAppointment ?? false;
// isHomeAppointmentAvailable=branchModel.serviceProviderService.
serviceRage = branchModel?.serviceProviderService?.customerLocationRange ?? 0;
if (serviceRage > 0) {
isHomeAppointmentAvailable = true;
}
chargersPerKm = branchModel?.serviceProviderService?.rangePricePerKm ?? "0";
serviceId = branchModel?.serviceProviderService?.serviceId ?? -1;
}
return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer<ServiceVM>(
builder: (context, model, _) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text(
branchModel!.branchName ?? "N/A",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
).toContainer(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
backgroundColor: MyColors.textFieldColor,
borderRadius: 0,
width: double.infinity,
),
12.height,
(branchModel!.categoryId != null)
? Text(
branchModel!.categoryName ?? "N/A",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
).toContainer(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
backgroundColor: MyColors.textFieldColor,
borderRadius: 0,
width: double.infinity,
)
: (branchModel!.categoryId == null && model.categoryDropList.isNotEmpty)
? DropdownField(
(DropValue value) async {
categoryId = value.id;
serviceId = -1;
isAppointmentAvailable = false;
isHomeAppointmentAvailable = false;
model.fetchServicesByCategoryId(value.id.toString());
},
list: model.categoryDropList,
hint: LocaleKeys.selectServiceCategory.tr(),
)
: const CircularProgressIndicator(),
12.height,
branchModel!.serviceProviderService != null
? Text(
branchModel!.serviceProviderService!.serviceName ?? "N/A",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
).toContainer(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
backgroundColor: MyColors.textFieldColor,
borderRadius: 0,
width: double.infinity,
)
: model.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
serviceId = value.id;
isAppointmentAvailable = false;
isHomeAppointmentAvailable = false;
model.setState(ViewState.idle);
},
list: model.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: categoryId == null
? Container()
: const CircularProgressIndicator(),
12.height,
if (serviceId != -1)
Column(
children: [
20.height,
CheckBoxWithTitleDescription(
isSelected: isAppointmentAvailable,
title: 'Available for appointment',
description: 'This option will allow customer to book appointment for these services',
onSelection: (bool v) {
isAppointmentAvailable = v;
model.setState(ViewState.idle);
},
),
20.height,
CheckBoxWithTitleDescription(
isSelected: isHomeAppointmentAvailable,
title: 'Allow home services',
description: 'This option will allow customer to book appointment at their desired location',
onSelection: (bool v) {
isHomeAppointmentAvailable = v;
model.setState(ViewState.idle);
},
),
20.height,
if (isHomeAppointmentAvailable)
Column(
children: [
TxtField(
hint: "Home Services Range",
keyboardType: TextInputType.number,
value: serviceRage == 0 ? null : serviceRage.toString(),
postfixWidget: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
"KM".toText(color: MyColors.lightTextColor),
],
),
onChanged: (v) {
if (v.isNotEmpty) {
serviceRage = int.parse(v);
} else {
serviceRage = 0;
}
},
),
12.height,
TxtField(
hint: "Charges per Kilometer",
keyboardType: TextInputType.number,
value: chargersPerKm == "0.0" ? null : chargersPerKm,
onChanged: (v) {
if (v.isNotEmpty) {
chargersPerKm = v;
} else {
chargersPerKm = "0";
}
},
),
],
),
],
),
],
),
),
),
),
if (serviceId != -1)
ShowFillButton(
title: LocaleKeys.save.tr(),
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
if (branchModel!.serviceProviderService != null) {
updateService(context, model);
} else {
if (model.services != null) {
createService(context, model);
}
}
},
),
],
);
},
),
),
);
}
createService(BuildContext context, ServiceVM model) async {
List<Map<String, dynamic>> map = [];
model.services!.data?.forEach((element) {
if (serviceId == element.id) {
element.isSelected = true;
} else {
element.isSelected = false;
}
});
for (int i = 0; i < model.services!.data!.length; i++) {
if (model.services!.data![i].isSelected ?? false) {
var postParams = {
// "id": services!.data![i].id,
"providerBranchID": branchModel!.branchId,
"serviceID": model.services!.data![i].id,
"isAllowAppointment": isAppointmentAvailable,
"isActive": true,
"customerLocationRange": serviceRage,
"rangePricePerKm": chargersPerKm
};
map.add(postParams);
}
}
// print(map);
Utils.showLoading(context);
MResponse mResponse = await model.createService(map);
model.getBranchAndServices();
Utils.hideLoading(context);
Utils.showToast(mResponse.message ?? "");
}
updateService(BuildContext context, ServiceVM model) async {
List<Map<String, dynamic>> map = [
{
"id": branchModel!.serviceProviderService!.serviceId.toString(),
"isAllowAppointment": isAppointmentAvailable,
"isActive": true,
"customerLocationRange": serviceRage,
"rangePricePerKm": chargersPerKm
}
];
// print(map);
Utils.showLoading(context);
MResponse mResponse = await model.updateServices(map);
model.getBranchAndServices();
Utils.hideLoading(context);
Utils.showToast(mResponse.message ?? "");
}
}

@ -0,0 +1,136 @@
import 'package:car_provider_app/common/item_model.dart';
import 'package:car_provider_app/common/widget/empty_widget.dart';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/view_models/items_view_model.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/model/branch2.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/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:flutter_svg/svg.dart';
class ItemsListPage extends StatelessWidget {
ServiceProviderService? serviceProviderService;
ItemsListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
serviceProviderService ??= ModalRoute.of(context)!.settings.arguments as ServiceProviderService;
context.read<ItemsVM>().getServiceItems(serviceProviderService!.serviceId ?? 0);
return Scaffold(
appBar: CustomAppBar(
title: serviceProviderService!.serviceName,
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: Consumer<ItemsVM>(
builder: (context, model, _) {
return model.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: model.serviceItems!.data!.isEmpty
? const EmptyWidget()
: ListView.separated(
itemBuilder: (BuildContext context, int 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: [
model.serviceItems!.data![index].name.toString().toText(fontSize: 16, isBold: true),
4.height,
showItem("Available for appointment:", (model.serviceItems!.data![index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Allowing Workshop service:", (model.serviceItems!.data![index].isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Allowing home service:", (model.serviceItems!.data![index].isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
12.height,
"Service Amount".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
model.serviceItems!.data![index].price!.toText(fontSize: 22, isBold: true),
2.width,
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
MyAssets.icEdit,
width: 16,
height: 16,
),
).onPress(() {
model.serviceItems!.data![index].isUpdate = true;
navigateWithName(context, ProviderAppRoutes.createItem, arguments: model.serviceItems!.data![index]);
}),
],
),
).toWhiteContainer(
width: double.infinity,
allPading: 12,
);
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
padding: const EdgeInsets.all(20),
itemCount: model.serviceItems!.data!.length,
);
},
),
),
ShowFillButton(
title: "Add Item",
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
navigateWithName(
context,
ProviderAppRoutes.createItem,
arguments: ItemData(
serviceProviderServiceId: serviceProviderService!.serviceId,
),
);
},
),
],
),
),
);
}
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),
],
);
}
}

@ -0,0 +1,176 @@
import 'package:car_provider_app/common/widget/empty_widget.dart';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/model/branch2.dart';
import 'package:mc_common_app/models/profile/categroy.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/widgets/common_widgets/app_bar.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/tab/menu_tabs.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
class CreateBranchModel {
String branchId;
String branchName;
String? categoryId;
String? categoryName;
ServiceProviderService? serviceProviderService;
CreateBranchModel({required this.branchId, required this.branchName, this.categoryId, this.categoryName, this.serviceProviderService});
}
class ServicesListPage extends StatefulWidget {
const ServicesListPage({Key? key}) : super(key: key);
@override
State<ServicesListPage> createState() => _ServicesListPageState();
}
class _ServicesListPageState extends State<ServicesListPage> {
int selectedTap = 0;
int selectedService = ServiceStatus.approvedOrActive.index;
@override
Widget build(BuildContext context) {
CategoryData categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData;
List<ServiceProviderService>? services = [];
if (selectedService == ServiceStatus.approvedOrActive.index) {
services = categoryData.services!.where((i) => i.serviceStatus == selectedService + 1).toList();
} else {
services = categoryData.services!.where((i) => i.serviceStatus != selectedService + 1).toList();
}
return Scaffold(
appBar: const CustomAppBar(
title: "Services",
),
body: SizedBox(
width: double.infinity,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 20),
child: RoleTypeTab(
selectedTap,
[
DropValue(0, "Active", ""),
DropValue(1, "Requested", ""),
],
width: (MediaQuery.of(context).size.width / 2) - 26,
onSelect: (DropValue value) {
setState(() {
selectedTap = value.id;
if (selectedTap == 0) {
selectedService = ServiceStatus.approvedOrActive.index;
} else {
selectedService = 1;
}
});
},
),
),
10.height,
Expanded(
child: services.isEmpty
? const EmptyWidget()
: ListView.separated(
itemBuilder: (context, index) {
return SizedBox(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: services![index].serviceName.toString().toText(fontSize: 16, isBold: true)),
Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
MyAssets.icEdit,
width: 16,
height: 16,
),
).onPress(() {
navigateWithName(
context,
ProviderAppRoutes.createServices3,
arguments: CreateBranchModel(
branchId: categoryData.branchId ?? "",
branchName: categoryData.branchName ?? "",
categoryId: categoryData.id.toString(),
categoryName: categoryData.categoryName,
serviceProviderService: services![index],
),
);
}),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
4.height,
showItem("Available for appointment:", "Yes", valueColor: Colors.green),
showItem("Allowing home service:", (services[index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Home service range:", services[index].customerLocationRange.toString()),
showItem("Charges per KM:", services[index].rangePricePerKm.toString()),
],
),
),
const Icon(
Icons.arrow_forward_rounded,
size: 16,
),
],
),
],
),
)
.toWhiteContainer(
width: double.infinity,
allPading: 12,
)
.onPress(
() {
navigateWithName(context, ProviderAppRoutes.itemsList, arguments: services![index]);
},
);
},
separatorBuilder: (context, index) {
return 12.height;
},
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
itemCount: services.length,
),
),
],
),
),
);
}
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),
],
);
}
}

@ -1,14 +1,21 @@
import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/tab/menu_tabs.dart';
import 'package:provider/provider.dart';
class MySubscriptionsPage extends StatelessWidget {
const MySubscriptionsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
context.read<SubscriptionsVM>().getMySubscriptions(AppState().getUser.data?.userInfo?.providerId.toString() ?? "");
return Scaffold(
appBar: const CustomAppBar(
title: "My Subscriptions",
@ -16,15 +23,33 @@ class MySubscriptionsPage extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
21.height,
SubscriptionsCard(
isSubscribed: true,
backgroundColor: MyColors.darkIconColor,
),
],
),
child: Consumer<SubscriptionsVM>(builder: (context, model, _) {
return model.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
21.height,
ListView.separated(
itemBuilder: (BuildContext context, int index) {
return SubscriptionsCard(
model.allSubscriptions.data![index],
isSubscribed: model.allSubscriptions.data![index].isSubscribed ?? false,
backgroundColor: MyColors.darkIconColor,
);
},
separatorBuilder: (BuildContext context, int index) {
return 21.height;
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: model.allSubscriptions.data!.length,
),
21.height,
],
),
);
}),
),
);
}

@ -1,16 +1,21 @@
import 'package:car_provider_app/view_models/subscriptions_view_model.dart';
import 'package:car_provider_app/views/subscriptions/widget/subscriptions_card.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/tab/menu_tabs.dart';
import 'package:provider/provider.dart';
class SubscriptionsPage extends StatelessWidget {
const SubscriptionsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
context.read<SubscriptionsVM>().getAllAvailableSubscriptions(null);
return Scaffold(
appBar: const CustomAppBar(
title: "Subscriptions",
@ -18,27 +23,44 @@ class SubscriptionsPage extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
21.height,
MenuTabs(
0,
[
DropValue(0, "1 Month", ""),
DropValue(1, "2 Month", ""),
DropValue(2, "3 Month", ""),
],
selectedColor: MyColors.primaryColor,
onSelect: (DropValue selectedValue) {},
),
21.height,
SubscriptionsCard(
isSubscribed: true,
),
21.height,
SubscriptionsCard()
],
),
child: Consumer<SubscriptionsVM>(builder: (context, model, _) {
return model.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
21.height,
MenuTabs(
model.selectedIndex,
model.monthlyTabs,
selectedColor: MyColors.primaryColor,
onSelect: (DropValue selectedValue) {
model.selectedMothlyTab = selectedValue;
// model.selectedIndex = selectedIndex;
model.filterSubscriptions();
model.setState(ViewState.idle);
},
),
21.height,
ListView.separated(
itemBuilder: (BuildContext context, int index) {
return SubscriptionsCard(
model.tempSubscriptions[index],
isSubscribed: model.tempSubscriptions[index].isSubscribed ?? false,
);
},
separatorBuilder: (BuildContext context, int index) {
return 21.height;
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: model.tempSubscriptions.length,
),
21.height,
],
),
);
}),
),
);
}

@ -1,16 +1,19 @@
import 'package:car_provider_app/common/subscription_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/utils/date_helper.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class SubscriptionsCard extends StatelessWidget {
Subscription subscription;
bool isSubscribed;
Color? backgroundColor;
late Color textColor;
SubscriptionsCard({Key? key, this.isSubscribed = false, this.backgroundColor}) : super(key: key);
SubscriptionsCard(this.subscription, {Key? key, this.isSubscribed = false, this.backgroundColor}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -21,10 +24,10 @@ class SubscriptionsCard extends StatelessWidget {
Row(
children: [
Expanded(
child: "Silver Plan".toText(
fontSize: 18,
color: textColor,
),
child: subscription.name.toString().toText(
fontSize: 18,
color: textColor,
),
),
if (isSubscribed)
Row(
@ -54,9 +57,9 @@ class SubscriptionsCard extends StatelessWidget {
],
),
6.height,
showItem("Ads:", "10"),
showItem("Users:", "20"),
showItem("Branches:", "5"),
showItem("Ads:", subscription.numberOfAds.toString()),
showItem("Users:", subscription.numberOfSubUsers.toString()),
showItem("Branches:", subscription.numberOfBranches.toString()),
14.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
@ -67,13 +70,13 @@ class SubscriptionsCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(
fontSize: 26,
isBold: true,
color: textColor,
),
subscription.price.toString().toText(
fontSize: 26,
isBold: true,
color: textColor,
),
2.width,
"SAR/Month".toText(
"${subscription.currency}/Month".toText(
color: MyColors.lightTextColor,
fontSize: 16,
),
@ -88,9 +91,10 @@ class SubscriptionsCard extends StatelessWidget {
color: textColor,
),
4.width,
const Icon(
Icon(
Icons.arrow_forward,
size: 16,
color: textColor,
)
],
)
@ -99,7 +103,7 @@ class SubscriptionsCard extends StatelessWidget {
if (isSubscribed)
Row(
children: [
"Expires on 3 Mar, 2023".toText(
"Expires on ${DateHelper.formatAsDayMonthYear(subscription.dateEnd)}".toText(
fontSize: 14,
color: textColor,
),

@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: async
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.11.0"
auto_size_text:
dependency: transitive
description:
@ -77,10 +77,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.0"
clock:
dependency: transitive
description:
@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted
version: "1.17.0"
version: "1.17.1"
cross_file:
dependency: transitive
description:
@ -121,14 +121,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
dropdown_button2:
dependency: transitive
description:
name: dropdown_button2
sha256: "193e97bfe9fd3d89317bddb6129653781fa9b62d99811d49f633e67ea449a62c"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
easy_localization:
dependency: transitive
description:
name: easy_localization
sha256: "6a2e99fa0bfe5765bf4c6ca9b137d5de2c75593007178c5e4cd2ae985f870080"
sha256: f30e9b20ed4d1b890171c30241d9b9c43efe21fee55dee7bd68f94daf269ea75
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2-dev.2"
easy_logger:
dependency: transitive
description:
@ -433,18 +441,18 @@ packages:
dependency: transitive
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
url: "https://pub.dev"
source: hosted
version: "0.17.0"
version: "0.18.0"
js:
dependency: transitive
description:
name: js
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.5"
version: "0.6.7"
lints:
dependency: transitive
description:
@ -457,10 +465,42 @@ packages:
dependency: transitive
description:
name: local_auth
sha256: d3fece0749101725b03206f84a7dab7aaafb702dbbd09131ff8d8173259a9b19
sha256: "0cf238be2bfa51a6c9e7e9cfc11c05ea39f2a3a4d3e5bb255d0ebc917da24401"
url: "https://pub.dev"
source: hosted
version: "2.1.6"
local_auth_android:
dependency: transitive
description:
name: local_auth_android
sha256: c5e48c4a67fc0e5dd9b5725cc8766b67e2da9a54155c82c6e2ea4a0d1cf9ef93
url: "https://pub.dev"
source: hosted
version: "1.1.11"
version: "1.0.28"
local_auth_ios:
dependency: transitive
description:
name: local_auth_ios
sha256: "503a938c4edde6b244c6ee3b1e2e675ddb7e37e79d5056658dbed1997cf04785"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
local_auth_platform_interface:
dependency: transitive
description:
name: local_auth_platform_interface
sha256: "9e160d59ef0743e35f1b50f4fb84dc64f55676b1b8071e319ef35e7f3bc13367"
url: "https://pub.dev"
source: hosted
version: "1.0.7"
local_auth_windows:
dependency: transitive
description:
name: local_auth_windows
sha256: "19323b75ab781d5362dbb15dcb7e0916d2431c7a6dbdda016ec9708689877f73"
url: "https://pub.dev"
source: hosted
version: "1.0.8"
logger:
dependency: transitive
description:
@ -473,10 +513,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted
version: "0.12.13"
version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
@ -496,10 +536,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.8.0"
version: "1.9.1"
nested:
dependency: transitive
description:
@ -520,10 +560,10 @@ packages:
dependency: transitive
description:
name: path
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.8.3"
path_drawing:
dependency: transitive
description:
@ -837,10 +877,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
source: hosted
version: "0.4.16"
version: "0.5.1"
typed_data:
dependency: transitive
description:
@ -962,5 +1002,5 @@ packages:
source: hosted
version: "6.2.2"
sdks:
dart: ">=2.18.0 <3.0.0"
dart: ">=3.0.0-0 <4.0.0"
flutter: ">=3.3.0"

Loading…
Cancel
Save