Compare commits

...

3 Commits

Author SHA1 Message Date
Mirza.Shafique@cloudsolutions.com.sa e4e1b0a3c4 Appointment Implementation 1.1 10 months ago
Mirza.Shafique@cloudsolutions.com.sa b437bf4c91 Appointment Implementation 10 months ago
Mirza.Shafique@cloudsolutions.com.sa ef7b24781e gradle fix 11 months ago

@ -6,7 +6,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -0,0 +1,14 @@
## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Wed Dec 13 16:00:22 AST 2023
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"

@ -0,0 +1,44 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

@ -1,4 +1,5 @@
import 'package:car_provider_app/views/appoinments/appoinment_detail_list_page.dart';
import 'package:car_provider_app/views/appoinments/merge_appointment_page.dart';
import 'package:car_provider_app/views/appoinments/update_appointment_page.dart';
import 'package:car_provider_app/views/requests/request_detail_page.dart';
import 'package:car_provider_app/views/requests/send_offer_page.dart';
@ -24,11 +25,14 @@ import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import '../views/appoinments/add_new_service_appointment_page.dart';
import '../views/appoinments/appointment_page.dart';
import '../views/dashboard/dashboard_page.dart';
class ProviderAppRoutes {
@ -40,8 +44,11 @@ class ProviderAppRoutes {
static const String defineBranch = "/defineBranch";
//Appointments
static const String appointment = "/appointment";
static const String appointmentDetailList = "/appointmentDetailList";
static const String updateAppointmentPage = "/updateAppointmentPage";
static const String addServiceInAppointment = "/addServiceInAppointment";
static const String mergeAppointments = "/mergeAppointments";
//Requests
static const String requestsDetailPage = "/requestsDetailPage";
@ -84,8 +91,14 @@ class ProviderAppRoutes {
ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
//Appointments
appointmentDetailList: (context) => const AppointmentDetailListPage(),
updateAppointmentPage: (context) => const UpdateAppointmentPage(),
appointment: (context) => AppointmentPage(
branch:
ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
appointmentDetailList: (context) => AppointmentDetailListPage(),
updateAppointmentPage: (context) => UpdateAppointmentPage(),
addServiceInAppointment: (context) => AddNewServiceAppointmentPage(
ModalRoute.of(context)!.settings.arguments as AppointmentListModel),
mergeAppointments: (context) => MergeAppointmentListPage(),
//Requests
requestsDetailPage: (context) => const RequestDetailPage(),

@ -17,13 +17,16 @@ import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/general_models/post_params_model.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart';
import 'package:mc_common_app/repositories/request_repo.dart';
import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/theme/app_theme.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
@ -68,7 +71,8 @@ Future<void> main() async {
),
),
ChangeNotifierProvider<SubscriptionsVM>(
create: (_) => SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
create: (_) =>
SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
),
ChangeNotifierProvider<ItemsVM>(
create: (_) => ItemsVM(
@ -95,6 +99,14 @@ Future<void> main() async {
// requestRepo: injector.get<RequestRepo>(),
// ),
// ),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
scheduleRepo: injector.get<AppointmentRepo>(),
providerRepo: injector.get<ProviderRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
],
child: const MyApp(),
).setupLocale());
@ -116,12 +128,19 @@ class MyApp extends StatelessWidget {
injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel(
PostParamsModel(
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
languageID:
EasyLocalization.of(context)?.locale.languageCode == "ar"
? 1
: 2,
),
);
ThemeData data = AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar");
ThemeData data = AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar");
return MaterialApp(
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
theme: AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,

@ -10,8 +10,6 @@ import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/branch.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
@ -20,9 +18,18 @@ import 'package:mc_common_app/models/provider_branches_models/profile/services.d
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
abstract class BranchRepo {
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude);
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true});
Future<MResponse> createBranch(String branchName, String branchDescription,
String cityId, String address, String latitude, String longitude);
Future<MResponse> updateBranch(
int id,
String branchName,
String branchDescription,
String cityId,
String address,
String latitude,
String longitude,
{bool isNeedToDelete = true});
Future<Branch> fetchAllBranches();
@ -30,11 +37,14 @@ abstract class BranchRepo {
Future<Services> fetchServicesByCategoryId(String serviceCategoryId);
Future<Services> fetchProviderServices(String branchID, String serviceCategoryId);
Future<MResponse> createNewService(List<Map<String, dynamic>> map);
Future<Document> getServiceProviderDocument(dynamic userId);
Future<MResponse> serviceProviderDocumentsUpdate(List<DocumentData>? documents);
Future<MResponse> serviceProviderDocumentsUpdate(
List<DocumentData>? documents);
Future<ProviderModel> getBranchAndServices();
@ -42,7 +52,8 @@ abstract class BranchRepo {
Future<MResponse> updateService(List<Map<String, dynamic>> map);
Future<MResponse> getMatchedServices(int oldBranchId, int newBranchId, int categoryId);
Future<MResponse> getMatchedServices(
int oldBranchId, int newBranchId, int categoryId);
Future<MResponse> duplicateItems(Map<String, dynamic> map);
@ -53,11 +64,14 @@ abstract class BranchRepo {
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map);
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map);
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map);
}
class BranchRepoImp implements BranchRepo {
@override
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
Future<MResponse> createBranch(String branchName, String branchDescription,
String cityId, String address, String latitude, String longitude) async {
var postParams = {
"serviceProviderID": AppState().getUser.data?.userInfo?.providerId ?? "",
"branchName": branchName,
@ -70,23 +84,37 @@ class BranchRepoImp implements BranchRepo {
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createProviderBranch, postParams, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.createProviderBranch,
postParams,
token: t);
}
@override
Future<Branch> fetchAllBranches() async {
var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
var postParams = {
"ServiceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet, queryParameters: postParams, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet,
queryParameters: postParams, token: t);
}
@override
Future<Category> fetchBranchCategory() async {
var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
var postParams = {
"ServiceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get, queryParameters: postParams, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get,
queryParameters: postParams, token: t);
}
@override
@ -94,13 +122,19 @@ class BranchRepoImp implements BranchRepo {
var postParams = {"ServiceCategoryID": serviceCategoryId};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, queryParameters: postParams, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Services.fromJson(json), ApiConsts.Services_Get,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> createNewService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Create,
map,
token: t);
}
@override
@ -110,13 +144,15 @@ class BranchRepoImp implements BranchRepo {
};
String? token = AppState().getUser.data?.accessToken;
debugPrint(token);
return await injector
.get<ApiClient>()
.getJsonForObject((json) => Document.fromJson(json), ApiConsts.GetProviderDocument, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? "");
return await injector.get<ApiClient>().getJsonForObject(
(json) => Document.fromJson(json), ApiConsts.GetProviderDocument,
queryParameters: queryParameters,
token: AppState().getUser.data!.accessToken ?? "");
}
@override
Future<MResponse> serviceProviderDocumentsUpdate(List<DocumentData>? documents) async {
Future<MResponse> serviceProviderDocumentsUpdate(
List<DocumentData>? documents) async {
List<Map<String, dynamic>> map = [];
for (int i = 0; i < documents!.length; i++) {
if (documents[i].document != null) {
@ -133,19 +169,36 @@ class BranchRepoImp implements BranchRepo {
}
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderDocument_Update, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderDocument_Update,
map,
token: t);
}
@override
Future<ProviderModel> getBranchAndServices() async {
var postParams = {"serviceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
var postParams = {
"serviceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
print("tokeen121 " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => ProviderModel.fromJson(json), ApiConsts.BranchesAndServices, queryParameters: postParams, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => ProviderModel.fromJson(json), ApiConsts.BranchesAndServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
Future<MResponse> updateBranch(
int id,
String branchName,
String branchDescription,
String cityId,
String address,
String latitude,
String longitude,
{bool isNeedToDelete = true}) async {
String lat = "0", long = "0";
try {
lat = latitude.substring(0, 9);
@ -163,59 +216,109 @@ class BranchRepoImp implements BranchRepo {
"isActive": isNeedToDelete
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateProviderBranch, postParams, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.updateProviderBranch,
postParams,
token: t);
}
@override
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Create,
map,
token: t);
}
@override
Future<MResponse> updateService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Update, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Update,
map,
token: t);
}
@override
Future<MResponse> getMatchedServices(int oldBranchId, int newBranchId, int categoryId) async {
Future<MResponse> getMatchedServices(
int oldBranchId, int newBranchId, int categoryId) async {
var postParams = {
"ProviderBranchIDExisted": oldBranchId.toString(),
"ProviderBranchIDNew": newBranchId.toString(),
"CategoryID": categoryId.toString(),
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getMatchedServices, queryParameters: postParams, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getMatchedServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.duplicateItems, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.duplicateItems, map,
token: t);
}
@override
Future<MResponse> getAllProviderDealers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getAllProviderDealers, queryParameters: map, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getAllProviderDealers,
queryParameters: map, token: t);
}
@override
Future<MResponse> getBranchUsers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getBranchUser, queryParameters: map, token: t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getBranchUser,
queryParameters: map, token: t);
}
@override
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.assignDealerToBranch, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.assignDealerToBranch, map,
token: t);
}
@override
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.removeDealerFromBranch, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.removeDealerFromBranch,
map,
token: t);
}
@override
Future<Services> fetchProviderServices(String branchID, String serviceCategoryId) async {
var postParams = {
"ServiceCategoryID": serviceCategoryId,
"ProviderBranchID": branchID,
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Services.fromJson(json), ApiConsts.GetProviderServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.AddNewServicesInAppointment,
map,
token: t);
}
}

