user profile & settings & api's

localization_aamir
Aamir.Muhammad 1 year ago
parent 0b5ec2d2f7
commit b228e88a94

@ -4,6 +4,9 @@ import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/user_models/register_user.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/profile/profile_view.dart';
import 'package:mc_common_app/views/setting_options/provider_license_page.dart';
import 'package:mc_common_app/views/setting_options/setting_option_help.dart';
import 'package:mc_common_app/views/setting_options/setting_options_language.dart';
import 'package:mc_common_app/views/user/change_email_page.dart';
import 'package:mc_common_app/views/user/change_mobile_page.dart';
@ -89,10 +92,12 @@ class AppRoutes {
static const String settingOptionsFaqs = "/settingOptionsFaqs";
static const String settingOptionsLanguages = "/settingOptionsLanguages";
static const String settingOptionsInviteFriends = "/settingOptionsInviteFriends";
static const String settingOptionsHelp = "/settingOptionsHelp";
//Profile Screen
static const String profileView = "/profileView";
static const providerLicensePage = "/providerLicensePage";
//Chat
static const String chatView = "/chatView";
@ -135,6 +140,9 @@ class AppRoutes {
changeEmailPage: (context) => const ChangeEmailPage(),
editAccountPage: (context) => const EditAccountPage(),
profileView: (context) => const ProfileScreen(),
settingOptionsLanguages: (context) => const SettingOptionsLanguage(),
settingOptionsHelp: (context) => const SettingOptionsHelp(),
providerLicensePage: (context) => ProviderLicensePage(),
};
}

@ -3,6 +3,7 @@
// final user = userFromJson(jsonString);
import 'dart:convert';
import 'dart:io';
import '../../classes/app_state.dart';
import '../../utils/enums.dart';
@ -68,27 +69,27 @@ class UserData {
}
class UserInfo {
UserInfo({
this.id,
this.userId,
this.firstName,
this.lastName,
this.mobileNo,
this.email,
this.userImageUrl,
this.roleId,
this.roleName,
this.isEmailVerified,
this.serviceProviderBranch,
this.isVerified,
this.userRoles,
this.isCustomer,
this.isProviderDealership,
this.isDealershipUser,
this.providerId,
this.customerId,
this.dealershipId,
});
UserInfo(
{this.id,
this.userId,
this.firstName,
this.lastName,
this.mobileNo,
this.email,
this.userImageUrl,
this.roleId,
this.roleName,
this.isEmailVerified,
this.serviceProviderBranch,
this.isVerified,
this.userRoles,
this.isCustomer,
this.isProviderDealership,
this.isDealershipUser,
this.providerId,
this.customerId,
this.dealershipId,
this.userLocalImage});
int? id;
String? userId;
@ -109,6 +110,7 @@ class UserInfo {
dynamic providerId;
int? customerId;
dynamic dealershipId;
File? userLocalImage;
UserInfo.fromJson(Map<String, dynamic> json) {
if (json["roleID"] == 5) {
@ -137,6 +139,7 @@ class UserInfo {
providerId = json["providerID"];
customerId = json["customerID"];
dealershipId = json["dealershipID"];
userLocalImage = null;
}
// factory UserInfo.fromJson(Map<String, dynamic> json) => UserInfo(

@ -275,7 +275,7 @@ class UserRepoImp implements UserRepo {
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token $t");
return await injector.get<ApiClient>().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t);
return await injector.get<ApiClient>().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t,);
}
@override

@ -9,6 +9,7 @@ class AppTheme {
return ThemeData(
fontFamily: !isArabic ? MyFonts.poppinsFont : null,
primaryColor: primaryColor,
useMaterial3: false,
primaryTextTheme: const TextTheme(
titleLarge: TextStyle(color: Colors.white),
), colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.orange).copyWith(background: Colors.white),

@ -73,16 +73,18 @@ class AppPermissions {
);
}
Future<int> getAndroidDeviceInfo() async {
AndroidDeviceInfo deviceInfo = await DeviceInfoPlugin().androidInfo;
return deviceInfo.version.sdkInt;
static Future<int> getAndroidDeviceInfo() async {
if (Platform.isAndroid) {
AndroidDeviceInfo deviceInfo = await DeviceInfoPlugin().androidInfo;
return deviceInfo.version.sdkInt;
} else {
return 0;
}
}
static Future<bool> checkStoragePermissions(BuildContext context) async {
bool permissionStatus;
final deviceInfo = await DeviceInfoPlugin().androidInfo;
if (deviceInfo.version.sdkInt > 32) {
bool permissionStatus = false;
if (await getAndroidDeviceInfo() > 32) {
permissionStatus = await Permission.photos.request().isGranted;
if (permissionStatus) {
return true;
@ -91,7 +93,12 @@ class AppPermissions {
return false;
}
} else {
permissionStatus = await Permission.storage.request().isGranted;
if (Platform.isAndroid) {
permissionStatus = await Permission.storage.request().isGranted;
} else if (Platform.isIOS) {
print("Ios");
permissionStatus = await Permission.photos.request().isGranted;
}
if (permissionStatus) {
return true;
} else {

@ -1643,7 +1643,7 @@ class AdVM extends BaseVM {
logger.d("Step 3");
if (vehicleBrands.isNotEmpty) {
for (var vBrands in vehicleBrands) {
if (vBrands.id == previousDetails.vehicle.) {
if (vBrands.id == previousDetails.vehicle!.id) {
// BrandsId need to be matched here.
vBrands.isSelected = true;
break;

@ -0,0 +1,615 @@
// import 'dart:convert';
// 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/provider_model.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/services/branch_model.dart';
// import 'package:mc_common_app/models/services/item_model.dart';
// import 'package:mc_common_app/models/services/service_model.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/common_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 CommonAppServices commonServices;
// final CommonRepo commonRepo;
//
// ServiceVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
//
// //Documents & Branches
// int selectedBranchStatus = 3;
// Document? document;
// ProviderModel? 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(BranchModel? 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(BranchModel? 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);
// }
//
// updateSelectedBranchType(int status) {
// selectedBranchStatus = status;
// notifyListeners();
// }
//
// List<ServiceModel>? matchedServices;
// bool isAllSelected = false;
//
// getAllMatchedServices(int oldBranchId, int newBranchId, int categoryId) async {
// matchedServices = null;
// MResponse response = await branchRepo.getMatchedServices(oldBranchId, newBranchId, categoryId);
// matchedServices = [];
// if (response.messageStatus == 1) {
// matchedServices = List<ServiceModel>.from(response.data.map((x) => ServiceModel.fromJson(x)));
// }
// notifyListeners();
// }
//
// selectAllServices(bool value) {
// for (var element in matchedServices!) {
// element.isExpandedOrSelected = value;
// for (var item in element.serviceItems!) {
// item.isUpdateOrSelected = value;
// }
// }
// isAllSelected = value;
// notifyListeners();
// }
//
// updateServiceItem(int serviceIndex, bool value) {
// for (var element in matchedServices![serviceIndex].serviceItems!) {
// element.isUpdateOrSelected = value;
// }
// notifyListeners();
// }
//
// copyItems(int index, List<ItemData> copiedItems) {
// matchedServices![index].serviceItems = copiedItems;
// notifyListeners();
// }
//
// Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
// return await branchRepo.duplicateItems(map);
// }
// }
import 'dart:io';
import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.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/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/models/user_models/branch_user.dart';
import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/app_permission_handler.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';
class ServiceVM extends BaseVM {
final BranchRepo branchRepo;
final CommonAppServices commonServices;
final CommonRepo commonRepo;
ServiceVM({
required this.branchRepo,
required this.commonServices,
required this.commonRepo,
});
// Documents & Branches
int selectedBranchStatus = 3;
Document? document;
ProviderModel? branches;
Country? country;
Cities? cities;
DropValue? countryValue;
DropValue? cityValue;
List<DropValue> countryDropList = [];
List<DropValue> citiesDropList = [];
double latitude = 0;
double longitude = 0;
int role = -1;
int countryId = -1;
int cityId = -1;
String countryCode = "";
String address = "";
String branchName = "";
String branchDescription = "";
Future<void> getServiceProviderDocument(int providerId) async {
setState(ViewState.busy);
document = await branchRepo.getServiceProviderDocument(providerId);
setState(ViewState.idle);
}
Future<void> selectFile(BuildContext context, int index) async {
final status = await AppPermissions.checkStoragePermissions(context);
if (status) {
final File? file = await commonServices.pickFile(
context,
fileType: FileType.custom,
allowedExtensions: ['png', 'pdf', 'jpeg'],
);
// if (result != null) {
// final File file = File(result.files.single.path!);
// final int sizeInBytes = file.lengthSync();
//
// if (sizeInBytes > 1000) {
// Utils.showToast("File is larger than 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
// }
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000000) {
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
Future<void> getBranchAndServices() async {
setState(ViewState.busy);
branches = await branchRepo.getBranchAndServices();
setState(ViewState.idle);
}
Future<void> getAllCountriesList(BranchDetailModel? branchData, String countryCode) async {
cities = null;
country = null;
setState(ViewState.busy);
resetValues();
country = await commonRepo.getAllCountries();
country!.data?.forEach((element) {
if (branchData != null && branchData.id != null) {
if (element.id == branchData.countryID) {
countryId = element.id ?? -1;
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 && branchData.id != null) {
await getAllCities(branchData, countryCode);
}
setState(ViewState.idle);
}
Future<void> getAllCities(BranchDetailModel? branchData, String countryCode) async {
setState(ViewState.busy);
citiesDropList = [];
cities = null;
cityId = -1;
cityValue = null;
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(),
);
}
void 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 = [];
Future<void> fetchBranchCategory(String countryCode) async {
categoryDropList.clear();
servicesDropList = [];
services = null;
setOnlyState(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);
}
Future<void> fetchServicesByCategoryId(int categoryId) async {
servicesDropList = [];
setState(ViewState.busy);
services = await branchRepo.fetchServicesByCategoryId(serviceCategoryId: categoryId); // to get all the services
for (var element in services!.data!) {
servicesDropList.add(
DropValue(
element.id ?? 0,
element.description ?? "N/A",
"",
),
);
}
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);
}
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map);
}
void updateSelectedBranchType(int status) {
selectedBranchStatus = status;
notifyListeners();
}
List<ServiceModel>? matchedServices;
bool isAllSelected = false;
Future<void> getAllMatchedServices(int oldBranchId, int newBranchId, int categoryId) async {
matchedServices = null;
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)));
}
notifyListeners();
}
void selectAllServices(bool value) {
for (var element in matchedServices!) {
element.isExpandedOrSelected = value;
for (var item in element.serviceItems!) {
item.isUpdateOrSelected = value;
}
}
isAllSelected = value;
notifyListeners();
}
void updateServiceItem(int serviceIndex, bool value) {
for (var element in matchedServices![serviceIndex].serviceItems!) {
element.isUpdateOrSelected = value;
}
notifyListeners();
}
void copyItems(int index, List<ItemData> copiedItems) {
matchedServices![index].serviceItems = copiedItems;
notifyListeners();
}
Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
return await branchRepo.duplicateItems(map);
}
// Branch Users
List<BranchUser> allProviderDealersList = [];
List<BranchUser> branchUserList = [];
getAllProviderDealers(Map<String, dynamic> map) async {
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)));
}
setState(ViewState.idle);
}
Future<void> getBranchUsers(Map<String, dynamic> map) async {
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)));
}
setState(ViewState.idle);
}
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map) async {
MResponse response = await branchRepo.assignDealerToBranch(map);
return response;
}
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map) async {
MResponse response = await branchRepo.removeDealerFromBranch(map);
return response;
}
Future<MResponse> addNewServiceInAppointment(Map<String, dynamic> map) async {
MResponse response = await branchRepo.addNewServicesInAppointment(map);
return response;
}
}