@ -9,6 +9,8 @@ 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';
import '../views/settings/schedule/widgets/chips_picker_item.dart';
class ItemsVM extends BaseVM {
final ItemsRepo itemsRepo;
final CommonAppServices commonServices;
@ -40,9 +42,25 @@ class ItemsVM extends BaseVM {
return response;
}
Future<ItemModel?> getServiceItems(int serviceId) async {
Future<ItemModel?> getServiceItems(int serviceId,
{List<PickerItem>? list}) async {
serviceItems = null;
setOnlyState(ViewState.busy);
serviceItems = await itemsRepo.getServiceItems(serviceId);
if (list != null) {
for (var element in list) {
for (var innerElement in serviceItems!.data!) {
if (element.id == innerElement.id) {
innerElement.isUpdateOrSelected = true;
}
}
// serviceItems!.data!.where(
// (innerElement) => element.id == innerElement.id
// ? innerElement.isUpdateOrSelected = true
// : innerElement.isUpdateOrSelected = true,
// );
}
}
setState(ViewState.idle);
return serviceItems;
}

@ -260,7 +260,6 @@ 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';
class ServiceVM extends BaseVM {
final BranchRepo branchRepo;
final CommonAppServices commonServices;
@ -347,7 +346,8 @@ class ServiceVM extends BaseVM {
setState(ViewState.idle);
}
Future<void> getAllCountriesList(BranchDetailModel? branchData, String countryCode) async {
Future<void> getAllCountriesList(
BranchDetailModel? branchData, String countryCode) async {
setState(ViewState.busy);
resetValues();
country = await commonRepo.getAllCountries();
@ -356,7 +356,9 @@ class ServiceVM extends BaseVM {
if (element.id == branchData.countryID) {
countryValue = DropValue(
element.id ?? 0,
countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""),
countryCode == "SA"
? (element.countryNameN ?? "")
: (element.countryName ?? ""),
element.countryCode ?? "",
);
}
@ -364,7 +366,9 @@ class ServiceVM extends BaseVM {
countryDropList.add(
DropValue(
element.id ?? 0,
countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""),
countryCode == "SA"
? (element.countryNameN ?? "")
: (element.countryName ?? ""),
element.countryCode ?? "",
),
);
@ -375,7 +379,8 @@ class ServiceVM extends BaseVM {
setState(ViewState.idle);
}
Future<void> getAllCities(BranchDetailModel? branchData, String countryCode) async {
Future<void> getAllCities(
BranchDetailModel? branchData, String countryCode) async {
setState(ViewState.busy);
citiesDropList.clear();
cities = null;
@ -393,7 +398,9 @@ class ServiceVM extends BaseVM {
cityId = branchData.cityId!;
cityValue = DropValue(
element.id ?? 0,
countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""),
countryCode == "SA"
? (element.cityNameN ?? "")
: (element.cityName ?? ""),
element.id.toString() ?? "",
);
}
@ -401,7 +408,9 @@ class ServiceVM extends BaseVM {
citiesDropList.add(
DropValue(
element.id ?? 0,
countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""),
countryCode == "SA"
? (element.cityNameN ?? "")
: (element.cityName ?? ""),
element.id.toString() ?? "",
),
);
@ -409,8 +418,10 @@ class ServiceVM extends BaseVM {
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> 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(
@ -498,6 +509,24 @@ class ServiceVM extends BaseVM {
setState(ViewState.idle);
}
Future<void> fetchProviderServices(String branchID, String categoryId) async {
servicesDropList = [];
services=null;
setState(ViewState.busy);
services = await branchRepo.fetchProviderServices(branchID, categoryId);
for (var element in services!.data!) {
servicesDropList.add(
DropValue(
element.id ?? 0,
element.description ?? "N/A",
"",
),
);
}
setState(ViewState.idle);
}
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
return await branchRepo.createService(map);
}
@ -514,13 +543,16 @@ class ServiceVM extends BaseVM {
List<ServiceModel>? matchedServices;
bool isAllSelected = false;
Future<void> getAllMatchedServices(int oldBranchId, int newBranchId, int categoryId) async {
Future<void> getAllMatchedServices(
int oldBranchId, int newBranchId, int categoryId) async {
matchedServices = null;
final MResponse response = await branchRepo.getMatchedServices(oldBranchId, newBranchId, categoryId);
final MResponse response = await branchRepo.getMatchedServices(
oldBranchId, newBranchId, categoryId);
matchedServices = [];
if (response.messageStatus == 1) {
matchedServices = List<ServiceModel>.from(response.data.map((x) => ServiceModel.fromJson(x)));
matchedServices = List<ServiceModel>.from(
response.data.map((x) => ServiceModel.fromJson(x)));
}
notifyListeners();
}
@ -560,8 +592,9 @@ class ServiceVM extends BaseVM {
setState(ViewState.busy);
MResponse response = await branchRepo.getAllProviderDealers(map);
if (response.messageStatus == 1) {
allProviderDealersList=[];
allProviderDealersList = List<BranchUser>.from(response.data.map((x) => BranchUser.fromJson(x)));
allProviderDealersList = [];
allProviderDealersList = List<BranchUser>.from(
response.data.map((x) => BranchUser.fromJson(x)));
}
setState(ViewState.idle);
}
@ -570,8 +603,9 @@ class ServiceVM extends BaseVM {
setState(ViewState.busy);
MResponse response = await branchRepo.getBranchUsers(map);
if (response.messageStatus == 1) {
branchUserList=[];
branchUserList = List<BranchUser>.from(response.data.map((x) => BranchUser.fromJson(x)));
branchUserList = [];
branchUserList = List<BranchUser>.from(
response.data.map((x) => BranchUser.fromJson(x)));
}
setState(ViewState.idle);
}
@ -585,4 +619,9 @@ class ServiceVM extends BaseVM {
MResponse response = await branchRepo.removeDealerFromBranch(map);
return response;
}
Future<MResponse> addNewServiceInAppointment(Map<String, dynamic> map) async {
MResponse response = await branchRepo.addNewServicesInAppointment(map);
return response;
}
}

@ -0,0 +1,286 @@
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/appoinments/widget/select_items_sheet.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.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/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/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';
import 'package:easy_localization/easy_localization.dart';
import '../../generated/locale_keys.g.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import '../settings/schedule/widgets/chips_picker_item.dart';
class AddNewServiceAppointmentPage extends StatelessWidget {
AppointmentListModel appointmentListModel;
AddNewServiceAppointmentPage(this.appointmentListModel, {Key? key})
: super(key: key);
DropValue? category;
DropValue? service;
List<ItemData> selectedList = [];
List<PickerItem>? pickedItems;
@override
Widget build(BuildContext context) {
ServiceVM serviceVM = context.read<ServiceVM>();
serviceVM.fetchBranchCategory(
EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
return Scaffold(
appBar: const CustomAppBar(
title: "Add Service",
),
body: Padding(
padding: const EdgeInsets.all(21.0),
child: Column(
children: [
AppointmentSliderWidget(
appointmentListModel: appointmentListModel,
isNeedTotalPayment: true,
isNeedToShowItems: true,
isNeedToShowToMoreText: false,
onTap: () {},
),
12.height,
Expanded(
child: Consumer<ServiceVM>(
builder: (context, model, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Select services you want to add".toText(
fontSize: 18,
isBold: true,
),
12.height,
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
model.categoryDropList.isNotEmpty
? DropdownField(
(DropValue value) async {
category = value;
service = null;
model.fetchProviderServices(
appointmentListModel.branchId
.toString(),
value.id.toString());
},
dropdownValue: category,
list: model.categoryDropList,
hint:
LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
model.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
model.setState(ViewState.idle);
showMyBottomSheet(
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
onSelectItems:
(List<ItemData> selectedList) {
this.selectedList.clear();
this.selectedList = selectedList;
pickedItems = [];
for (var element
in selectedList) {
pickedItems!.add(
PickerItem(
id: element.id ?? 0,
title:
element.name ?? ""),
);
}
model.notifyListeners();
},
),
);
},
dropdownValue: service,
list: model.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: model.services != null &&
model.servicesDropList.isEmpty
? const Text("No Service Found")
: const CircularProgressIndicator(),
12.height,
(service != null &&
pickedItems != null &&
pickedItems!.length > 0)
? ChipsPickerItem(
hint: 'Select Items',
itemsList: [...pickedItems ?? []],
onClick: () {
showMyBottomSheet(
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
list: pickedItems,
onSelectItems:
(List<ItemData> selectedList) {
pickedItems = [];
for (var element
in selectedList) {
pickedItems!.add(
PickerItem(
id: element.id ?? 0,
title:
element.name ?? ""),
);
}
model.notifyListeners();
},
),
);
},
)
: service != null
? const Text("No Item Selected Yet")
: const SizedBox(),
if ((service != null &&
pickedItems != null &&
pickedItems!.length > 0))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
"Total Additional Amount".toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
calculatePrice().toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
"SAR".toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
),
],
),
],
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
Row(
children: [
Expanded(
child: ShowFillButton(
title: "Cancel",
maxWidth: double.infinity,
isFilled: false,
txtColor: MyColors.redColor,
borderColor: MyColors.redColor,
onPressed: () {},
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "Add",
maxWidth: double.infinity,
onPressed: () async {
if (pickedItems != null &&
pickedItems!.length > 0) {
List<int> items = [];
pickedItems?.forEach((element) {
items.add(element.id);
});
Utils.showLoading(context);
var postParams = {
"providerBranchID":
appointmentListModel.branchId,
"appointmentID": appointmentListModel.id,
"serviceItemID": items
};
MResponse res = await serviceVM
.addNewServiceInAppointment(postParams);
_updateAppointment(context,
appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast(
"Items are added Successfully");
pop(context);
} else {
Utils.showToast(res.message.toString());
}
} else {
Utils.showToast("Please select items");
}
},
),
),
],
),
],
);
},
),
),
],
),
),
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
double calculatePrice() {
double total = 0;
for (var element in selectedList) {
total = total + double.parse(element.price ?? "0");
}
return total;
}
}

@ -1,11 +1,18 @@
import 'package:car_provider_app/views/appoinments/widget/appointment_detail_list_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import '../../config/provider_routes.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import 'package:provider/provider.dart';
class AppointmentDetailListPage extends StatelessWidget {
const AppointmentDetailListPage({Key? key}) : super(key: key);
AppointmentDetailListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -19,20 +26,60 @@ class AppointmentDetailListPage extends StatelessWidget {
child: Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(21),
children: [
AppointmentDetailListWidget(),
21.height,
AppointmentDetailListWidget(),
],
),
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![index],
isNeedTotalPayment: true,
isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: true,
onTap: () {
appointmentsVM.selectedAppointmentId =
appointmentsVM
.myFilteredAppointments2[appointmentsVM
.selectedAppointmentIndex]
.customerAppointmentList![index]
.id ??
0;
appointmentsVM.selectedAppointmentSubIndex = index;
navigateWithName(context,
ProviderAppRoutes.updateAppointmentPage,
arguments: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![index]);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!
.length,
padding: const EdgeInsets.all(21),
);
}
}),
),
ShowFillButton(
title: "Merge Appointments",
maxWidth: double.infinity,
margin: const EdgeInsets.all(21),
onPressed: () {},
onPressed: () {
navigateWithName(
context, ProviderAppRoutes.mergeAppointments);
},
),
],
)),