@ -1,11 +1,14 @@
import 'dart:convert';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart';
import 'package:huawei_fido/huawei_fido.dart';
import 'package:image_picker/image_picker.dart';
import 'package:local_auth/local_auth.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
@ -22,12 +25,14 @@ import 'package:mc_common_app/models/user_models/confirm_password.dart';
import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/models/user_models/forget_password_otp_compare.dart';
import 'package:mc_common_app/models/user_models/forget_password_otp_request.dart';
import 'package:mc_common_app/models/user_models/image_response.dart';
import 'package:mc_common_app/models/user_models/login_password.dart';
import 'package:mc_common_app/models/user_models/register_user.dart';
import 'package:mc_common_app/models/user_models/user.dart';
import 'package:mc_common_app/models/user_models/verify_email.dart';
import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_auth_service.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/shared_prefrence.dart';
@ -40,8 +45,9 @@ import 'package:mc_common_app/widgets/tab/login_email_tab.dart';
class UserVM extends BaseVM {
final UserRepo userRepo;
final CommonAppServices commanServices;
UserVM({required this.userRepo});
UserVM({required this.userRepo, required this.commanServices});
bool completeProfilePageCheckbox = false;
@ -582,4 +588,20 @@ class UserVM extends BaseVM {
return true;
}
}
Future<void> updateUserImage(BuildContext context) async {
File? myPick = await commanServices.pickFile(context, fileType: FileType.image);
if (myPick != null) {
userRepo.updateUserImage(encodeBase64Image(myPick)).whenComplete(() {
AppState().getUser.data!.userInfo!.userLocalImage = myPick;
});
}
notifyListeners();
}
String encodeBase64Image(File file) {
List<int> imageBytes = file.readAsBytesSync();
print(imageBytes);
return base64Encode(imageBytes);
}
}