@ -0,0 +1,273 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/appointment_slider_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.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/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.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/widgets/common_widgets/app_bar.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:provider/provider.dart';
class AppointmentPage extends StatelessWidget {
BranchDetailModel branch;
String date = "";
AppointmentPage({
required this.branch,
Key? key,
}) : super(key: key);
GlobalKey<RefreshIndicatorState> refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async {
await context.read<AppointmentsVM>().getAppointmentSlotsInfo(
context: context,
map: {
"ProviderBranchID": branch.id.toString(),
"FromDate": date,
"ToDate": date
},
isNeedToRebuild: true,
);
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branch.id.toString(),
"FromDate": date,
"DateTo": date,
});
}
@override
Widget build(BuildContext context) {
date = DateHelper.formatAsYearMonthDay(DateTime.now());
context.read<AppointmentsVM>().setupProviderAppointmentFilter();
_pullRefresh(context);
context.read<AppointmentsVM>().selectedBranch = branch.id ?? 0;
return Scaffold(
appBar: CustomAppBar(
profileImageUrl: MyAssets.carBanner,
title: branch.branchName,
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
progressWidget(context, appointmentsVM),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(
appointmentStatusEnum:
selectedFilterId.toAppointmentStatusEnum(),
isNeedCustomerFilter: true,
);
},
),
if (appointmentsVM.myFilteredAppointments2.isEmpty)
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: "No Appointment Found".toText(),
),
ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel:
appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
context
.read<AppointmentsVM>()
.selectedAppointmentIndex = index;
navigateWithName(
context,
ProviderAppRoutes.appointmentDetailList,
// arguments: appointmentsVM
// .myFilteredAppointments2[index]
// .customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
],
),
),
);
}
}),
),
);
}
Widget progressWidget(BuildContext context, AppointmentsVM appointmentsVM) {
double percent = (appointmentsVM.appointmentSlots?.occupiedSlots ??
0.0 / (appointmentsVM.appointmentSlots?.totalSlots ?? 0.0))
.toDouble() *
100;
return Column(
children: [
Row(
children: [
Expanded(
child: "Slots Overview".toText(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
date.toText(
fontWeight: FontWeight.bold,
),
const Icon(
Icons.keyboard_arrow_down_outlined,
size: 16,
),
],
)
.toContainer(
backgroundColor: MyColors.lightGreyEAColor,
borderRadius: 100,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
)
.onPress(() async {
date = await Utils.pickDateFromDatePicker(
context,
firstDate: null,
);
_pullRefresh(context);
// context.read<AppointmentsVM>().notifyListeners();
}),
],
),
24.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.lightGreyEAColor,
),
4.width,
"Empty: ".toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.emptySlots ?? 0)
.toString()
.toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
8.height,
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.darkPrimaryColor,
),
4.width,
"Occupied: ".toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.occupiedSlots ?? 0)
.toString()
.toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
],
),
CircularPercentIndicator(
radius: 60.0,
lineWidth: 12.0,
percent: percent,
circularStrokeCap: CircularStrokeCap.round,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"Total Slots".toText(
fontSize: 13,
fontWeight: FontWeight.bold,
),
(appointmentsVM.appointmentSlots?.totalSlots ?? 0)
.toString()
.toText(
fontSize: 24,
fontWeight: FontWeight.bold,
),
],
),
backgroundColor: MyColors.lightGreyEAColor,
progressColor: MyColors.darkPrimaryColor,
),
],
)
],
).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
margin: const EdgeInsets.all(21),
);
}
}