@ -1,264 +1,184 @@
import 'dart:io';
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
import 'package:mc_common_app/views/user/change_password_page.dart';
import 'package:mc_common_app/views/user/change_password_page.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class ProfileScreen extends StatelessWidget {
class ProfileScreen extends StatefulWidget {
const ProfileScreen({Key? key}) : super(key: key);
// final ImagePicker _picker = ImagePicker();
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
Widget showItem({required String icon, required String title, required VoidCallback onTap, String? subTitle}) {
return InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
icon,
color: subTitle == null ? MyColors.black : MyColors.primaryColor,
),
),
12.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title.toText(isBold: true, fontSize: 14),
if (subTitle != null) subTitle.toText(fontSize: 14, color: MyColors.primaryColor),
],
),
),
const Icon(
Icons.arrow_forward,
size: 16,
),
],
),
),
);
class _ProfileScreenState extends State<ProfileScreen> {
late UserVM userVM;
@override
void initState() {
// TODO: implement initState
super.initState();
userVM = Provider.of<UserVM>(context, listen: false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
backgroundColor: const Color(0xffefefef),
body: Stack(
children: [
Column(
children: [
Expanded(
flex: 3,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(MyAssets.icLogoWhitePng),
fit: BoxFit.cover,
body: Consumer<UserVM>(builder: (_, model, __) {
return Stack(
// fit: StackFit.loose,
children: [
Column(
children: [
Expanded(
flex: 3,
child: Container(
decoration: BoxDecoration(
image: AppState().getUser.data!.userInfo!.userLocalImage != null
? DecorationImage(
image: FileImage(AppState().getUser.data!.userInfo!.userLocalImage!),
fit: BoxFit.cover,
)
: AppState().getUser.data!.userInfo!.userImageUrl != null
? DecorationImage(
image: CachedNetworkImageProvider(
AppState().getUser.data!.userInfo!.userImageUrl,
),
fit: BoxFit.cover,
)
: DecorationImage(
image: AssetImage(
MyAssets.icLogoWhitePng,
),
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 7.0, sigmaY: 7.0),
child: Container(
// height:,
color: Colors.white.withOpacity(0.0),
),
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 7.0, sigmaY: 7.0),
child: Container(
// height:,
color: Colors.white.withOpacity(0.0),
),
Expanded(
flex: 8,
child: Container(
width: double.infinity,
color: Colors.white,
child: ListView(
children: [
20.height,
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25),
Column(
children: [
CustomProfileOptionsTile(
titleText: "Country",
subtitleText: "Saudi Arabia",
needBorderBelow: true,
onTap: () {},
),
CustomProfileOptionsTile(
titleText: "Email",
subtitleText: "${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true,
onTap: () {
Navigator.pushNamed(context, AppRoutes.changeEmailPage);
},
),
CustomProfileOptionsTile(
titleText: "Phone Number",
subtitleText: "${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true,
onTap: () {
Navigator.pushNamed(context, AppRoutes.changeMobilePage);
},
),
CustomProfileOptionsTile(
titleText: "Password",
subtitleText: "************",
onTap: () {
Navigator.pushNamed(context, AppRoutes.changePassword);
},
),
],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 20, 24, 0), borderRadius: 0),
],
),
),
),
),
Expanded(
flex: 8,
child: Container(
width: double.infinity,
color: Colors.white,
child: ListView(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: 90,
alignment: Alignment.centerLeft,
child: ClipOval(
child: Image.asset(
MyAssets.carBanner,
width: 90,
height: 90,
fit: BoxFit.fill,
),
)),
Container(
height: 35,
width: 35,
decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)),
child: const Icon(Icons.edit_note, color: MyColors.darkIconColor, size: 27).paddingOnly(left: 5),
).onPress(() {})
],
).horPaddingMain(),
10.height,
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25),
Column(
children: [
CustomProfileOptionsTile(
titleText: "Country",
subtitleText: "Saudi Arabia",
needBorderBelow: true,
onTap: () {},
),
CustomProfileOptionsTile(
titleText: "Email",
subtitleText: "${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true,
onTap: () {},
),
CustomProfileOptionsTile(
titleText: "Phone Number",
subtitleText: "${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true,
onTap: () {},
),
CustomProfileOptionsTile(
titleText: "Password",
subtitleText: "************",
onTap: () {},
],
),
Positioned(
top: MediaQuery.of(context).size.height * 0.25,
child: Container(
height: 90,
alignment: Alignment.centerLeft,
child: ClipOval(
child: AppState().getUser.data!.userInfo!.userLocalImage != null
? Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!,
width: 90,
height: 90,
fit: BoxFit.fill,
)
: CachedNetworkImage(
imageUrl: "${AppState().getUser.data!.userInfo!.userImageUrl}",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0),
],
),
placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => const Icon(Icons.error),
width: 90,
height: 90,
fit: BoxFit.fill,
fadeInCurve: Curves.easeIn,
fadeInDuration: Duration(milliseconds: 1000),
useOldImageOnUrlChange: false,
),
),
).horPaddingMain(),
),
Positioned(
top: MediaQuery.of(context).size.height * 0.30,
right: MediaQuery.of(context).size.height * 0.036,
child: Container(
height: 35,
width: 35,
decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)),
child: const Icon(Icons.edit_note, color: MyColors.darkIconColor, size: 27).paddingOnly(left: 5),
).onPress(
() async {
model.updateUserImage(context);
},
),
],
),
CircleAvatar(
radius: 20,
backgroundColor: Colors.white,
child: const Icon(Icons.arrow_back_ios_rounded, color: MyColors.darkIconColor, size: 18).paddingOnly(right: 4),
).onPress(() {
Navigator.pop(context);
}).paddingOnly(left: 21, right: 21, top: 50),
// SingleChildScrollView(
// scrollDirection: Axis.vertical,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// CircleAvatar(
// radius: 20,
// backgroundColor: Colors.white,
// child: const Icon(Icons.arrow_back_ios_rounded, color: MyColors.darkIconColor, size: 18).paddingOnly(right: 4),
// ).onPress(() {
// Navigator.pop(context);
// }),
// ],
// ).paddingOnly(left: 21, right: 21, top: 50),
// Stack(
// children: [
// Column(
// children: [
// showItem(
// icon: MyAssets.icEmail,
// title: "Country",
// onTap: () {
// navigateWithName(context, AppRoutes.changeEmailPage);
// },
// ),
// const Divider(
// height: 1,
// ),
// showItem(
// icon: MyAssets.icPassword,
// title: "Country",
// onTap: () {
// navigateWithName(context, AppRoutes.changePassword);
// },
// ),
// const Divider(
// height: 1,
// ),
// showItem(
// icon: MyAssets.icPhoneNumber,
// title: "Country",
// onTap: () {
// navigateWithName(context, AppRoutes.changeMobilePage);
// },
// ),
// const Divider(
// height: 1,
// ),
// ],
// ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.symmetric(horizontal: 21)),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Container(
// height: 68,
// alignment: Alignment.centerLeft,
// child: ClipOval(
// child: Image.asset(
// MyAssets.carBanner,
// width: 68,
// height: 68,
// fit: BoxFit.fill,
// ),
// )),
// InkWell(
// onTap: () {},
// child: Container(
// padding: const EdgeInsets.only(left: 17, right: 17, top: 8, bottom: 8),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(30),
// color: Colors.black.withOpacity(.21),
// ),
// child: Row(
// children: [
// const Icon(Icons.photo, color: Colors.white, size: 16),
// 4.width,
// "edit".toText(fontSize: 12, color: Colors.white),
// ],
// ),
// ),
// ),
// ],
// ),
// ],
// ).horPaddingMain(),
// ],
// ),
// ),
// Container(
// height: MediaQuery.of(context).size.height,
// width: MediaQuery.of(context).size.width,
// color: Colors.white,
// child: Column(
// children: [
// CustomSettingOptionsTile(
// leadingWidget: const Icon(Icons.person, size: 20), titleText: "Invite Friends", needBorderBelow: true, onTap: () => navigateWithName(context, AppRoutes.myRequestsPage)),
// CustomSettingOptionsTile(
// leadingWidget: const Icon(Icons.help, size: 20), titleText: "Help", needBorderBelow: true, onTap: () => navigateWithName(context, AppRoutes.settingOptionsFaqs)),
// CustomSettingOptionsTile(leadingWidget: const Icon(Icons.person, size: 20), titleText: "Account", onTap: () => navigateWithName(context, AppRoutes.profileView)),
// ],
// ).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, borderRadius: 0),
// ),
],
),
),
],
);
}),
);
}
}

@ -0,0 +1,220 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.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/generated/locale_keys.g.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/app_permission_handler.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/service_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 'package:mc_common_app/widgets/txt_field.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class ProviderLicensePage extends StatefulWidget {
@override
State<ProviderLicensePage> createState() => _ProviderLicensePageState();
}
class _ProviderLicensePageState extends State<ProviderLicensePage> {
late ServiceVM branchVM;
@override
void initState() {
// TODO: implement initState
super.initState();
branchVM = Provider.of<ServiceVM>(context, listen: false);
branchVM.getServiceProviderDocument(AppState().getUser.data!.userInfo!.providerId ?? 0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.defineLicences.tr(),
isRemoveBackButton: false,
),
body: Consumer<ServiceVM>(builder: (_, model, __) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
// LocaleKeys.defineLicences.tr().toText20(isBold: true),
// 12.height,
// LocaleKeys.defineLicenese.tr().toText14(color: MyColors.lightTextColor),
20.height,
showWidget(model),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: ShowFillButton(
title: LocaleKeys.continu.tr(),
maxWidth: double.infinity,
onPressed: () {
if (AppState().getUser.data!.userInfo!.roleId == 5) {
if (validation(model)) {
updateDocument(model);
} else {
Utils.showToast("All document's are mandatory for Dealership Provider");
}
} else {
updateDocument(model);
}
},
),
),
],
);
}),
);
}
validation(ServiceVM model) {
bool valid = true;
model.document!.data!.forEach((element) {
if (element.documentUrl == null) {
valid = false;
}
});
return valid;
}
updateDocument(ServiceVM model) async {
Utils.showLoading(context);
MResponse res = await model.updateDocument(model.document!.data);
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast("Documents uploaded successfully");
} else {
Utils.showToast(res.message ?? "");
}
}
Widget showWidget(ServiceVM model) {
if (model.state == ViewState.idle) {
return model.document!.data!.isEmpty
? Text("LocaleKeys.somethingWrong.tr()")
: ListView.separated(
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
model.document?.data![index].documentName ?? "",
style: const TextStyle(
fontSize: 16,
),
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 4, bottom: 8),
child: LocaleKeys.enter_licence_detail.tr().toText(fontSize: 14, color: MyColors.lightTextColor, textAlign: TextAlign.center),
),
TxtField(
hint: LocaleKeys.description.tr(),
maxLines: 3,
isBackgroundEnabled: true,
),
if ((model.document?.data![index].documentUrl ?? "").toString().isNotEmpty)
Column(
children: [
8.height,
(model.document?.data![index].documentUrl ?? "").toString().toText(
fontSize: 14,
color: MyColors.lightTextColor,
),
],
),
8.height,
InkWell(
onTap: () async {
model.selectFile(context, index);
},
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,
Text(
LocaleKeys.attachFile.tr(),
style: const TextStyle(
color: MyColors.darkPrimaryColor,
),
),
const Icon(
Icons.attach_file,
size: 18,
color: Colors.transparent,
),
],
),
),
),
],
);
},
separatorBuilder: (context, index) {
return 20.height;
},
itemCount: model.document!.data!.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
}
// selectFile(int index) async {
// FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
//
// if (result != null) {
// File file = File(result.files.single.path ?? "");
// 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);
// setState(() {
// document!.data![index].documentUrl = result.files.single.path ?? "";
// });
// }
// } else {
// // User canceled the picker
// }
// }
}