@ -0,0 +1,159 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/general_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/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import '../../config/provider_routes.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import 'package:provider/provider.dart';
class MergeAppointmentListPage extends StatelessWidget {
MergeAppointmentListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Select Appointments",
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
return Column(
children: [
Expanded(
child: Column(
children: [
Expanded(
child: (appointmentsVM.state == ViewState.busy)
? const Center(child: CircularProgressIndicator())
: ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel: appointmentsVM
.myFilteredAppointments2[appointmentsVM
.selectedAppointmentIndex]
.customerAppointmentList![index],
isNeedTotalPayment: true,
isSelectable: true,
isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: true,
onTap: () {
appointmentsVM
.updateCheckBoxInMergeRequest(index);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!
.length,
padding: const EdgeInsets.all(21),
),
),
],
),
),
ShowFillButton(
title: "Merge Appointments",
maxWidth: double.infinity,
margin: const EdgeInsets.all(21),
txtColor: appointmentsVM.inNeedToEnableMergeButton
? MyColors.white
: MyColors.black,
backgroundColor: appointmentsVM.inNeedToEnableMergeButton
? MyColors.primaryColor
: MyColors.greyButtonColor,
onPressed: () async {
Utils.showLoading(context);
List<int> appointmentIDs = [];
for (var element in appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!) {
if (element.isSelected ?? false) {
appointmentIDs.add(element.id ?? 0);
}
}
Map<String, dynamic> map = {
"serviceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"serviceProviderBranchID": appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.branchId,
"serviceAppointmentIDs": appointmentIDs
};
try {
MResponse response =
await appointmentsVM.createMergeAppointment(map);
Utils.hideLoading(context);
if (response.messageStatus == 1) {
Utils.showToast(
"Appointment Merge is Successfully done");
_updateAppointment(
context,
appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.branchId ??
0);
pop(context);
pop(context);
} else {
Utils.showToast(response.message.toString());
}
} catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context);
}
},
),
],
);
},
),
),
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
}