@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class SettingOptionsHelp extends StatelessWidget {
const SettingOptionsHelp({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Help",
isRemoveBackButton: false,
isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context),
),
body: Column(
children: [
Expanded(
child: ListView(
children: [
Column(
children: [
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.info_rounded, size: 20),
titleText: "FAQs",
needBorderBelow: true,
onTap: () {},
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.mail, size: 20),
titleText: "Contact Us",
needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsFaqs),
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.lock, size: 20),
titleText: "Term & Privacy",
onTap: () => navigateWithName(context, AppRoutes.profileView),
),
],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0),
],
),
),
],
),
);
}
}
class CustomSettingOptionsTile extends StatelessWidget {
final Widget leadingWidget;
final String titleText;
final bool needBorderBelow;
final bool isForLanguage;
final Function() onTap;
const CustomSettingOptionsTile({super.key, required this.leadingWidget, required this.onTap, required this.titleText, this.needBorderBelow = false, this.isForLanguage = false});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
leadingWidget,
12.width,
titleText.toText(fontSize: 16),
],
),
isForLanguage ? const Icon(Icons.language, size: 18) : const Icon(Icons.arrow_forward, size: 18)
],
).onPress(onTap),
5.height,
if (needBorderBelow) ...[
const Divider(thickness: 1),
],
],
);
}
}

@ -1,6 +1,12 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/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/dashboard_view_model_customer.dart';
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
@ -23,28 +29,145 @@ class SettingOptionsLanguage extends StatelessWidget {
),
body: Column(
children: [
// (AppState().currentAppType == AppType.provider)
// ?
Expanded(
child: ListView(
children: [
Column(
children: [
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20),
titleText: "My Requests",
needBorderBelow: true,
onTap: () {
context.read<DashboardVmCustomer>().onNavbarTapped(4);
Navigator.pop(context);
}),
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.favorite, size: 20), titleText: "Favorite list", needBorderBelow: true, onTap: () {}),
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.settings, size: 20), titleText: "Settings", onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends)),
],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0),
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.translate, size: 20), titleText: "Language", isForLanguage: true, onTap: () {})
.toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, marginAll: 21, borderRadius: 0),
],
),
),
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.zero,
children: [
Column(
children: [
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.quickreply_outlined, size: 20),
titleText: "Requests",
needBorderBelow: true,
onTap: () {
context.read<DashboardVmCustomer>().onNavbarTapped(4);
Navigator.pop(context);
}),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20),
titleText: "Settings",
needBorderBelow: true,
onTap: () {},
//navigateWithName(context, AppRoutes.settingOptionsInviteFriends),
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.question_mark_outlined, size: 20),
titleText: "Help",
needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsHelp),
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20),
titleText: "Account",
needBorderBelow: false,
onTap: () {
navigateWithName(context, AppRoutes.profileView);
// context.read<DashboardVmCustomer>().onNavbarTapped(4);
// Navigator.pop(context);
}),
],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height,
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.translate, size: 20),
titleText: "Language",
isForLanguage: true,
onTap: () {
if (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA") {
context.setLocale(const Locale("en", "US"));
} else {
context.setLocale(const Locale('ar', 'SA'));
}
},
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height,
(AppState().currentAppType == AppType.provider)
? Column(
children: [
CustomSettingOptionsTile(
leadingWidget: SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
MyAssets.icStar,
color: MyColors.primaryColor,
),
),
titleText: "My Subscriptions",
subTitle: "Silver",
isForLanguage: false,
needBorderBelow: true,
onTap: () {
navigateWithName(context, AppRoutes.mySubscriptionsPage);
},
),
CustomSettingOptionsTile(
leadingWidget: SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
MyAssets.icGroupStar,
// color: MyColors.primaryColor,
),
),
titleText: "Subscriptions",
subTitle: null,
isForLanguage: false,
needBorderBelow: true,
onTap: () {
navigateWithName(context, AppRoutes.subscriptionsPage);
},
),
CustomSettingOptionsTile(
leadingWidget: SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
MyAssets.icGroupStar,
// color: MyColors.primaryColor,
),
),
titleText: "Define Licenses",
subTitle: null,
isForLanguage: false,
needBorderBelow: false,
onTap: () {
navigateWithName(context, AppRoutes.providerLicensePage);
},
)
],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0)
: SizedBox(),
(AppState().currentAppType == AppType.provider) ? 10.height : SizedBox(),
],
)),
// : Expanded(
// child: ListView(
// children: [
// Column(
// children: [
// CustomSettingOptionsTile(
// leadingWidget: const Icon(Icons.person, size: 20),
// titleText: "My Requests",
// needBorderBelow: true,
// onTap: () {
// context.read<DashboardVmCustomer>().onNavbarTapped(4);
// Navigator.pop(context);
// }),
// CustomSettingOptionsTile(leadingWidget: const Icon(Icons.favorite, size: 20), titleText: "Favorite list", needBorderBelow: true, onTap: () {}),
// CustomSettingOptionsTile(
// leadingWidget: const Icon(Icons.settings, size: 20), titleText: "Settings", onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends)),
// ],
// ).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0),
// CustomSettingOptionsTile(leadingWidget: const Icon(Icons.translate, size: 20), titleText: "Language", isForLanguage: true, onTap: () {})
// .toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, marginAll: 21, borderRadius: 0),
// ],
// ),
// ),
(AppState().currentAppType == AppType.provider) ? const Text("Provider") : const Text("Customer"),
Row(
children: [
Expanded(
@ -59,9 +182,9 @@ class SettingOptionsLanguage extends StatelessWidget {
),
),
],
).paddingAll(21),
).paddingAll(0),
],
),
).paddingAll(21),
);
}
}

@ -1,8 +1,11 @@
import 'package:easy_localization/easy_localization.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/generated/locale_keys.g.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 CustomSettingOptionsTile extends StatelessWidget {
final Widget leadingWidget;
@ -10,8 +13,17 @@ class CustomSettingOptionsTile extends StatelessWidget {
final bool needBorderBelow;
final bool isForLanguage;
final Function() onTap;
final String? subTitle;
const CustomSettingOptionsTile({super.key, required this.leadingWidget, required this.onTap, required this.titleText, this.needBorderBelow = false, this.isForLanguage = false});
const CustomSettingOptionsTile({
super.key,
required this.leadingWidget,
required this.onTap,
required this.titleText,
this.needBorderBelow = false,
this.isForLanguage = false,
this.subTitle,
});
@override
Widget build(BuildContext context) {
@ -20,17 +32,39 @@ class CustomSettingOptionsTile extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
leadingWidget,
12.width,
titleText.toText(fontSize: 16),
Row(
children: [
leadingWidget,
12.width,
titleText.toText(fontSize: 16),
],
),
if (subTitle != null)
Row(
children: [
28.width,
subTitle!.toText(fontSize: 14, color: MyColors.primaryColor),
],
),
],
),
isForLanguage ? const Icon(Icons.language, size: 18) : const Icon(Icons.arrow_forward, size: 18)
isForLanguage
? LocaleKeys.english.tr().toText(fontSize: 12, isUnderLine: true, color: MyColors.primaryColor)
// const Icon(
// Icons.language,
// size: 18,
// color: MyColors.primaryColor,
// )
//
: const Icon(Icons.arrow_forward, size: 18)
],
).onPress(onTap),
5.height,
subTitle != null ? 3.height : 5.height,
if (needBorderBelow) ...[
const Divider(thickness: 1),
],

@ -36,7 +36,7 @@ class _ChangePasswordPageState extends State<ChangePasswordPage> {
child: Container(
// width: double.infinity,
// height: double.infinity,
padding: EdgeInsets.all(40),
padding: EdgeInsets.all(20),
child: Column(
children: [
LocaleKeys.enterNewPassword.tr().toText(height: 23 / 24, fontSize: 24, letterSpacing: -1.44,),

@ -4,8 +4,11 @@ import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -70,29 +73,87 @@ class _EditAccountPageState extends State<EditAccountPage> {
),
],
).toWhiteContainer(width: double.infinity, pading: EdgeInsets.symmetric(horizontal: 12)),
21.height,
Column(
children: [
showItem(
icon: MyAssets.icStar,
title: "My Subscriptions",
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.quickreply_outlined, size: 20),
titleText: "Requests",
needBorderBelow: true,
onTap: () {
context.read<DashboardVmCustomer>().onNavbarTapped(4);
Navigator.pop(context);
}),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20),
titleText: "Settings",
needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends),
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.question_mark_outlined, size: 20),
titleText: "Help",
needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends),
),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20),
titleText: "Account",
needBorderBelow: false,
onTap: () {
context.read<DashboardVmCustomer>().onNavbarTapped(4);
Navigator.pop(context);
}),
],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height,
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.translate, size: 20),
titleText: "Language",
isForLanguage: true,
onTap: () {},
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height,
Column(
children: [
CustomSettingOptionsTile(
leadingWidget: SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
MyAssets.icStar,
color: MyColors.primaryColor,
),
),
titleText: "My Subscriptions",
subTitle: "Silver",
isForLanguage: false,
needBorderBelow: true,
onTap: () {
navigateWithName(context, AppRoutes.mySubscriptionsPage);
},
),
const Divider(
height: 1,
),
showItem(
icon: MyAssets.icGroupStar,
title: "Subscriptions",
CustomSettingOptionsTile(
leadingWidget: SizedBox(
width: 16,
height: 16,
child: SvgPicture.asset(
MyAssets.icGroupStar,
// color: MyColors.primaryColor,
),
),
titleText: "Subscriptions",
subTitle: null,
isForLanguage: false,
needBorderBelow: false,
onTap: () {
navigateWithName(context, AppRoutes.subscriptionsPage);
},
),
)
],
).toWhiteContainer(width: double.infinity, pading: EdgeInsets.symmetric(horizontal: 12)),
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height,
(AppState().currentAppType == AppType.provider) ? const Text("Provider") : const Text("Customer"),
],
),
),
@ -121,7 +182,7 @@ class _EditAccountPageState extends State<EditAccountPage> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
title.toText(isBold: true, fontSize: 14),
title.toText(isBold: false, fontSize: 16),
if (subTitle != null) subTitle.toText(fontSize: 14, color: MyColors.primaryColor),
],
),