@ -1,11 +1,27 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/appoinments/widget/appointment_detail_list_widget.dart';
import 'package:car_provider_app/views/appoinments/widget/sheets.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.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/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:provider/provider.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
class UpdateAppointmentPage extends StatelessWidget {
const UpdateAppointmentPage({Key? key}) : super(key: key);
late AppointmentListModel appointmentListModel;
UpdateAppointmentPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -16,42 +32,284 @@ class UpdateAppointmentPage extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(21),
children: [
AppointmentDetailListWidget(
isNeedClick: false,
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
appointmentListModel = appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![
appointmentsVM.selectedAppointmentSubIndex];
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(21),
children: [
AppointmentSliderWidget(
appointmentListModel: appointmentListModel,
isNeedTotalPayment: true,
isNeedToShowItems: true,
isNeedToShowToMoreText: false,
onTap: () {},
),
21.height,
ShowFillButton(
title: "+ Add New Service",
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
onPressed: () {
navigateWithName(
context,
ProviderAppRoutes.addServiceInAppointment,
arguments: appointmentListModel,
);
},
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(21.0),
child: Row(
children: [
Expanded(
child: ShowFillButton(
title: "Cancel",
maxWidth: double.infinity,
onPressed: () {},
),
),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.cancelled)
"Appointment is Canceled".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.booked)
Column(
children: [
showPayNowButton(context, appointmentsVM),
showCancelButton(context, appointmentsVM),
],
),
21.width,
Expanded(
child: ShowFillButton(
title: "Merge Appointments",
maxWidth: double.infinity,
onPressed: () {},
),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.confirmed &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.defaultStatus)
Column(
children: [
showArrivedutton(context, appointmentsVM),
],
),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.defaultStatus)
Column(
children: [
showPayNowButton(context, appointmentsVM),
showPayLaterButton(context, appointmentsVM),
],
),
],
),
),
],
)),
if ((appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived ||
appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted) &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payNow)
"Waiting for the payment from the customer".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived &&
(appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.paid ||
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payLater))
Column(
children: [
showWorkStartButton(context, appointmentsVM),
],
),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payPartial)
Column(
children: [
showPayLaterButton(context, appointmentsVM),
showPayNowButton(context, appointmentsVM),
],
),
// "Show Pay Now".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.paid)
Column(
children: [
showCompleteButton(context, appointmentsVM),
],
),
// "Show Complete Button".toText(),
if(appointmentListModel.appointmentStatusEnum==AppointmentStatusEnum.workStarted&&appointmentListModel.appointmentPaymentStatusEnum==AppointmentPaymentStatusEnum.payLater)
showPayNowButton(context, appointmentsVM),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.visitCompleted)
"Appointment is completed".toText(),
// Padding(
// padding: const EdgeInsets.all(21.0),
// child: Column(
// children: [
// ShowFillButton(
// title: "Confirm Arrive",
// maxWidth: double.infinity,
// onPressed: () {
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
// },
// ),
// 12.height,
// ShowFillButton(
// title: "Cancel Appointment",
// maxWidth: double.infinity,
// isFilled: false,
// txtColor: MyColors.redColor,
// borderColor: MyColors.redColor,
// onPressed: () {
// showMyBottomSheet(context,
// child: CancelAppointmentReasonSheet(
// onCancelClick: (String reason) {},
// ));
// },
// ),
// ],
// ),
// ),
],
);
}
})),
);
}
Widget showWorkStartButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Work Start",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 7
});
Utils.hideLoading(context);
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
},
);
}
Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Pay Now",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentPaymentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentServicePaymentStatusID": 2
});
Utils.hideLoading(context);
},
);
}
Widget showArrivedutton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Arrived",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 3
});
Utils.hideLoading(context);
},
);
}
Widget showPayLaterButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Pay Later",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentPaymentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentServicePaymentStatusID": 4
});
Utils.hideLoading(context);
},
);
}
Widget showCompleteButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Complete",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 8
});
Utils.hideLoading(context);
},
);
}
Widget showCancelButton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Cancel",
maxWidth: double.infinity,
isFilled: false,
txtColor: MyColors.redColor,
borderColor: MyColors.redColor,
onPressed: () {
showMyBottomSheet(
context,
child: ShowCollectPaymentSheet(
onClickYes: () {},
onClickNo: () {},
),
);
},
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
}

@ -0,0 +1,144 @@
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/services_models/item_model.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';
import '../../settings/schedule/widgets/chips_picker_item.dart';
class SelectItemsSheet extends StatelessWidget {
int serviceId;
Function(List<ItemData>) onSelectItems;
List<PickerItem>? list;
SelectItemsSheet(
{Key? key,
required this.serviceId,
required this.onSelectItems,
this.list})
: super(key: key);
@override
Widget build(BuildContext context) {
context.read<ItemsVM>().getServiceItems(serviceId,list: list);
return SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height / 1.4,
child: Column(
children: [
Expanded(
child: Consumer<ItemsVM>(
builder: (_, model, child) {
return Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 6),
child: Column(
children: [
Row(
children: [
Expanded(
child: "Select Items"
.toText(fontSize: 24, isBold: true),
),
Center(
child: (model.serviceItems == null
? "0"
: model.serviceItems!.data!
.where((element) =>
element.isUpdateOrSelected == 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 Items",
onChanged: (v) {},
),
12.height,
Expanded(
child: model.serviceItems?.data == null
? const Center(child: CircularProgressIndicator())
: model.serviceItems?.data!.length == 0
? Center(child: "No Item Found".toText())
: ListView.separated(
itemBuilder:
(BuildContext context, int index) {
return Row(
children: [
Checkbox(
value: model
.serviceItems!
.data![index]
.isUpdateOrSelected,
onChanged: (bool? v) {
model.serviceItems!.data![index]
.isUpdateOrSelected = v;
model.notifyListeners();
},
),
12.width,
Expanded(
child: model.serviceItems!
.data![index].name!
.toText(),
),
],
);
},
separatorBuilder:
(BuildContext context, int index) {
return const Divider(
height: 1,
);
},
itemCount:
model.serviceItems?.data?.length ?? 0,
),
),
],
),
);
},
),
),
ShowFillButton(
title: 'Add Selected Items',
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
if (context.read<ItemsVM>().serviceItems != null) {
List<ItemData> list = [];
context.read<ItemsVM>().serviceItems!.data!.forEach((element) {
if (element.isUpdateOrSelected ?? false) {
list.add(element);
}
});
onSelectItems(list);
}
Navigator.pop(context);
},
)
],
),
);
}
}