@ -49,7 +49,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
// phoneNum = "966580816976";
// password = "123@Shf";
phoneNum = "966530896018";
password = "Amir@123";
password = "Amir@1234";
}
scheduleMicrotask(() {
userVM = Provider.of(context, listen: false);

@ -1,65 +1,13 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
//import 'package:flutter/material.dart';
// 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/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 CustomAppBar extends StatelessWidget with PreferredSizeWidget {
// final Color? backgroundColor;
// final double? elevation;
// final String? title;
// final Color? titleColor;
// final bool? isTitleCenter;
// final Color? backIconColor;
// final List<Widget>? actions;
// final bool isRemoveBackButton;
//
// const CustomAppBar({
// Key? key,
// this.title,
// required this.isRemoveBackButton,
// this.backgroundColor,
// this.actions,
// this.backIconColor,
// this.elevation,
// this.isTitleCenter,
// this.titleColor,
// }) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return AppBar(
// backgroundColor: backgroundColor ?? appBackgroundColor,
// elevation: elevation ?? 0,
// centerTitle: isTitleCenter ?? true,
// leading: isRemoveBackButton
// ? null
// : IconButton(
// icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
// onPressed: () => Navigator.of(context).pop(),
// ),
// iconTheme: IconThemeData(
// color: backIconColor ?? Colors.black, //change your color here
// ),
// actions: actions,
// title: (title ?? "").toText(fontSize: 20, isBold: true),
// );
// }
//
// @override
// Size get preferredSize => const Size.fromHeight(kToolbarHeight);
// }
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Color? backgroundColor;
final double? elevation;
@ -104,45 +52,76 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
centerTitle: isTitleCenter ?? true,
leading: isDrawerEnabled
? InkWell(
onTap: onTap,
child: Row(
children: [
Image.asset(
profileImageUrl,
width: 34,
height: 34,
fit: BoxFit.fill,
).toCircle(borderRadius: 100),
10.width,
SvgPicture.asset(MyAssets.dashboardDrawerIcon),
],
).paddingOnly(left: 21),
)
: isRemoveBackButton
? null
: Row(
children: [
21.width,
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: 16,
onTap: onTap,
child: Row(
children: [
profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userLocalImage != null
? Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!,
width: 34,
height: 34,
fit: BoxFit.fill,
).toCircle(borderRadius: 100)
: profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userImageUrl != null
? CachedNetworkImage(
imageUrl: AppState().getUser.data!.userInfo!.userImageUrl,
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
onPressed: onBackButtonTapped ??
() {
Navigator.pop(context);
},
).toContainer(
paddingAll: 0,
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
height: 40,
width: 40,
),
],
),
),
placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => const Icon(Icons.error),
fadeInCurve: Curves.easeIn,
width: 34,
height: 34,
fit: BoxFit.fill,
fadeInDuration: Duration(milliseconds: 1000),
useOldImageOnUrlChange: false,
).toCircle(borderRadius: 100)
: Image.asset(
MyAssets.carBanner,
width: 34,
height: 34,
fit: BoxFit.fill,
).toCircle(borderRadius: 100),
10.width,
SvgPicture.asset(MyAssets.dashboardDrawerIcon),
],
).paddingOnly(left: 21),
)
: isRemoveBackButton
? null
: Row(
children: [
21.width,
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: 16,
),
onPressed: onBackButtonTapped ??
() {
Navigator.pop(context);
},
).toContainer(
paddingAll: 0,
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
height: 40,
width: 40,
),
],
),
iconTheme: IconThemeData(
color: backIconColor ?? Colors.black, //change your color here
),

Loading…
Cancel
Save