@ -0,0 +1,185 @@
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/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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
class ShowCollectPaymentSheet extends StatelessWidget {
Function() onClickYes;
Function() onClickNo;
ShowCollectPaymentSheet(
{required this.onClickYes, required this.onClickNo, Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 12),
child: Column(
children: [
"Do you want to collect the money before providing services?".toText(
fontSize: 24,
isBold: true,
),
21.height,
Row(
children: [
Expanded(
child: ShowFillButton(
title: "Yes",
onPressed: onClickYes,
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "No",
isFilled: false,
txtColor: MyColors.darkPrimaryColor,
onPressed: onClickNo,
),
),
],
),
],
),
);
}
}
class Reason {
String title;
bool isSelected;
Reason(this.title, this.isSelected);
}
class CancelAppointmentReasonSheet extends StatefulWidget {
Function(String) onCancelClick;
CancelAppointmentReasonSheet({required this.onCancelClick, Key? key})
: super(key: key);
@override
State<CancelAppointmentReasonSheet> createState() =>
_CancelAppointmentReasonSheetState();
}
class _CancelAppointmentReasonSheetState
extends State<CancelAppointmentReasonSheet> {
String reason = "";
List<Reason> reasonList = [
Reason("Operational Issue", true),
Reason("Material Issue", false),
Reason("The customer no longer responding", false),
Reason("Other", false),
];
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 21),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Reason".toText(fontSize: 24, isBold: true),
ListView.separated(
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 12, bottom: 12),
child: Row(
children: [
Container(
width: 14,
height: 14,
decoration: BoxDecoration(
color: reasonList[index].isSelected
? MyColors.darkPrimaryColor
: Colors.transparent,
borderRadius: BorderRadius.circular(122),
border: Border.all(
color: reasonList[index].isSelected
? MyColors.darkPrimaryColor
: borderColor,
width: 1),
),
child: const Icon(
Icons.done,
size: 12,
color: Colors.white,
),
),
12.width,
reasonList[index].title.toText(isBold: true)
],
),
).onPress(() {
for (var element in reasonList) {
element.isSelected = false;
}
setState(() {
reason = reasonList[index].title;
reasonList[index].isSelected = true;
});
});
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 1,
color: MyColors.borderColor,
);
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: reasonList.length,
),
if (reason == "Other")
TxtField(
hint: "Type Here...",
maxLines: 5,
onChanged: (v) {
reason = v;
},
),
12.height,
Row(
children: [
Expanded(
child: ShowFillButton(
title: "No",
isFilled: false,
txtColor: MyColors.darkPrimaryColor,
onPressed: () {
pop(context);
},
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "Yes",
onPressed: () {
if (reason.isEmpty || reason == "Other") {
Utils.showToast("Please Select Reason");
} else {
widget.onCancelClick(reason);
pop(context);
}
},
),
),
],
)
],
),
);
}
}

@ -11,14 +11,18 @@ import 'package:car_provider_app/views/dashboard/widget/drawer_widget.dart';
import 'package:car_provider_app/views/settings/branch/branch_list_page.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/bottom_nav_bar.dart';
import 'package:provider/provider.dart';
import 'fragments/branch_appointment_fragment.dart';
import 'fragments/home_fragment.dart';
import 'fragments/request_list_fragment.dart';
@ -44,15 +48,23 @@ class _DashboardPageState extends State<DashboardPage> {
}
Future<void> _onRefresh() async {
context.read<AdVM>().populateAdsFilterList();
// context.read<AdVM>().populateAdsFilterList();
context.read<ServiceVM>().getBranchAndServices();
AdVM adVm = Provider.of<AdVM>(context, listen: false);
if (adVm.myAds.isEmpty) {
await adVm.getMyAds();
}
if (adVm.exploreAds.isEmpty) {
await adVm.getExploreAds();
AppointmentsVM appointmentsVM =
Provider.of<AppointmentsVM>(context, listen: false);
if (appointmentsVM.myAppointments.isEmpty) {
await appointmentsVM.getProviderMyAppointments({
"ServiceProviderID":
injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0"
});
}
// if (adVm.myAds.isEmpty) {
// await adVm.getMyAds();
// }
// if (adVm.exploreAds.isEmpty) {
// await adVm.getExploreAds();
// }
}
@override
@ -63,7 +75,7 @@ class _DashboardPageState extends State<DashboardPage> {
dashboardVM.updateIndex(2);
},
),
AppointmentFragment(
BranchAppointmentFragment(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},

@ -1,18 +1,52 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/appointment_slider_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.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/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/tab/menu_tabs.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/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:provider/provider.dart';
class AppointmentFragment extends StatelessWidget {
String date = "";
VoidCallback onBackButtonTapped;
AppointmentFragment({required this.onBackButtonTapped});
AppointmentFragment({Key? key, required this.onBackButtonTapped})
: super(key: key);
GlobalKey<RefreshIndicatorState> refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0"
});
}
@override
Widget build(BuildContext context) {
context.read<AppointmentsVM>().setupProviderAppointmentFilter();
date = DateHelper.formatAsDayMonthYear(DateTime.now());
return Scaffold(
appBar: CustomAppBar(
profileImageUrl: MyAssets.carBanner,
@ -29,38 +63,180 @@ class AppointmentFragment extends StatelessWidget {
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
child: Column(
children: [
12.height,
SizedBox(
height: 35,
width: double.infinity,
child: MenuTabs(
0,
[
DropValue(0, "All Appointments", ""),
DropValue(1, "Booked", ""),
DropValue(2, "Confirmed", ""),
DropValue(3, "Arrived", ""),
],
onSelect: (DropValue value) {},
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
progressWidget(context),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(
appointmentStatusEnum:
selectedFilterId.toAppointmentStatusEnum(),
);
},
),
ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel:
appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
navigateWithName(
context,
ProviderAppRoutes.appointmentDetailList,
arguments: appointmentsVM
.myFilteredAppointments2[index]
.customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
],
),
),
);
}),
),
);
}
Widget progressWidget(BuildContext context) {
return Column(
children: [
Row(
children: [
Expanded(
child: "Slots Overview".toText(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
date.toText(
fontWeight: FontWeight.bold,
),
const Icon(
Icons.keyboard_arrow_down_outlined,
size: 16,
),
],
)
.toContainer(
backgroundColor: MyColors.lightGreyEAColor,
borderRadius: 100,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
ListView(
padding: const EdgeInsets.all(21),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
)
.onPress(() async {
date = await Utils.pickDateFromDatePicker(
context,
firstDate: null,
);
context.read<AppointmentsVM>().notifyListeners();
}),
],
),
24.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.lightGreyEAColor,
),
4.width,
"Empty: ".toText(
fontSize: 8,
color: Colors.white,
),
"8".toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
8.height,
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.darkPrimaryColor,
),
4.width,
"Occupied: ".toText(
fontSize: 8,
color: Colors.white,
),
"54".toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
],
),
CircularPercentIndicator(
radius: 60.0,
lineWidth: 12.0,
percent: 0.7,
circularStrokeCap: CircularStrokeCap.round,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppointmentSliderWidget(),
21.height,
const AppointmentSliderWidget(),
"Total Slots".toText(
fontSize: 13,
fontWeight: FontWeight.bold,
),
"24".toText(
fontSize: 24,
fontWeight: FontWeight.bold,
),
],
),
],
),
),
),
backgroundColor: MyColors.lightGreyEAColor,
progressColor: MyColors.darkPrimaryColor,
),
],
)
],
).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
margin: const EdgeInsets.all(21),
);
}
}

@ -0,0 +1,170 @@
import 'package:geolocator/geolocator.dart';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.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/tab/role_type_tab.dart';
import '../../../generated/locale_keys.g.dart';
import '../../../view_models/service_view_model.dart';
import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
class BranchAppointmentFragment extends StatelessWidget {
bool isNeedAppBar;
VoidCallback onBackButtonTapped;
BranchAppointmentFragment(
{Key? key, this.isNeedAppBar = true, required this.onBackButtonTapped})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: !isNeedAppBar
? null
: CustomAppBar(
title: "Appointments",
onBackButtonTapped: onBackButtonTapped,
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 21, right: 21, top: 21),
child: RoleTypeTab(
context.watch<ServiceVM>().selectedBranchStatus == 3
? 0
: context.watch<ServiceVM>().selectedBranchStatus,
[
DropValue(3, "Active", ""),
DropValue(1, "Requested", ""),
],
onSelect: (DropValue value) {
context.read<ServiceVM>().updateSelectedBranchType(value.id);
},
),
),
Expanded(
child: Consumer<ServiceVM>(
builder: (context, model, _) {
if (model.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
List<BranchDetailModel> branches = [];
if (model.branches!.data != null) {
branches = model.branches!.data!.serviceProviderBranch!
.where((element) =>
model.selectedBranchStatus == element.statusId)
.toList();
}
return branches.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
return Row(
children: [
Container(
width: 74,
height: 50,
decoration: const BoxDecoration(
color: MyColors.darkPrimaryColor,
borderRadius:
BorderRadius.all(Radius.circular(8)),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
),
),
12.width,
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.place,
size: 12,
color: MyColors.darkPrimaryColor,
),
Geolocator.distanceBetween(
AppState()
.currentLocation
.latitude,
AppState()
.currentLocation
.latitude,
double.parse(branches[index]
.latitude ??
"0"),
double.parse(branches[index]
.longitude ??
"0"))
.toStringAsFixed(2)
.toText(
fontSize: 12,
color:
MyColors.darkPrimaryColor,
)
],
),
Text(
branches[index].branchName ?? "",
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
"Tap to view".toText(
fontSize: 10,
color: MyColors.grey70Color),
],
),
),
12.width,
],
).toContainer().onPress(() async {
branches[index].countryID =
model.branches!.data!.countryID;
branches[index].countryName =
model.branches!.data!.countryName;
navigateWithName(
context, ProviderAppRoutes.appointment,
arguments: branches[index]);
});
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: branches.length,
padding: const EdgeInsets.all(12),
);
}
},
),
),
],
),
),
);
}
}

@ -5,8 +5,11 @@ 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/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart';
import 'package:mc_common_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart';
@ -17,10 +20,15 @@ import 'package:provider/provider.dart';
import '../widget/appointment_slider_widget.dart';
class HomeFragment extends StatelessWidget {
VoidCallback onTap,onNotificaitonClick;
VoidCallback onTap, onNotificaitonClick;
RefreshCallback onRefresh;
HomeFragment({required this.onTap, required this.onRefresh,required this.onNotificaitonClick, Key? key}) : super(key: key);
HomeFragment(
{required this.onTap,
required this.onRefresh,
required this.onNotificaitonClick,
Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
@ -64,7 +72,17 @@ class HomeFragment extends StatelessWidget {
subTitle: 'View All',
onSubtitleTapped: () {},
).horPaddingMain(),
const AppointmentSliderWidget().horPaddingMain(),
// const AppointmentSliderWidget().horPaddingMain(),
CustomerAppointmentSliderWidget(
myUpComingAppointments:
context.read<AppointmentsVM>().myUpComingAppointments,
isNeedToShowEmptyMessage: true,
onAppointmentClick: (){
// navigateWithName(
// context, ProviderAppRoutes.appointment,
// arguments: branches[index]);
},
),
21.height,
ViewAllWidget(
title: 'My Branches',
@ -95,7 +113,8 @@ class HomeFragment extends StatelessWidget {
shouldShowAdStatus: true,
isAdsFragment: false,
adsList: adVM.myActiveAdsForHome,
scrollPhysics: const NeverScrollableScrollPhysics(),
scrollPhysics:
const NeverScrollableScrollPhysics(),
),
],
)
@ -115,9 +134,12 @@ class HomeFragment extends StatelessWidget {
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds,
adsList: adVM.exploreAds.length >= 3
? adVM.exploreAds.take(3).toList()
: adVM.exploreAds,
isAdsFragment: false,
scrollPhysics: const NeverScrollableScrollPhysics(),
scrollPhysics:
const NeverScrollableScrollPhysics(),
),
],
)

@ -1,96 +1,353 @@
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/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:sizer/sizer.dart';
import 'package:flutter_svg/flutter_svg.dart';
class AppointmentSliderWidget extends StatelessWidget {
const AppointmentSliderWidget({Key? key}) : super(key: key);
AppointmentListModel appointmentListModel;
bool isNeedTotalPayment;
bool isNeedToShowItems;
bool isNeedToShowToMoreText;
bool isSelectable;
bool isNeedToShowAppointmentStatus;
bool isNeedToShowMergeStatus;
Function()? onTap;
AppointmentSliderWidget(
{required this.appointmentListModel,
required this.onTap,
this.isNeedTotalPayment = false,
this.isNeedToShowItems = false,
this.isNeedToShowToMoreText = true,
this.isSelectable = false,
this.isNeedToShowAppointmentStatus = false,
this.isNeedToShowMergeStatus = false,
Key? key})
: super(key: key);
List<Widget> buildServicesFromAppointment(
{required AppointmentListModel appointmentListModel}) {
if (appointmentListModel.appointmentServicesList == null ||
appointmentListModel.appointmentServicesList!.isEmpty) {
return [SizedBox()];
}
if (appointmentListModel.appointmentServicesList!.length == 1) {
List<Widget> itemsList = [];
if (isNeedToShowItems) {
itemsList = List.generate(
appointmentListModel
.appointmentServicesList?.first.serviceItems?.length ??
0,
(index) => (appointmentListModel.appointmentServicesList?.first
.serviceItems?[index].name ??
"")
.toString()
.toText(
color: MyColors.lightTextColor,
isBold: true,
),
);
}
return [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
showServices(
appointmentListModel
.appointmentServicesList![0].providerServiceDescription,
MyAssets.modificationsIcon,
),
if (isNeedToShowItems) ...itemsList,
],
)
];
}
List<Widget> servicesList = List.generate(
isNeedToShowToMoreText
? 2
: appointmentListModel.appointmentServicesList?.length ?? 0,
(index) {
List<Widget> itemsList = [];
if (isNeedToShowItems) {
itemsList = List.generate(
appointmentListModel
.appointmentServicesList?[index].serviceItems?.length ??
0,
(mIndex) =>
(" - ${appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? ""}")
.toString()
.toText(
color: MyColors.lightTextColor,
isBold: true,
),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showServices(
appointmentListModel
.appointmentServicesList![index].providerServiceDescription,
MyAssets.modificationsIcon),
if (isNeedToShowItems) ...itemsList,
],
).paddingOnly(bottom: 4);
},
);
if (isNeedToShowToMoreText &&
appointmentListModel.appointmentServicesList!.length > 1) {
servicesList.add(
showServices(
"+ ${appointmentListModel.appointmentServicesList!.length - 1} More",
"",
isMoreText: true,
),
);
}
return servicesList;
}
@override
Widget build(BuildContext context) {
return Column(
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
if (isSelectable)
SizedBox(
child: const SizedBox(
width: 14,
height: 14,
).toContainer(
borderRadius: 24,
marginAll: 4,
paddingAll: 0,
backgroundColor: (appointmentListModel.isSelected ?? false)
? MyColors.primaryColor
: MyColors.greyButtonColor,
),
).toContainer(
borderRadius: 24,
isEnabledBorder: true,
paddingAll: 0,
borderWidget: 3,
borderColor: MyColors.primaryColor,
),
if (isSelectable) 12.width,
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isNeedToShowMergeStatus)
"Appointment Merged".toText(color: MyColors.white).toContainer(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 3),
borderRadius: 12,
backgroundColor: MyColors.greenColor,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Olaya Brach".toText(
fontSize: 12,
color: MyColors.darkTextColor,
isBold: true,
),
"Abdullah Alhbas".toText(
fontSize: 14,
isBold: true,
),
Row(
children: [
"Appt. On:".toText(
color: MyColors.lightTextColor,
),
2.width,
"19-Mar-2023 11:48 AM".toText(),
],
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(appointmentListModel.branchName ?? "").toText(
fontSize: 12,
color: MyColors.darkTextColor,
isBold: true,
),
(appointmentListModel.customerName ?? "").toText(
color: MyColors.black, isBold: true, fontSize: 16),
Row(
children: [
"Phone:".toText(
color: MyColors.lightTextColor,
),
2.width,
appointmentListModel.customerMobileNum
.toString()
.toText(
fontSize: 12,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Appt. On:".toText(
color: MyColors.lightTextColor,
),
2.width,
Expanded(
child:
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}"
.toText(
fontSize: 12,
),
),
],
),
Row(
children: [
"Location: ".toText(
color: MyColors.lightTextColor,
),
2.width,
appointmentListModel.appointmentType
.toString()
.toText(
fontSize: 12,
),
],
),
],
),
),
if (!isNeedTotalPayment)
if (appointmentListModel.customerAppointmentList!.length >
1)
"${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments"
.toText(
fontSize: 8,
)
.toContainer(
borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor,
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
),
if (isNeedToShowAppointmentStatus)
(appointmentListModel.appointmentStatusEnum!
.getAppointmentNameFromEnum())
.toText(color: MyColors.white)
.toContainer(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 3),
borderRadius: 12,
backgroundColor: MyColors.primaryColor,
),
],
),
),
"1+ Requests".toText(fontSize: 10).toContainer(
borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor,
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
),
],
),
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Column(
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
showServices("Maintenance"),
2.height,
showServices("Accessories and Modification"),
Expanded(
child: Column(
children: [
...buildServicesFromAppointment(
appointmentListModel: appointmentListModel),
if (isNeedTotalPayment)
Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
24.height,
"Total Amount".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
appointmentListModel.totalAmount
.toString()
.toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2.height,
"Remaining Amount".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
appointmentListModel.remainingAmount
.toString()
.toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
],
),
],
)
],
),
),
if (!isNeedToShowItems)
const Icon(
Icons.arrow_forward,
),
],
),
),
const Icon(
Icons.arrow_forward,
),
],
),
],
),
)
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
onTap: () {
navigateWithName(context, ProviderAppRoutes.appointmentDetailList);
});
).toWhiteContainer(width: double.infinity, allPading: 12, onTap: onTap);
}
Widget showServices(String title) {
double calculateTotalPrice() {
double totalServiceListPrice = 0;
appointmentListModel.appointmentServicesList!.forEach((servicesElement) {
servicesElement.serviceItems!.forEach((itemsElement) {
totalServiceListPrice += double.parse(itemsElement.price ?? "0");
});
});
return totalServiceListPrice;
}
Widget showServices(String title, String icon, {bool isMoreText = false}) {
return Row(
children: [
const Icon(
Icons.ac_unit,
color: MyColors.primaryColor,
size: 18,
),
8.width,
title.toText(
fontSize: 14,
isBold: true,
if (icon != "") ...[
SvgPicture.asset(icon),
8.width,
],
Flexible(
child: title.toText(
fontSize: 12,
isBold: true,
color: isMoreText ? MyColors.primaryColor : MyColors.black,
),
),
],
);

@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.18.0"
country_code_picker:
dependency: transitive
description:
@ -226,10 +226,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "2.0.3"
flutter_localizations:
dependency: transitive
description: flutter
@ -425,10 +425,10 @@ packages:
dependency: transitive
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.0"
version: "0.18.1"
js:
dependency: transitive
description:
@ -441,10 +441,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
version: "2.1.1"
local_auth:
dependency: transitive
description:
@ -505,22 +505,22 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
mc_common_app:
dependency: "direct main"
description:
path: "C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app"
path: "/Users/mirzashafiq/AndroidStudioProjects/car_common_app"
relative: false
source: path
version: "1.0.0+1"
@ -528,10 +528,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
nested:
dependency: transitive
description:
@ -628,6 +628,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.11.1"
percent_indicator:
dependency: transitive
description:
name: percent_indicator
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
url: "https://pub.dev"
source: hosted
version: "4.2.3"
permission_handler:
dependency: transitive
description:
@ -813,10 +821,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
sqflite:
dependency: transitive
description:
@ -845,18 +853,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
@ -901,10 +909,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.1"
tuple:
dependency: transitive
description:
@ -1009,6 +1017,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
@ -1042,5 +1058,5 @@ packages:
source: hosted
version: "6.1.0"
sdks:
dart: ">=3.0.0 <4.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.10.0"

@ -39,7 +39,7 @@ dependencies:
# path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app
mc_common_app:
path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app
path: /Users/mirzashafiq/AndroidStudioProjects/car_common_app
@ -53,7 +53,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

Loading…
Cancel
Save